//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
void RigReservoirBuilderMock::appendCells(size_t nodeStartIndex, size_t cellCount, RigGridBase* hostGrid, std::vector<RigCell>& cells)
{
    size_t activeCellIndex = 0;
    size_t i;
    for (i = 0; i < cellCount; i++)
    {
        RigCell riCell;

        riCell.setHostGrid(hostGrid);
        riCell.setCellIndex(i);

        riCell.cornerIndices()[0] = nodeStartIndex + i * 8 + 0;
        riCell.cornerIndices()[1] = nodeStartIndex + i * 8 + 1;
        riCell.cornerIndices()[2] = nodeStartIndex + i * 8 + 2;
        riCell.cornerIndices()[3] = nodeStartIndex + i * 8 + 3;
        riCell.cornerIndices()[4] = nodeStartIndex + i * 8 + 4;
        riCell.cornerIndices()[5] = nodeStartIndex + i * 8 + 5;
        riCell.cornerIndices()[6] = nodeStartIndex + i * 8 + 6;
        riCell.cornerIndices()[7] = nodeStartIndex + i * 8 + 7;

        riCell.setParentCellIndex(0);

        //TODO: Rewrite active cell info in mock models
        /*
        if (!(i % 5))
        {
            riCell.setActiveIndexInMatrixModel(cvf::UNDEFINED_SIZE_T);
        }
        else
        {
            riCell.setActiveIndexInMatrixModel(activeCellIndex++);
        }
        */

        cells.push_back(riCell);
    }
}
Пример #2
0
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
cvf::StructGridInterface::FaceType RigNNCData::calculateCellFaceOverlap(const RigCell &c1,
                                                                        const RigCell &c2,
                                                                        const RigMainGrid &mainGrid,
                                                                        std::vector<size_t>* connectionPolygon,
                                                                        std::vector<cvf::Vec3d>* connectionIntersections)
{
    // Try to find the shared face

    bool isPossibleNeighborInDirection[6]={ true, true, true, true, true, true };

    if ( c1.hostGrid() == c2.hostGrid() )
    {
        char hasNeighbourInAnyDirection = 0;

        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));
            return cvf::StructGridInterface::NO_FACE;
        }
    }

    #if 0
    // 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() )
            {

            }
        }
    }
    #endif


    for ( unsigned 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>*)nullptr,
            cvf::wrapArrayConst(&mainGrid.nodes()),
            face1.data(),
            face2.data(),
            1e-6);

        if ( foundOverlap )
        {
            if (connectionPolygon)(*connectionPolygon) = polygon;
            if (connectionIntersections) (*connectionIntersections) = intersections;
            return (cvf::StructGridInterface::FaceType)(fIdx);
        }
    }

    return cvf::StructGridInterface::NO_FACE;
}
Пример #3
0
bool transferGridCellData(RigMainGrid* mainGrid, RigGridBase* localGrid, const ecl_grid_type* localEclGrid, size_t matrixActiveStartIndex, size_t fractureActiveStartIndex)
{
    int cellCount = ecl_grid_get_global_size(localEclGrid);
    size_t cellStartIndex = mainGrid->cells().size();
    size_t nodeStartIndex = mainGrid->nodes().size();

    RigCell defaultCell;
    defaultCell.setHostGrid(localGrid);
    mainGrid->cells().resize(cellStartIndex + cellCount, defaultCell);

    mainGrid->nodes().resize(nodeStartIndex + cellCount*8, cvf::Vec3d(0,0,0));

    int progTicks = 100;
    double cellsPrProgressTick = cellCount/(float)progTicks;
    caf::ProgressInfo progInfo(progTicks, "");
    size_t computedCellCount = 0;
    // Loop over cells and fill them with data

    #pragma omp parallel for
    for (int gIdx = 0; gIdx < cellCount; ++gIdx)
    {
        RigCell& cell = mainGrid->cells()[cellStartIndex + gIdx];

        bool invalid = ecl_grid_cell_invalid1(localEclGrid, gIdx);
        cell.setInvalid(invalid);
        cell.setCellIndex(gIdx);

        // Active cell index

        int matrixActiveIndex = ecl_grid_get_active_index1(localEclGrid, gIdx);
        if (matrixActiveIndex != -1)
        {
            cell.setActiveIndexInMatrixModel(matrixActiveStartIndex + matrixActiveIndex);
        }
        else
        {
            cell.setActiveIndexInMatrixModel(cvf::UNDEFINED_SIZE_T);
        }

        int fractureActiveIndex = ecl_grid_get_active_fracture_index1(localEclGrid, gIdx);
        if (fractureActiveIndex != -1)
        {
            cell.setActiveIndexInFractureModel(fractureActiveStartIndex + fractureActiveIndex);
        }
        else
        {
            cell.setActiveIndexInFractureModel(cvf::UNDEFINED_SIZE_T);
        }

        // Parent cell index

        int parentCellIndex = ecl_grid_get_parent_cell1(localEclGrid, gIdx);
        if (parentCellIndex == -1)
        {
            cell.setParentCellIndex(cvf::UNDEFINED_SIZE_T);
        }
        else
        {
            cell.setParentCellIndex(parentCellIndex);
        }

        // Coarse cell info
        ecl_coarse_cell_type * coarseCellData = ecl_grid_get_cell_coarse_group1( localEclGrid , gIdx);
        cell.setInCoarseCell(coarseCellData != NULL);

        // Corner coordinates
        int cIdx;
        for (cIdx = 0; cIdx < 8; ++cIdx)
        {
            double * point = mainGrid->nodes()[nodeStartIndex + gIdx * 8 + cellMappingECLRi[cIdx]].ptr();
            ecl_grid_get_corner_xyz1(localEclGrid, gIdx, cIdx, &(point[0]), &(point[1]), &(point[2]));
            point[2] = -point[2];
            cell.cornerIndices()[cIdx] = nodeStartIndex + gIdx*8 + cIdx;
        }

        // Sub grid in cell
        const ecl_grid_type* subGrid = ecl_grid_get_cell_lgr1(localEclGrid, gIdx);
        if (subGrid != NULL)
        {
            int subGridFileIndex = ecl_grid_get_grid_nr(subGrid);
            CVF_ASSERT(subGridFileIndex > 0);
            cell.setSubGrid(static_cast<RigLocalGrid*>(mainGrid->gridByIndex(subGridFileIndex)));
        }

        // Mark inactive long pyramid looking cells as invalid
        if (!invalid && (cell.isInCoarseCell() || (!cell.isActiveInMatrixModel() && !cell.isActiveInFractureModel()) ) )
        {
            cell.setInvalid(cell.isLongPyramidCell());
        }

        #pragma omp atomic
        computedCellCount++;

        progInfo.setProgress((int)(computedCellCount/cellsPrProgressTick));
    }
    return true;
}