//--------------------------------------------------------------------------------------------------
/// Read geometry from file given by name into given reservoir object
//--------------------------------------------------------------------------------------------------
bool RifReaderEclipseOutput::transferGeometry(const ecl_grid_type* mainEclGrid, RigReservoir* reservoir)
{
    CVF_ASSERT(reservoir);

    if (!mainEclGrid)
    {
        // Some error
        return false;
    }

    RigMainGrid* mainGrid = reservoir->mainGrid();
    {
        cvf::Vec3st  gridPointDim(0,0,0);
        gridPointDim.x() = ecl_grid_get_nx(mainEclGrid) + 1;
        gridPointDim.y() = ecl_grid_get_ny(mainEclGrid) + 1;
        gridPointDim.z() = ecl_grid_get_nz(mainEclGrid) + 1;
        mainGrid->setGridPointDimensions(gridPointDim);
    }

    // Get and set grid and lgr metadata

    size_t totalCellCount = static_cast<size_t>(ecl_grid_get_global_size(mainEclGrid));

    int numLGRs = ecl_grid_get_num_lgr(mainEclGrid);
    int lgrIdx;
    for (lgrIdx = 0; lgrIdx < numLGRs; ++lgrIdx)
    {
        ecl_grid_type* localEclGrid = ecl_grid_iget_lgr(mainEclGrid, lgrIdx);

        std::string lgrName = ecl_grid_get_name(localEclGrid);
        cvf::Vec3st  gridPointDim(0,0,0);
        gridPointDim.x() = ecl_grid_get_nx(localEclGrid) + 1;
        gridPointDim.y() = ecl_grid_get_ny(localEclGrid) + 1;
        gridPointDim.z() = ecl_grid_get_nz(localEclGrid) + 1;

        RigLocalGrid* localGrid = new RigLocalGrid(mainGrid);
        mainGrid->addLocalGrid(localGrid);

        localGrid->setIndexToStartOfCells(totalCellCount);
        localGrid->setGridName(lgrName);
        localGrid->setGridPointDimensions(gridPointDim);

        totalCellCount += ecl_grid_get_global_size(localEclGrid);
    }

    // Reserve room for the cells and nodes and fill them with data

    mainGrid->cells().reserve(totalCellCount);
    mainGrid->nodes().reserve(8*totalCellCount);

    caf::ProgressInfo progInfo(3 + numLGRs, "");
    progInfo.setProgressDescription("Main Grid");
    progInfo.setNextProgressIncrement(3);

    transferGridCellData(mainGrid, mainGrid, mainEclGrid, 0, 0);

    progInfo.setProgress(3);

    size_t globalMatrixActiveSize = ecl_grid_get_nactive(mainEclGrid);
    size_t globalFractureActiveSize = ecl_grid_get_nactive_fracture(mainEclGrid);

    mainGrid->setMatrixModelActiveCellCount(globalMatrixActiveSize);
    mainGrid->setFractureModelActiveCellCount(globalFractureActiveSize);

    for (lgrIdx = 0; lgrIdx < numLGRs; ++lgrIdx)
    {
        progInfo.setProgressDescription("LGR number " + QString::number(lgrIdx+1));

        ecl_grid_type* localEclGrid = ecl_grid_iget_lgr(mainEclGrid, lgrIdx);
        RigLocalGrid* localGrid = static_cast<RigLocalGrid*>(mainGrid->gridByIndex(lgrIdx+1));

        transferGridCellData(mainGrid, localGrid, localEclGrid, globalMatrixActiveSize, globalFractureActiveSize);

        int activeCellCount = ecl_grid_get_nactive(localEclGrid);
        localGrid->setMatrixModelActiveCellCount(activeCellCount);
        globalMatrixActiveSize += activeCellCount;

        activeCellCount = ecl_grid_get_nactive_fracture(localEclGrid);
        localGrid->setFractureModelActiveCellCount(activeCellCount);
        globalFractureActiveSize += activeCellCount;

        progInfo.setProgress(3 + lgrIdx);
    }


    mainGrid->setGlobalMatrixModelActiveCellCount(globalMatrixActiveSize);
    mainGrid->setGlobalFractureModelActiveCellCount(globalFractureActiveSize);

    return true;
}
Example #2
0
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
void RigNNCData::processConnections(const RigMainGrid& mainGrid)
{
    //cvf::Trace::show("NNC: Total number: " + cvf::String((int)m_connections.size()));

    for (size_t cnIdx = 0; cnIdx < m_connections.size(); ++cnIdx)
    {
        const RigCell& c1 = mainGrid.cells()[m_connections[cnIdx].m_c1GlobIdx];
        const RigCell& c2 = mainGrid.cells()[m_connections[cnIdx].m_c2GlobIdx];

        // Try to find the shared face

        char hasNeighbourInAnyDirection = 0;
        bool isPossibleNeighborInDirection[6]= {true, true, true, true, true, true};

        if (c1.hostGrid() == c2.hostGrid())
        {
            size_t i1, j1, k1;
            c1.hostGrid()->ijkFromCellIndex(c1.gridLocalCellIndex(), &i1, &j1, &k1);
            size_t i2, j2, k2;
            c2.hostGrid()->ijkFromCellIndex(c2.gridLocalCellIndex(), &i2, &j2, &k2);

          
            isPossibleNeighborInDirection[cvf::StructGridInterface::POS_I] = ((i1 + 1) == i2);
            isPossibleNeighborInDirection[cvf::StructGridInterface::NEG_I] = ((i2 + 1) == i1);
            isPossibleNeighborInDirection[cvf::StructGridInterface::POS_J] = ((j1 + 1) == j2);
            isPossibleNeighborInDirection[cvf::StructGridInterface::NEG_J] = ((j2 + 1) == j1);
            isPossibleNeighborInDirection[cvf::StructGridInterface::POS_K] = ((k1 + 1) == k2);
            isPossibleNeighborInDirection[cvf::StructGridInterface::NEG_K] = ((k2 + 1) == k1);

            hasNeighbourInAnyDirection = 
                isPossibleNeighborInDirection[cvf::StructGridInterface::POS_I] 
            + isPossibleNeighborInDirection[cvf::StructGridInterface::NEG_I]
            + isPossibleNeighborInDirection[cvf::StructGridInterface::POS_J]
            + isPossibleNeighborInDirection[cvf::StructGridInterface::NEG_J]
            + isPossibleNeighborInDirection[cvf::StructGridInterface::POS_K]
            + isPossibleNeighborInDirection[cvf::StructGridInterface::NEG_K];


            // If cell 2 is not adjancent with respect to any of the six ijk directions, 
            // assume that we have no overlapping area.

            if (!hasNeighbourInAnyDirection)
            {
                // Add to search map
                //m_cellIdxToFaceToConnectionIdxMap[m_connections[cnIdx].m_c1GlobIdx][cvf::StructGridInterface::NO_FACE].push_back(cnIdx);
                //m_cellIdxToFaceToConnectionIdxMap[m_connections[cnIdx].m_c2GlobIdx][cvf::StructGridInterface::NO_FACE].push_back(cnIdx);

                //cvf::Trace::show("NNC: No direct neighbors : C1: " + cvf::String((int)m_connections[cnIdx].m_c1GlobIdx) + " C2: " + cvf::String((int)m_connections[cnIdx].m_c2GlobIdx));
                continue; // to next connection
            }
        }

        // Possibly do some testing to avoid unneccesary overlap calculations

        cvf::Vec3d normal;
        for (char fIdx = 0; fIdx < 6; ++fIdx)
        {
            if (isPossibleNeighborInDirection[fIdx])
            {
                cvf::Vec3d fc1 = c1.faceCenter((cvf::StructGridInterface::FaceType)(fIdx));
                cvf::Vec3d fc2 = c2.faceCenter(cvf::StructGridInterface::oppositeFace((cvf::StructGridInterface::FaceType)(fIdx)));
                cvf::Vec3d fc1ToFc2 = fc2 - fc1;
                normal = c1.faceNormalWithAreaLenght((cvf::StructGridInterface::FaceType)(fIdx));
                normal.normalize();
                // Check that face centers are approx in the face plane
                if (normal.dot(fc1ToFc2) < 0.01*fc1ToFc2.length()) 
                {

                }
            }
        }

        bool foundAnyOverlap = false;

        for (char fIdx = 0; fIdx < 6; ++fIdx)
        {
            if (!isPossibleNeighborInDirection[fIdx])
            { 
                continue;
            }

            // Calculate connection polygon

            std::vector<size_t> polygon;
            std::vector<cvf::Vec3d> intersections;
            caf::SizeTArray4 face1;
            caf::SizeTArray4 face2;
            c1.faceIndices((cvf::StructGridInterface::FaceType)(fIdx), &face1);
            c2.faceIndices(cvf::StructGridInterface::oppositeFace((cvf::StructGridInterface::FaceType)(fIdx)), &face2);

            bool foundOverlap = cvf::GeometryTools::calculateOverlapPolygonOfTwoQuads(
                &polygon, 
                &intersections, 
                (cvf::EdgeIntersectStorage<size_t>*)NULL, 
                cvf::wrapArrayConst(&mainGrid.nodes()), 
                face1.data(), 
                face2.data(), 
                1e-6);

            if (foundOverlap)
            {
                foundAnyOverlap = true;
                // Found an overlap polygon. Store data about connection

                m_connections[cnIdx].m_c1Face = (cvf::StructGridInterface::FaceType)fIdx;
                for (size_t pIdx = 0; pIdx < polygon.size(); ++pIdx)
                {
                    if (polygon[pIdx] < mainGrid.nodes().size())
                        m_connections[cnIdx].m_polygon.push_back(mainGrid.nodes()[polygon[pIdx]]);
                    else
                        m_connections[cnIdx].m_polygon.push_back(intersections[polygon[pIdx] - mainGrid.nodes().size()]);
                }

                // Add to search map, possibly not needed
                //m_cellIdxToFaceToConnectionIdxMap[m_connections[cnIdx].m_c1GlobIdx][fIdx].push_back(cnIdx);
                //m_cellIdxToFaceToConnectionIdxMap[m_connections[cnIdx].m_c2GlobIdx][cvf::StructGridInterface::oppositeFace((cvf::StructGridInterface::FaceType)(fIdx))].push_back(cnIdx);

                break; // The connection face is found. Stop looping over the cell faces. Jump to next connection
            }
        }

        if (!foundAnyOverlap)
        {
            //cvf::Trace::show("NNC: No overlap found for : C1: " + cvf::String((int)m_connections[cnIdx].m_c1GlobIdx) + "C2: " + cvf::String((int)m_connections[cnIdx].m_c2GlobIdx));
        }
    }
}