Example #1
0
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
void RimCellRangeFilter::setDefaultValues()
{
    CVF_ASSERT(m_parentContainer);

    RigMainGrid* mainGrid = m_parentContainer->mainGrid();
    if (mainGrid)
    {
        cvf::Vec3st min, max;
        mainGrid->matrixModelActiveCellsBoundingBox(min, max);

        // Adjust to Eclipse indexing
        min.x() = min.x() + 1;
        min.y() = min.y() + 1;
        min.z() = min.z() + 1;

        max.x() = max.x() + 1;
        max.y() = max.y() + 1;
        max.z() = max.z() + 1;

        startIndexI = static_cast<int>(min.x());
        startIndexJ = static_cast<int>(min.y());
        startIndexK = static_cast<int>(min.z());
        cellCountI = static_cast<int>(max.x() - min.x() + 1);
        cellCountJ = static_cast<int>(max.y() - min.y() + 1);
        cellCountK = static_cast<int>(max.z() - min.z() + 1);
    }
}
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
QList<caf::PdmOptionItemInfo> RimCellRangeFilter::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly)
{
    QList<caf::PdmOptionItemInfo> options;

    if (useOptionsOnly) (*useOptionsOnly) = true;

    if (&gridIndex == fieldNeedingOptions)
    { 
        RigMainGrid * mainGrid = NULL;

        if (parentContainer() && parentContainer()->reservoirView() && parentContainer()->reservoirView()->eclipseCase() &&  parentContainer()->reservoirView()->eclipseCase()->reservoirData())
            mainGrid = parentContainer()->reservoirView()->eclipseCase()->reservoirData()->mainGrid();

        for (size_t gIdx = 0; gIdx < mainGrid->gridCount(); ++gIdx)
        {
            RigGridBase* grid = mainGrid->gridByIndex(gIdx);
            QString gridName;

            gridName += grid->gridName().c_str();
            if (gIdx == 0)
            {
                if (gridName.isEmpty())
                    gridName += "Main Grid";
                else
                    gridName += " (Main Grid)";
            }

            caf::PdmOptionItemInfo item(gridName, (int)gIdx);
            options.push_back(item);
        }
    }
    return options;
}
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
const cvf::StructGridInterface* RimCellRangeFilterCollection::gridByIndex(int gridIndex) const
{
    RigMainGrid* mnGrid = mainGrid();
    RigFemPartCollection* femPartColl = this->femPartColl();

    if (mnGrid)
    {
        RigGridBase* grid = NULL;

        grid = mnGrid->gridByIndex(gridIndex);

        CVF_ASSERT(grid);

        return grid;
    }
    else if (femPartColl)
    {
        if (gridIndex < femPartColl->partCount())
            return femPartColl->part(gridIndex)->structGrid();
        else 
            return NULL;
    }
    
    return NULL;
}
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
RigGridBase* RimCellRangeFilter::selectedGrid()
{
    RigMainGrid* mainGrid = m_parentContainer->mainGrid();
    CVF_ASSERT(mainGrid);

    RigGridBase* grid = NULL;
    if (static_cast<size_t>(gridIndex()) >= mainGrid->gridCount())
    {
        gridIndex = 0;
    }

    grid = mainGrid->gridByIndex(gridIndex());
    CVF_ASSERT(grid);
    return grid;
}
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
QString RimCellRangeFilterCollection::gridName(int gridIndex) const
{
    RigMainGrid* mnGrid = mainGrid();
    RigFemPartCollection* femPartColl = this->femPartColl();

    if (mnGrid)
    {
        return mnGrid->gridByIndex(gridIndex)->gridName().c_str();
    }
    else if (femPartColl)
    {
        return QString::number(gridIndex);
    }

    return "";
}
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
int RimCellRangeFilterCollection::gridCount() const
{
    RigMainGrid* mnGrid = mainGrid();
    RigFemPartCollection* femPartColl = this->femPartColl();

    if (mnGrid)
    {
        return (int)mnGrid->gridCount();
    }
    else if (femPartColl)
    {
        return femPartColl->partCount();
    }

    return 0;
}
Example #7
0
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
void RimCellRangeFilter::defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute * attribute)
{
    caf::PdmUiSliderEditorAttribute* myAttr = static_cast<caf::PdmUiSliderEditorAttribute*>(attribute);
    if (!myAttr || !m_parentContainer)
    {
        return;
    }

    RigMainGrid* mainGrid = m_parentContainer->mainGrid();
    if (mainGrid)
    {
        cvf::Vec3st min, max;
        mainGrid->matrixModelActiveCellsBoundingBox(min, max);

        // Adjust to Eclipse indexing
        min.x() = min.x() + 1;
        min.y() = min.y() + 1;
        min.z() = min.z() + 1;

        max.x() = max.x() + 1;
        max.y() = max.y() + 1;
        max.z() = max.z() + 1;

        startIndexI.setUiName(QString("I Start (%1)").arg(min.x()));
        startIndexJ.setUiName(QString("J Start (%1)").arg(min.y()));
        startIndexK.setUiName(QString("K Start (%1)").arg(min.z()));
        cellCountI.setUiName(QString("  Width (%1)").arg(max.x() - min.x() + 1));
        cellCountJ.setUiName(QString("  Width (%1)").arg(max.y() - min.y() + 1));
        cellCountK.setUiName(QString("  Width (%1)").arg(max.z() - min.z() + 1));

        if (field == &startIndexI || field == &cellCountI)
        {
            myAttr->m_minimum = 1;
            myAttr->m_maximum = static_cast<int>(mainGrid->cellCountI());
        }
        else if (field == &startIndexJ  || field == &cellCountJ)
        {
            myAttr->m_minimum = 1;
            myAttr->m_maximum = static_cast<int>(mainGrid->cellCountJ());
        }
        else if (field == &startIndexK || field == &cellCountK)
        {
            myAttr->m_minimum = 1;
            myAttr->m_maximum = static_cast<int>(mainGrid->cellCountK());
        }
    }
}
Example #8
0
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
void RimCellRangeFilter::computeAndSetValidValues()
{
    CVF_ASSERT(m_parentContainer);

    RigMainGrid* mainGrid = m_parentContainer->mainGrid();
    if (mainGrid && mainGrid->cellCount() > 0 )
    {
        cellCountI = cvf::Math::clamp(cellCountI.v(),   1, static_cast<int>(mainGrid->cellCountI()));
        startIndexI = cvf::Math::clamp(startIndexI.v(), 1, static_cast<int>(mainGrid->cellCountI()));

        cellCountJ = cvf::Math::clamp(cellCountJ.v(),   1, static_cast<int>(mainGrid->cellCountJ()));
        startIndexJ = cvf::Math::clamp(startIndexJ.v(), 1, static_cast<int>(mainGrid->cellCountJ()));

        cellCountK = cvf::Math::clamp(cellCountK.v(),   1, static_cast<int>(mainGrid->cellCountK()));
        startIndexK = cvf::Math::clamp(startIndexK.v(), 1, static_cast<int>(mainGrid->cellCountK()));
    }
    this->updateIconState();
}
Example #9
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.globalCellArray()[m_connections[cnIdx].m_c1GlobIdx];
        const RigCell& c2 = mainGrid.globalCellArray()[m_connections[cnIdx].m_c2GlobIdx];

        bool foundAnyOverlap = false;
        std::vector<size_t> connectionPolygon;
        std::vector<cvf::Vec3d> connectionIntersections;
        cvf::StructGridInterface::FaceType connectionFace = cvf::StructGridInterface::NO_FACE;

        connectionFace = calculateCellFaceOverlap(c1, c2, mainGrid,  &connectionPolygon, &connectionIntersections);

        if (connectionFace != cvf::StructGridInterface::NO_FACE)
        {
            foundAnyOverlap = true;
            // Found an overlap polygon. Store data about connection

            m_connections[cnIdx].m_c1Face = connectionFace;
            for (size_t pIdx = 0; pIdx < connectionPolygon.size(); ++pIdx)
            {
                if (connectionPolygon[pIdx] < mainGrid.nodes().size())
                    m_connections[cnIdx].m_polygon.push_back(mainGrid.nodes()[connectionPolygon[pIdx]]);
                else
                    m_connections[cnIdx].m_polygon.push_back(connectionIntersections[connectionPolygon[pIdx] - mainGrid.nodes().size()]);
            }

            // Add to search map, possibly not needed
            //m_cellIdxToFaceToConnectionIdxMap[m_connections[cnIdx].m_c1GlobIdx][connectionFace].push_back(cnIdx);
            //m_cellIdxToFaceToConnectionIdxMap[m_connections[cnIdx].m_c2GlobIdx][cvf::StructGridInterface::oppositeFace(connectionFace].push_back(cnIdx);
        }
        else
        {
            //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));
        }
    }
}
Example #10
0
//--------------------------------------------------------------------------------------------------
/// Create mask for the parts outside the grid cells of the reservoir
//--------------------------------------------------------------------------------------------------
cvf::ref<cvf::Part> RivWellFracturePartMgr::createMaskOfFractureOutsideGrid(const RimEclipseView& activeView)
{
    cvf::Mat4d frMx = m_rimFracture->transformMatrix();

    std::vector<cvf::Vec3f> maskTriangles;

    auto displCoordTrans = activeView.displayCoordTransform();

    for (const auto& visibleFracturePolygon : m_visibleFracturePolygons)
    {
        std::vector<cvf::Vec3d> borderOfFractureCellPolygonLocalCsd;
        cvf::BoundingBox        frBBox;

        for (const auto& pv : visibleFracturePolygon)
        {
            cvf::Vec3d pvd(pv);
            borderOfFractureCellPolygonLocalCsd.push_back(pvd);
            pvd.transformPoint(frMx);
            frBBox.add(pvd);
        }

        std::vector<std::vector<cvf::Vec3d>> clippedPolygons;

        std::vector<size_t> cellCandidates;
        activeView.mainGrid()->findIntersectingCells(frBBox, &cellCandidates);
        if (cellCandidates.empty())
        {
            clippedPolygons.push_back(borderOfFractureCellPolygonLocalCsd);
        }
        else
        {
            // Check if fracture polygon is fully inside the grid

            bool allPointsInsideGrid = true;
            for (const auto& v : borderOfFractureCellPolygonLocalCsd)
            {
                auto         pointInDomainCoords = v.getTransformedPoint(frMx);
                bool         pointInsideGrid     = false;
                RigMainGrid* mainGrid            = activeView.mainGrid();

                std::array<cvf::Vec3d, 8> corners;
                for (size_t cellIndex : cellCandidates)
                {
                    mainGrid->cellCornerVertices(cellIndex, corners.data());

                    if (RigHexIntersectionTools::isPointInCell(pointInDomainCoords, corners.data()))
                    {
                        pointInsideGrid = true;
                        break;
                    }
                }

                if (!pointInsideGrid)
                {
                    allPointsInsideGrid = false;
                    break;
                }
            }

            if (!allPointsInsideGrid)
            {
                std::vector<std::vector<cvf::Vec3d>> allEclCellPolygons;
                for (size_t resCellIdx : cellCandidates)
                {
                    // Calculate Eclipse cell intersection with fracture plane

                    std::array<cvf::Vec3d, 8> corners;
                    activeView.mainGrid()->cellCornerVertices(resCellIdx, corners.data());

                    std::vector<std::vector<cvf::Vec3d>> eclCellPolygons;
                    bool hasIntersection = RigHexIntersectionTools::planeHexIntersectionPolygons(corners, frMx, eclCellPolygons);

                    if (!hasIntersection || eclCellPolygons.empty()) continue;

                    // Transform eclCell - plane intersection onto fracture

                    cvf::Mat4d invertedTransformMatrix = frMx.getInverted();
                    for (std::vector<cvf::Vec3d>& eclCellPolygon : eclCellPolygons)
                    {
                        for (cvf::Vec3d& v : eclCellPolygon)
                        {
                            v.transformPoint(invertedTransformMatrix);
                        }

                        allEclCellPolygons.push_back(eclCellPolygon);
                    }
                }

                {
                    std::vector<std::vector<cvf::Vec3d>> polys =
                        RigCellGeometryTools::subtractPolygons(borderOfFractureCellPolygonLocalCsd, allEclCellPolygons);

                    for (const auto& polygon : polys)
                    {
                        clippedPolygons.push_back(polygon);
                    }
                }
            }
        }

        for (auto& clippedPolygon : clippedPolygons)
        {
            for (auto& point : clippedPolygon)
            {
                point.transformPoint(frMx);
            }
        }

        // Create triangles from the clipped polygons
        cvf::Vec3d fractureNormal = cvf::Vec3d(frMx.col(2));

        for (const auto& clippedPolygon : clippedPolygons)
        {
            cvf::EarClipTesselator tess;
            tess.setNormal(fractureNormal);
            cvf::Vec3dArray cvfNodes(clippedPolygon);
            tess.setGlobalNodeArray(cvfNodes);
            std::vector<size_t> polyIndexes;
            for (size_t idx = 0; idx < clippedPolygon.size(); ++idx)
                polyIndexes.push_back(idx);
            tess.setPolygonIndices(polyIndexes);

            std::vector<size_t> triangleIndices;
            tess.calculateTriangles(&triangleIndices);

            for (size_t idx : triangleIndices)
            {
                maskTriangles.push_back(cvf::Vec3f(displCoordTrans->transformToDisplayCoord(clippedPolygon[idx])));
            }
        }
    }

    if (maskTriangles.size() >= 3)
    {
        cvf::ref<cvf::DrawableGeo> maskTriangleGeo = new cvf::DrawableGeo;
        maskTriangleGeo->setVertexArray(new cvf::Vec3fArray(maskTriangles));

        cvf::ref<cvf::PrimitiveSetDirect> primitives = new cvf::PrimitiveSetDirect(cvf::PT_TRIANGLES);
        primitives->setIndexCount(maskTriangles.size());
        maskTriangleGeo->addPrimitiveSet(primitives.p());
        maskTriangleGeo->computeNormals();

        cvf::ref<cvf::Part> containmentMaskPart = new cvf::Part(0, "FractureContainmentMaskPart");
        containmentMaskPart->setDrawable(maskTriangleGeo.p());
        containmentMaskPart->setSourceInfo(new RivObjectSourceInfo(m_rimFracture));

        cvf::Color4f maskColor = cvf::Color4f(cvf::Color3f(cvf::Color3::GRAY));

        caf::SurfaceEffectGenerator surfaceGen(maskColor, caf::PO_NONE);
        cvf::ref<cvf::Effect>       eff = surfaceGen.generateCachedEffect();
        containmentMaskPart->setEffect(eff.p());

        return containmentMaskPart;
    }

    return nullptr;
}
Example #11
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;
}
Example #12
0
    bool interpretCommand(RiaSocketServer* server, const QList<QByteArray>&  args, QDataStream& socketStream) override
    {
        RimEclipseCase* rimCase = RiaSocketTools::findCaseFromArgs(server, args);

        QString porosityModelName;
        porosityModelName = args[2];

        RiaDefines::PorosityModelType porosityModelEnum = RiaDefines::MATRIX_MODEL;
        if (porosityModelName.toUpper() == "FRACTURE")
        {
            porosityModelEnum = RiaDefines::FRACTURE_MODEL;
        }

        if (!rimCase || !rimCase->eclipseCaseData() )
        {
            // No data available
            socketStream << (quint64)0 << (quint64)0 ;
            return true;
        }

        RigActiveCellInfo* actCellInfo = rimCase->eclipseCaseData()->activeCellInfo(porosityModelEnum);
        RigMainGrid* mainGrid = rimCase->eclipseCaseData()->mainGrid();

        size_t activeCellCount = actCellInfo->reservoirActiveCellCount();
        size_t doubleValueCount = activeCellCount * 3 * 8;

        socketStream << (quint64)activeCellCount;
        quint64 byteCount = doubleValueCount * sizeof(double);
        socketStream << byteCount;

        // This structure is supposed to be received by Octave using a NDArray. The ordering of this loop is
        // defined by the ordering of the receiving NDArray
        //
        // See riGetCellCorners
        //
        //  dim_vector dv;
        //  dv.resize(3);
        //  dv(0) = coordCount;
        //  dv(1) = 8;
        //  dv(2) = 3;

        cvf::Vec3d cornerVerts[8];
        size_t blockByteCount = activeCellCount * sizeof(double);
        std::vector<double> doubleValues(blockByteCount);

        for (int coordIdx = 0; coordIdx < 3; coordIdx++)
        {
            for (size_t cornerIdx = 0; cornerIdx < 8; cornerIdx++)
            {
                size_t cornerIndexMapping = cellCornerMappingEclipse[cornerIdx];

                quint64 valueIndex = 0;

                for (size_t reservoirCellIndex = 0; reservoirCellIndex < mainGrid->globalCellArray().size(); reservoirCellIndex++)
                {
                    if (!actCellInfo->isActive(reservoirCellIndex)) continue;

                    mainGrid->cellCornerVertices(reservoirCellIndex, cornerVerts);

                    doubleValues[valueIndex++] = getCellCornerWithPositiveDepth(cornerVerts, cornerIndexMapping, coordIdx);
                }

                CVF_ASSERT(valueIndex == activeCellCount);

                RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)doubleValues.data(), blockByteCount);
            }
        }

        return true;
    }
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
void RivReservoirFaultsPartMgr::appendPartsToModel(cvf::ModelBasicList* model)
{
    CVF_ASSERT(model != NULL);

    RimFaultCollection* faultCollection = m_reservoirView->faultCollection();
    if (!faultCollection) return;

 
    bool isShowingGrid = faultCollection->isGridVisualizationMode();
    if (!faultCollection->showFaultCollection() && !isShowingGrid) return;
    
    // Check match between model fault count and fault parts
    CVF_ASSERT(faultCollection->faults.size() == m_faultParts.size());

    cvf::ModelBasicList parts;

    for (size_t i = 0; i < faultCollection->faults.size(); i++)
    {
        const RimFault* rimFault = faultCollection->faults[i];

        cvf::ref<RivFaultPartMgr> rivFaultPart = m_faultParts[i];
        CVF_ASSERT(rivFaultPart.notNull());

        // Parts that is overridden by the grid settings
        bool forceDisplayOfFault = false;
        if (!faultCollection->showFaultsOutsideFilters())
        {
            forceDisplayOfFault = isShowingGrid;
        }

        if (m_forceVisibility && isShowingGrid)
        {
            forceDisplayOfFault = true;
        }

        if ( (faultCollection->showFaultCollection() && rimFault->showFault()) || forceDisplayOfFault)
        {
            if (faultCollection->showFaultFaces() || forceDisplayOfFault)
            {
                rivFaultPart->appendNativeFaultFacesToModel(&parts);
            }

            if (faultCollection->showOppositeFaultFaces() || forceDisplayOfFault)
            {
                rivFaultPart->appendOppositeFaultFacesToModel(&parts);
            }

            if (faultCollection->showFaultFaces() || faultCollection->showOppositeFaultFaces() || faultCollection->showNNCs() || forceDisplayOfFault)
            {
                rivFaultPart->appendMeshLinePartsToModel(&parts);
            }
        }

        // Parts that is not overridden by the grid settings
        RimEclipseFaultColors* faultResultColors = m_reservoirView->faultResultSettings();
        RimEclipseCellColors* cellResultColors = m_reservoirView->cellResult();

        if (rimFault->showFault() && faultCollection->showFaultCollection())
        {
            if (faultCollection->showNNCs())
            {
                bool showNncs = true;
                if (faultCollection->hideNncsWhenNoResultIsAvailable())
                {
                    size_t scalarResultIndex = cvf::UNDEFINED_SIZE_T;
                    if (faultResultColors->showCustomFaultResult())
                    {
                        scalarResultIndex = faultResultColors->customFaultResult()->scalarResultIndex();
                    }
                    else
                    {
                        scalarResultIndex = cellResultColors->scalarResultIndex();
                    }

                    RigMainGrid* mainGrid = m_reservoirView->eclipseCase()->reservoirData()->mainGrid();
                    if (!(mainGrid && mainGrid->nncData()->hasScalarValues(scalarResultIndex)))
                    {
                        showNncs = false;
                    }
                }

                if (showNncs)
                {
                    rivFaultPart->appendNNCFacesToModel(&parts);
                }
            }
        }
    }

    for (size_t i = 0; i < parts.partCount(); i++)
    {
        cvf::Part* part = parts.part(i);
        part->setTransform(m_scaleTransform.p());
        
        model->addPart(part);
    }
}
//--------------------------------------------------------------------------------------------------
/// 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 #15
0
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
bool RifEclipseInputFileTools::openGridFile(const QString& fileName, RigEclipseCaseData* eclipseCase, bool readFaultData)
{
    CVF_ASSERT(eclipseCase);

    std::vector< RifKeywordAndFilePos > keywordsAndFilePos;
    findKeywordsOnFile(fileName, &keywordsAndFilePos);

    qint64 coordPos = -1;
    qint64 zcornPos = -1;
    qint64 specgridPos = -1;
    qint64 actnumPos = -1;
    qint64 mapaxesPos = -1;

    findGridKeywordPositions(keywordsAndFilePos, &coordPos, &zcornPos, &specgridPos, &actnumPos, &mapaxesPos);

    if (coordPos < 0 || zcornPos < 0 || specgridPos < 0)
    {
        QString errorText = QString("Failed to import grid file '%1'\n").arg(fileName);

        if (coordPos < 0)
        {
            errorText += "  Missing required keyword COORD";
        }

        if (zcornPos < 0)
        {
            errorText += "  Missing required keyword ZCORN";
        }

        if (specgridPos < 0)
        {
            errorText += "  Missing required keyword SPECGRID";
        }

        RiaLogging::error(errorText);

        return false;
    }


    FILE* gridFilePointer = util_fopen(fileName.toLatin1().data(), "r");
    if (!gridFilePointer) return false;

    // Main grid dimensions
    // SPECGRID - This is whats normally available, but not really the input to Eclipse.
    // DIMENS - Is what Eclipse expects and uses, but is not defined in the GRID section and is not (?) available normally
    // ZCORN, COORD, ACTNUM, MAPAXES

    //ecl_kw_type  *  ecl_kw_fscanf_alloc_grdecl_dynamic__( FILE * stream , const char * kw , bool strict , ecl_type_enum ecl_type);
    //ecl_grid_type * ecl_grid_alloc_GRDECL_kw( int nx, int ny , int nz , const ecl_kw_type * zcorn_kw , const ecl_kw_type * coord_kw , const ecl_kw_type * actnum_kw , const ecl_kw_type * mapaxes_kw ); 



    ecl_kw_type* specGridKw  = nullptr;
    ecl_kw_type* zCornKw     = nullptr;
    ecl_kw_type* coordKw     = nullptr;
    ecl_kw_type* actNumKw    = nullptr;
    ecl_kw_type* mapAxesKw   = nullptr;

    // Try to read all the needed keywords. Early exit if some are not found
    caf::ProgressInfo progress(8, "Read Grid from Eclipse Input file");



    bool allKwReadOk = true;

    fseek(gridFilePointer, specgridPos, SEEK_SET);
    allKwReadOk = allKwReadOk && nullptr != (specGridKw = ecl_kw_fscanf_alloc_current_grdecl__(gridFilePointer, false , ecl_type_create_from_type(ECL_INT_TYPE)));
    progress.setProgress(1);

    fseek(gridFilePointer, zcornPos, SEEK_SET);
    allKwReadOk = allKwReadOk && nullptr != (zCornKw    = ecl_kw_fscanf_alloc_current_grdecl__(gridFilePointer, false , ecl_type_create_from_type(ECL_FLOAT_TYPE)));
    progress.setProgress(2);

    fseek(gridFilePointer, coordPos, SEEK_SET);
    allKwReadOk = allKwReadOk && nullptr != (coordKw    = ecl_kw_fscanf_alloc_current_grdecl__(gridFilePointer, false , ecl_type_create_from_type(ECL_FLOAT_TYPE)));
    progress.setProgress(3);

    // If ACTNUM is not defined, this pointer will be NULL, which is a valid condition
    if (actnumPos >= 0)
    {
        fseek(gridFilePointer, actnumPos, SEEK_SET);
        allKwReadOk = allKwReadOk && nullptr != (actNumKw   = ecl_kw_fscanf_alloc_current_grdecl__(gridFilePointer, false , ecl_type_create_from_type(ECL_INT_TYPE)));
        progress.setProgress(4);
    }

    // If MAPAXES is not defined, this pointer will be NULL, which is a valid condition
    if (mapaxesPos >= 0)
    {
        fseek(gridFilePointer, mapaxesPos, SEEK_SET);
        mapAxesKw = ecl_kw_fscanf_alloc_current_grdecl__( gridFilePointer, false , ecl_type_create_from_type(ECL_FLOAT_TYPE));
    }

    if (!allKwReadOk)
    {
        if(specGridKw) ecl_kw_free(specGridKw);
        if(zCornKw) ecl_kw_free(zCornKw);
        if(coordKw) ecl_kw_free(coordKw);
        if(actNumKw) ecl_kw_free(actNumKw);
        if(mapAxesKw) ecl_kw_free(mapAxesKw);

        return false;
    }

    progress.setProgress(5);

    int nx = ecl_kw_iget_int(specGridKw, 0); 
    int ny = ecl_kw_iget_int(specGridKw, 1); 
    int nz = ecl_kw_iget_int(specGridKw, 2);

    ecl_grid_type* inputGrid = ecl_grid_alloc_GRDECL_kw( nx, ny, nz, zCornKw, coordKw, actNumKw, mapAxesKw ); 

    progress.setProgress(6);

    RifReaderEclipseOutput::transferGeometry(inputGrid, eclipseCase);

    progress.setProgress(7);
    progress.setProgressDescription("Read faults ...");

    if (readFaultData)
    {
        cvf::Collection<RigFault> faults;
        RifEclipseInputFileTools::readFaults(fileName, keywordsAndFilePos, &faults);

        RigMainGrid* mainGrid = eclipseCase->mainGrid();
        mainGrid->setFaults(faults);
    }
    
    progress.setProgress(8);
    progress.setProgressDescription("Cleaning up ...");

    ecl_kw_free(specGridKw);
    ecl_kw_free(zCornKw);
    ecl_kw_free(coordKw);
    if (actNumKw) ecl_kw_free(actNumKw);
    if (mapAxesKw) ecl_kw_free(mapAxesKw);

    ecl_grid_free(inputGrid);

    util_fclose(gridFilePointer);
    
    return true;
}
Example #16
0
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
void RigReservoirBuilderMock::addFaults(RigEclipseCaseData* eclipseCase)
{
    if (!eclipseCase) return;

    RigMainGrid* grid = eclipseCase->mainGrid();
    if (!grid) return;

    cvf::Collection<RigFault> faults;

    {
        cvf::ref<RigFault> fault = new RigFault;
        fault->setName("Fault A");
        
        cvf::Vec3st min = cvf::Vec3st::ZERO;
        cvf::Vec3st max(0, 0, cellDimension().z() - 2);
        
        if (cellDimension().x() > 5)
        {
            min.x() = cellDimension().x() / 2;
            max.x() = min.x() + 2;
        }
        
        if (cellDimension().y() > 5)
        {
            min.y() = cellDimension().y() / 2;
            max.y() = cellDimension().y() / 2;
        }

        cvf::CellRange cellRange(min, max);

        fault->addCellRangeForFace(cvf::StructGridInterface::POS_I, cellRange);
        faults.push_back(fault.p());
    }

    grid->setFaults(faults);

    // NNCs
    std::vector<RigConnection>& nncConnections = grid->nncData()->connections();
    {
        size_t i1 = 2;
        size_t j1 = 2;
        size_t k1 = 3;
        
        size_t i2 = 2;
        size_t j2 = 3;
        size_t k2 = 4;

        addNnc(grid, i1, j1, k1, i2, j2, k2, nncConnections);
    }

    {
        size_t i1 = 2;
        size_t j1 = 2;
        size_t k1 = 3;

        size_t i2 = 2;
        size_t j2 = 1;
        size_t k2 = 4;

        addNnc(grid, i1, j1, k1, i2, j2, k2, nncConnections);
    }

    std::vector<double>& tranVals = grid->nncData()->makeStaticConnectionScalarResult(RigNNCData::propertyNameCombTrans());
    for (size_t cIdx = 0; cIdx < tranVals.size(); ++cIdx)
    {
        tranVals[cIdx] = 0.2;
    }

}
Example #17
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.globalCellArray()[m_connections[cnIdx].m_c1GlobIdx];
        const RigCell& c2 = mainGrid.globalCellArray()[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));
        }
    }
}