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); } }
// 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() ); }