void CpGridData::processEclipseFormat(const Opm::EclipseGrid& ecl_grid, bool periodic_extension, bool turn_normals, bool clip_z,
                                          const std::vector<double>& poreVolume)
    {
        std::vector<double> coordData;
        ecl_grid.exportCOORD(coordData);

        std::vector<int> actnumData;
        ecl_grid.exportACTNUM(actnumData);

        // Mutable because grdecl::zcorn is non-const.
        auto zcornData = getSanitizedZCORN(ecl_grid, actnumData);

        // Make input struct for processing code.
        grdecl g;
        g.dims[0] = ecl_grid.getNX();
        g.dims[1] = ecl_grid.getNY();
        g.dims[2] = ecl_grid.getNZ();
        g.coord = &coordData[0];
        g.zcorn = &zcornData[0];

        g.actnum = actnumData.empty() ? nullptr : &actnumData[0];

        // Possibly process MINPV
        if (!poreVolume.empty() && (ecl_grid.getMinpvMode() != Opm::MinpvMode::ModeEnum::Inactive)) {
            Opm::MinpvProcessor mp(g.dims[0], g.dims[1], g.dims[2]);
            // Currently the pinchProcessor is not used and only opmfil is supported
            //bool opmfil = ecl_grid.getMinpvMode() == Opm::MinpvMode::OpmFIL;
            bool opmfil = true;
            size_t cells_modified = mp.process(poreVolume, ecl_grid.getMinpvValue(), actnumData, opmfil, zcornData.data());
            if (cells_modified > 0) {
                this->zcorn = zcornData;
            }
        }

        // this variable is only required because getCellZvals() needs
        // a coord_t instead of a plain integer pointer...
        coord_t logicalCartesianSize;
        for (int axisIdx = 0; axisIdx < 3; ++axisIdx)
            logicalCartesianSize[axisIdx] = g.dims[axisIdx];

        // Handle zcorn clipping. The g variable points to the data in
        // the clipped_zcorn variable, i.e. clipped_zcorn must remain
        // in scope.
        std::vector<double> clipped_zcorn;
        if (clip_z) {
            double minz_top = 1e100;
            double maxz_bot = -1e100;
            for (int i = 0; i < g.dims[0]; ++i) {
                for (int j = 0; j < g.dims[1]; ++j) {
                    coord_t logicalCartesianCoord;
                    logicalCartesianCoord[0] = i;
                    logicalCartesianCoord[1] = j;

                    logicalCartesianCoord[2] = 0;
                    std::array<double, 8> cellz_bot = getCellZvals(logicalCartesianCoord, logicalCartesianSize, &zcornData[0]);

                    logicalCartesianCoord[2] = g.dims[2] - 1;
                    std::array<double, 8> cellz_top = getCellZvals(logicalCartesianCoord, logicalCartesianSize, &zcornData[0]);

                    for (int dd = 0; dd < 4; ++dd) {
                        minz_top = std::min(cellz_top[dd+4], minz_top);
                        maxz_bot = std::max(cellz_bot[dd], maxz_bot);
                    }
                }
            }
            if (minz_top <= maxz_bot) {
                OPM_THROW(std::runtime_error, "Grid cannot be clipped to a shoe-box (in z): Would be empty afterwards.");
            }
            int num_zcorn = zcornData.size();
            clipped_zcorn.resize(num_zcorn);
            for (int i = 0; i < num_zcorn; ++i) {
                clipped_zcorn[i] = std::max(maxz_bot, std::min(minz_top, g.zcorn[i]));
            }
            g.zcorn = &clipped_zcorn[0];
            this->zcorn = clipped_zcorn;
        }

        // Get z_tolerance.
        const double z_tolerance = ecl_grid.isPinchActive() ?
            ecl_grid.getPinchThresholdThickness() : 0.0;

        if (periodic_extension) {
            // Extend grid periodically with one layer of cells in the (i, j) directions.
            std::vector<double> new_coord;
            std::vector<double> new_zcorn;
            std::vector<int> new_actnum;
            grdecl new_g;
            addOuterCellLayer(g, new_coord, new_zcorn, new_actnum, new_g);
            // Make the grid.
            processEclipseFormat(new_g, z_tolerance, true, turn_normals);
        } else {
            // Make the grid.
            processEclipseFormat(g, z_tolerance, false, turn_normals);
        }
    }
Beispiel #2
0
    // Construct corner-point grid from EclipseGrid.
    void GridManager::initFromEclipseGrid(const Opm::EclipseGrid& inputGrid,
                                          const std::vector<double>& poreVolumes)
    {
        struct grdecl g;
        std::vector<int> actnum;
        std::vector<double> coord;
        std::vector<double> zcorn;
        std::vector<double> mapaxes;

        g.dims[0] = inputGrid.getNX();
        g.dims[1] = inputGrid.getNY();
        g.dims[2] = inputGrid.getNZ();

        inputGrid.exportMAPAXES( mapaxes );
        inputGrid.exportCOORD( coord );
        inputGrid.exportZCORN( zcorn );
        inputGrid.exportACTNUM( actnum );

        g.coord = coord.data();
        g.zcorn = zcorn.data();
        g.actnum = actnum.data();
        g.mapaxes = mapaxes.data();

        if (!poreVolumes.empty() && (inputGrid.getMinpvMode() != MinpvMode::ModeEnum::Inactive)) {
            MinpvProcessor mp(g.dims[0], g.dims[1], g.dims[2]);
            const std::vector<double>& minpvv  = inputGrid.getMinpvVector();
            const size_t cartGridSize = g.dims[0] * g.dims[1] * g.dims[2];
            std::vector<double> thickness(cartGridSize);
            for (size_t i = 0; i < cartGridSize; ++i) {
                thickness[i] = inputGrid.getCellThicknes(i);
            }

            // The legacy code only supports the opmfil option
            bool opmfil = true; //inputGrid.getMinpvMode() == MinpvMode::OpmFIL;
            const double z_tolerance = inputGrid.isPinchActive() ? inputGrid.getPinchThresholdThickness() : 0.0;
            mp.process(thickness, z_tolerance, poreVolumes, minpvv, actnum, opmfil, zcorn.data());
        }

        const double z_tolerance = inputGrid.isPinchActive() ? inputGrid.getPinchThresholdThickness() : 0.0;
        ug_ = create_grid_cornerpoint(&g, z_tolerance);
        if (!ug_) {
            OPM_THROW(std::runtime_error, "Failed to construct grid.");
        }

        attach_zcorn_copy( ug_ , zcorn.data() );

    }