void CpGrid::createCartesian(const array<int, 3>& dims, const array<double, 3>& cellsize) { // Make the grdecl format arrays. // Pillar coords. std::vector<double> coord; coord.reserve(6*(dims[0] + 1)*(dims[1] + 1)); double bot = 0.0; double top = dims[2]*cellsize[2]; // i runs fastest for the pillars. for (int j = 0; j < dims[1] + 1; ++j) { double y = j*cellsize[1]; for (int i = 0; i < dims[0] + 1; ++i) { double x = i*cellsize[0]; double pillar[6] = { x, y, bot, x, y, top }; coord.insert(coord.end(), pillar, pillar + 6); } } std::vector<double> zcorn(8*dims[0]*dims[1]*dims[2]); const int num_per_layer = 4*dims[0]*dims[1]; double* offset = &zcorn[0]; for (int k = 0; k < dims[2]; ++k) { double zlow = k*cellsize[2]; std::fill(offset, offset + num_per_layer, zlow); offset += num_per_layer; double zhigh = (k+1)*cellsize[2]; std::fill(offset, offset + num_per_layer, zhigh); offset += num_per_layer; } std::vector<int> actnum(dims[0]*dims[1]*dims[2], 1); // Process them. grdecl g; g.dims[0] = dims[0]; g.dims[1] = dims[1]; g.dims[2] = dims[2]; g.coord = &coord[0]; g.zcorn = &zcorn[0]; g.actnum = &actnum[0]; processEclipseFormat(g, 0.0, false, false); }
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); } }