Esempio n. 1
0
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
void RigMainGrid::calculateFaults(const RigActiveCellInfo* activeCellInfo)
{
    m_faultsPrCellAcc = new RigFaultsPrCellAccumulator(m_cells.size());

    // Spread fault idx'es on the cells from the faults
    for (size_t fIdx = 0 ; fIdx < m_faults.size(); ++fIdx)
    {
        m_faults[fIdx]->accumulateFaultsPrCell(m_faultsPrCellAcc.p(), static_cast<int>(fIdx));
    }

    // Find the geometrical faults that is in addition: Has no user defined (eclipse) fault assigned.
    // Separate the grid faults that has an inactive cell as member

    RigFault* unNamedFault = new RigFault;
    unNamedFault->setName(RimDefines::undefinedGridFaultName());
    int unNamedFaultIdx = static_cast<int>(m_faults.size());
    m_faults.push_back(unNamedFault);

    RigFault* unNamedFaultWithInactive = new RigFault;
    unNamedFaultWithInactive->setName(RimDefines::undefinedGridFaultWithInactiveName());
    int unNamedFaultWithInactiveIdx = static_cast<int>(m_faults.size());
    m_faults.push_back(unNamedFaultWithInactive);

    const std::vector<cvf::Vec3d>& vxs = m_mainGrid->nodes();

    for (int gcIdx = 0 ; gcIdx < static_cast<int>(m_cells.size()); ++gcIdx)
    {
        if ( m_cells[gcIdx].isInvalid())
        {
            continue;
        }

        size_t neighborReservoirCellIdx;
        size_t neighborGridCellIdx;
        size_t i, j, k;
        RigGridBase* hostGrid = NULL; 
        bool firstNO_FAULTFaceForCell = true;
        bool isCellActive = true;

        for (char faceIdx = 0; faceIdx < 6; ++faceIdx)
        {
            cvf::StructGridInterface::FaceType face = cvf::StructGridInterface::FaceType(faceIdx);

            // For faces that has no used defined Fault assigned:

            if (m_faultsPrCellAcc->faultIdx(gcIdx, face) == RigFaultsPrCellAccumulator::NO_FAULT)
            {
                // Find neighbor cell
                if (firstNO_FAULTFaceForCell) // To avoid doing this for every face, and only when detecting a NO_FAULT
                {
                    hostGrid = m_cells[gcIdx].hostGrid();
                    hostGrid->ijkFromCellIndex(m_cells[gcIdx].gridLocalCellIndex(), &i,&j, &k);
                    isCellActive = activeCellInfo->isActive(gcIdx);

                    firstNO_FAULTFaceForCell = false;
                }

                if(!hostGrid->cellIJKNeighbor(i, j, k, face, &neighborGridCellIdx))
                {
                    continue;
                }

                neighborReservoirCellIdx = hostGrid->reservoirCellIndex(neighborGridCellIdx);
                if (m_cells[neighborReservoirCellIdx].isInvalid())
                {
                    continue;
                }

                bool isNeighborCellActive = activeCellInfo->isActive(neighborReservoirCellIdx);

                double tolerance = 1e-6;

                caf::SizeTArray4 faceIdxs;
                m_cells[gcIdx].faceIndices(face, &faceIdxs);
                caf::SizeTArray4 nbFaceIdxs;
                m_cells[neighborReservoirCellIdx].faceIndices(StructGridInterface::oppositeFace(face), &nbFaceIdxs);


                bool sharedFaceVertices = true;
                if (sharedFaceVertices && vxs[faceIdxs[0]].pointDistance(vxs[nbFaceIdxs[0]]) > tolerance ) sharedFaceVertices = false;
                if (sharedFaceVertices && vxs[faceIdxs[1]].pointDistance(vxs[nbFaceIdxs[3]]) > tolerance ) sharedFaceVertices = false;
                if (sharedFaceVertices && vxs[faceIdxs[2]].pointDistance(vxs[nbFaceIdxs[2]]) > tolerance ) sharedFaceVertices = false;
                if (sharedFaceVertices && vxs[faceIdxs[3]].pointDistance(vxs[nbFaceIdxs[1]]) > tolerance ) sharedFaceVertices = false;

                if (sharedFaceVertices)
                {
                    continue;
                }

                // To avoid doing this calculation for the opposite face 
                int faultIdx = unNamedFaultIdx;
                if (!(isCellActive && isNeighborCellActive)) faultIdx = unNamedFaultWithInactiveIdx;

                m_faultsPrCellAcc->setFaultIdx(gcIdx, face, faultIdx);
                m_faultsPrCellAcc->setFaultIdx(neighborReservoirCellIdx, StructGridInterface::oppositeFace(face), faultIdx);

                // Add as fault face only if the grid index is less than the neighbors

                if (static_cast<size_t>(gcIdx) < neighborReservoirCellIdx)
                {
                    RigFault::FaultFace ff(gcIdx, cvf::StructGridInterface::FaceType(faceIdx), neighborReservoirCellIdx);
                    if(isCellActive && isNeighborCellActive)
                    {
                        unNamedFault->faultFaces().push_back(ff);
                    }
                    else
                    {
                        unNamedFaultWithInactive->faultFaces().push_back(ff);
                    }
                }
                else
                {
                    CVF_FAIL_MSG("Found fault with global neighbor index less than the native index. "); // Should never occur. because we flag the opposite face in the faultsPrCellAcc
                }
            }
        }
    }

    distributeNNCsToFaults();
}
Esempio n. 2
0
//--------------------------------------------------------------------------------------------------
/// The file pointer is pointing at the line following the FAULTS keyword.
/// Parse content of this keyword until end of file or
/// end of keyword when a single line with '/' is found
//--------------------------------------------------------------------------------------------------
void RifEclipseInputFileTools::readFaults(QFile &data, qint64 filePos, cvf::Collection<RigFault>* faults, bool* isEditKeywordDetected)
{
    if (!data.seek(filePos))
    {
        return;
    }

    // qDebug() << "Reading faults from\n  " << data.fileName();

    RigFault* fault = nullptr;

    do 
    {
        QString line = data.readLine();
        line = line.trimmed();

        if (line.startsWith("--", Qt::CaseInsensitive))
        {
            // Skip comment lines
            continue;
        }
        else if (line.startsWith("/", Qt::CaseInsensitive))
        {
            // Detected end of keyword data section
            return;
        }
        else if (line.startsWith(editKeyword, Qt::CaseInsensitive))
        {
            // End parsing when edit keyword is detected

            if (isEditKeywordDetected)
            {
                *isEditKeywordDetected = true;
            }

            return;
        }

        // Replace tab with space to be able to split the string using space as splitter
        line.replace("\t", " ");

        // Remove character ' used to mark start and end of fault name, possibly also around face definition; 'I+'
        line.remove("'");

        QStringList entries = line.split(" ", QString::SkipEmptyParts);
        if (entries.size() < 8)
        {
            continue;
        }

        QString name = entries[0];

        int i1, i2, j1, j2, k1, k2;
        i1 = entries[1].toInt();
        i2 = entries[2].toInt();
        j1 = entries[3].toInt();
        j2 = entries[4].toInt();
        k1 = entries[5].toInt();
        k2 = entries[6].toInt();

        QString faceString = entries[7];

        cvf::StructGridInterface::FaceEnum cellFaceEnum = RifEclipseInputFileTools::faceEnumFromText(faceString);

        // Adjust from 1-based to 0-based cell indices
        // Guard against invalid cell ranges by limiting lowest possible range value to zero
        cvf::CellRange cellrange(CVF_MAX(i1 - 1, 0), CVF_MAX(j1 - 1, 0), CVF_MAX(k1 - 1, 0), CVF_MAX(i2 - 1, 0), CVF_MAX(j2 - 1, 0), CVF_MAX(k2 - 1, 0));

        if (!(fault && fault->name() == name))
        {
            if (findFaultByName(*faults, name) == cvf::UNDEFINED_SIZE_T)
            {
                RigFault* newFault = new RigFault;
                newFault->setName(name);

                faults->push_back(newFault);
            }

            size_t faultIndex = findFaultByName(*faults, name);
            if (faultIndex == cvf::UNDEFINED_SIZE_T)
            {
                CVF_ASSERT(faultIndex != cvf::UNDEFINED_SIZE_T);
                continue;
            }

            fault = faults->at(faultIndex);
        }

        CVF_ASSERT(fault);

        fault->addCellRangeForFace(cellFaceEnum, cellrange);

    } while (!data.atEnd());
}