CornerPointChopper(const std::string& file) { Opm::ParseMode parseMode; Opm::ParserPtr parser(new Opm::Parser()); deck_ = parser->parseFile(file , parseMode); metricUnits_.reset(Opm::UnitSystem::newMETRIC()); Opm::DeckRecordConstPtr specgridRecord = deck_->getKeyword("SPECGRID")->getRecord(0); dims_[0] = specgridRecord->getItem("NX")->getInt(0); dims_[1] = specgridRecord->getItem("NY")->getInt(0); dims_[2] = specgridRecord->getItem("NZ")->getInt(0); int layersz = 8*dims_[0]*dims_[1]; const std::vector<double>& ZCORN = deck_->getKeyword("ZCORN")->getRawDoubleData(); botmax_ = *std::max_element(ZCORN.begin(), ZCORN.begin() + layersz/2); topmin_ = *std::min_element(ZCORN.begin() + dims_[2]*layersz - layersz/2, ZCORN.begin() + dims_[2]*layersz); abszmax_ = *std::max_element(ZCORN.begin(), ZCORN.end()); abszmin_ = *std::min_element(ZCORN.begin(), ZCORN.end()); std::cout << "Parsed grdecl file with dimensions (" << dims_[0] << ", " << dims_[1] << ", " << dims_[2] << ")" << std::endl; }
void BlackoilPVT::init(Opm::DeckConstPtr deck) { Opm::ParseMode parseMode; const auto eclipseState = std::make_shared<EclipseState>(deck , parseMode); region_number_ = 0; // Surface densities. Accounting for different orders in eclipse and our code. if (deck->hasKeyword("DENSITY")) { Opm::DeckRecordConstPtr densityRecord = deck->getKeyword("DENSITY")->getRecord(/*regionIdx=*/0); densities_[Aqua] = densityRecord->getItem("WATER")->getSIDouble(0); densities_[Vapour] = densityRecord->getItem("GAS")->getSIDouble(0); densities_[Liquid] = densityRecord->getItem("OIL")->getSIDouble(0); } else { OPM_THROW(std::runtime_error, "Input is missing DENSITY\n"); } // Water PVT if (deck->hasKeyword("PVTW")) { water_props_.reset(new MiscibilityWater(deck->getKeyword("PVTW"))); } else { water_props_.reset(new MiscibilityWater(0.5*Opm::prefix::centi*Opm::unit::Poise)); // Eclipse 100 default } // Oil PVT const auto& tables = eclipseState->getTableManager(); const auto& pvdoTables = tables->getPvdoTables(); const auto& pvtoTables = tables->getPvtoTables(); if (!pvdoTables.empty()) { const auto& pvdoTable = pvdoTables.getTable<PvdoTable>(0); oil_props_.reset(new MiscibilityDead(pvdoTable)); } else if (pvtoTables.empty()) { // PVTOTables is a std::vector<> const auto& pvtoTable = pvtoTables[0]; oil_props_.reset(new MiscibilityLiveOil(pvtoTable)); } else if (deck->hasKeyword("PVCDO")) { auto *misc_water = new MiscibilityWater(0); misc_water->initFromPvcdo(deck->getKeyword("PVCDO")); oil_props_.reset(misc_water); } else { OPM_THROW(std::runtime_error, "Input is missing PVDO and PVTO\n"); } // Gas PVT const auto& pvdgTables = tables->getPvdgTables(); const auto& pvtgTables = tables->getPvtgTables(); if (!pvdgTables.empty()) { const auto& pvdgTable = pvdgTables.getTable<PvdgTable>(0); gas_props_.reset(new MiscibilityDead(pvdgTable)); } else if (pvtgTables.empty()) { gas_props_.reset(new MiscibilityLiveGas(pvtgTables[0])); } else { OPM_THROW(std::runtime_error, "Input is missing PVDG and PVTG\n"); } }
std::vector<double> getMapaxesValues(Opm::DeckConstPtr deck) { Opm::DeckRecordConstPtr mapaxesRecord = deck->getKeyword("MAPAXES")->getRecord(0); std::vector<double> result; for (size_t itemIdx = 0; itemIdx < mapaxesRecord->size(); ++itemIdx) { Opm::DeckItemConstPtr curItem = mapaxesRecord->getItem(itemIdx); for (size_t dataItemIdx = 0; dataItemIdx < curItem->size(); ++dataItemIdx) { result.push_back(curItem->getRawDouble(dataItemIdx)); } } return result; }
void GridManager::createGrdecl(Opm::DeckConstPtr deck, struct grdecl &grdecl) { // Extract data from deck. const std::vector<double>& zcorn = deck->getKeyword("ZCORN")->getSIDoubleData(); const std::vector<double>& coord = deck->getKeyword("COORD")->getSIDoubleData(); const int* actnum = NULL; if (deck->hasKeyword("ACTNUM")) { actnum = &(deck->getKeyword("ACTNUM")->getIntData()[0]); } std::array<int, 3> dims; if (deck->hasKeyword("DIMENS")) { Opm::DeckKeywordConstPtr dimensKeyword = deck->getKeyword("DIMENS"); dims[0] = dimensKeyword->getRecord(0)->getItem(0)->getInt(0); dims[1] = dimensKeyword->getRecord(0)->getItem(1)->getInt(0); dims[2] = dimensKeyword->getRecord(0)->getItem(2)->getInt(0); } else if (deck->hasKeyword("SPECGRID")) { Opm::DeckKeywordConstPtr specgridKeyword = deck->getKeyword("SPECGRID"); dims[0] = specgridKeyword->getRecord(0)->getItem(0)->getInt(0); dims[1] = specgridKeyword->getRecord(0)->getItem(1)->getInt(0); dims[2] = specgridKeyword->getRecord(0)->getItem(2)->getInt(0); } else { OPM_THROW(std::runtime_error, "Deck must have either DIMENS or SPECGRID."); } // Collect in input struct for preprocessing. grdecl.zcorn = &zcorn[0]; grdecl.coord = &coord[0]; grdecl.actnum = actnum; grdecl.dims[0] = dims[0]; grdecl.dims[1] = dims[1]; grdecl.dims[2] = dims[2]; if (deck->hasKeyword("MAPAXES")) { Opm::DeckKeywordConstPtr mapaxesKeyword = deck->getKeyword("MAPAXES"); Opm::DeckRecordConstPtr mapaxesRecord = mapaxesKeyword->getRecord(0); // memleak alert: here we need to make sure that C code // can properly take ownership of the grdecl.mapaxes // object. if it is not freed, it will result in a // memleak... double *cWtfMapaxes = static_cast<double*>(malloc(sizeof(double)*mapaxesRecord->size())); for (unsigned i = 0; i < mapaxesRecord->size(); ++i) cWtfMapaxes[i] = mapaxesRecord->getItem(i)->getSIDouble(0); grdecl.mapaxes = cWtfMapaxes; } else grdecl.mapaxes = NULL; }
/// Mirror keyword SPECGRID in deck void mirror_specgrid(Opm::DeckConstPtr deck, std::string direction, std::ofstream& out) { // We only need to multiply the dimension by 2 in the correct direction. Opm::DeckRecordConstPtr specgridRecord = deck->getKeyword("SPECGRID")->getRecord(0); std::vector<int> dimensions(3); dimensions[0] = specgridRecord->getItem("NX")->getInt(0); dimensions[1] = specgridRecord->getItem("NY")->getInt(0); dimensions[2] = specgridRecord->getItem("NZ")->getInt(0); if (direction == "x") {dimensions[0] *= 2;} else if (direction == "y") {dimensions[1] *= 2;} else {std::cerr << "Direction should be either x or y" << std::endl; exit(1);} out << "SPECGRID" << std::endl << dimensions[0] << " " << dimensions[1] << " " << dimensions[2] << " " << specgridRecord->getItem("NUMRES")->getInt(0) << " " << specgridRecord->getItem("COORD_TYPE")->getString(0) << " " << std::endl << "/" << std::endl << std::endl; }
IncompPropertiesSinglePhase::IncompPropertiesSinglePhase(Opm::DeckConstPtr deck, Opm::EclipseStateConstPtr eclState, const UnstructuredGrid& grid) { rock_.init(eclState, grid.number_of_cells, grid.global_cell, grid.cartdims); if (deck->hasKeyword("DENSITY")) { Opm::DeckRecordConstPtr densityRecord = deck->getKeyword("DENSITY")->getRecord(0); surface_density_ = densityRecord->getItem("OIL")->getSIDouble(0); } else { surface_density_ = 1000.0; OPM_MESSAGE("Input is missing DENSITY -- using a standard density of " << surface_density_ << ".\n"); } // This will be modified if we have a PVCDO specification. reservoir_density_ = surface_density_; if (deck->hasKeyword("PVCDO")) { Opm::DeckRecordConstPtr pvcdoRecord = deck->getKeyword("PVCDO")->getRecord(0); if (pvcdoRecord->getItem("OIL_COMPRESSIBILITY")->getSIDouble(0) != 0.0 || pvcdoRecord->getItem("OIL_VISCOSIBILITY")->getSIDouble(0) != 0.0) { OPM_MESSAGE("Compressibility effects in PVCDO are ignored."); } reservoir_density_ /= pvcdoRecord->getItem("OIL_VOL_FACTOR")->getSIDouble(0); viscosity_ = pvcdoRecord->getItem("OIL_VISCOSITY")->getSIDouble(0); } else { viscosity_ = 1.0 * prefix::centi*unit::Poise; OPM_MESSAGE("Input is missing PVCDO -- using a standard viscosity of " << viscosity_ << " and reservoir density equal to surface density.\n"); } }
void EclipseGridInspector::init_() { if (!deck_->hasKeyword("COORD")) { OPM_THROW(std::runtime_error, "Needed field \"COORD\" is missing in file"); } if (!deck_->hasKeyword("ZCORN")) { OPM_THROW(std::runtime_error, "Needed field \"ZCORN\" is missing in file"); } if (deck_->hasKeyword("SPECGRID")) { Opm::DeckRecordConstPtr specgridRecord = deck_->getKeyword("SPECGRID")->getRecord(0); logical_gridsize_[0] = specgridRecord->getItem("NX")->getInt(0); logical_gridsize_[1] = specgridRecord->getItem("NY")->getInt(0); logical_gridsize_[2] = specgridRecord->getItem("NZ")->getInt(0); } else if (deck_->hasKeyword("DIMENS")) { Opm::DeckRecordConstPtr dimensRecord = deck_->getKeyword("DIMENS")->getRecord(0); logical_gridsize_[0] = dimensRecord->getItem("NX")->getInt(0); logical_gridsize_[1] = dimensRecord->getItem("NY")->getInt(0); logical_gridsize_[2] = dimensRecord->getItem("NZ")->getInt(0); } else { OPM_THROW(std::runtime_error, "Found neither SPECGRID nor DIMENS in file. At least one is needed."); } }
void initFromOil(Opm::DeckKeywordConstPtr pvcdoKeyword) { int numRegions = pvcdoKeyword->size(); ref_press_.resize(numRegions); ref_B_.resize(numRegions); comp_.resize(numRegions); viscosity_.resize(numRegions); visc_comp_.resize(numRegions); for (int regionIdx = 0; regionIdx < numRegions; ++ regionIdx) { Opm::DeckRecordConstPtr pvcdoRecord = pvcdoKeyword->getRecord(regionIdx); ref_press_[regionIdx] = pvcdoRecord->getItem("P_REF")->getSIDouble(0); ref_B_[regionIdx] = pvcdoRecord->getItem("OIL_VOL_FACTOR")->getSIDouble(0); comp_[regionIdx] = pvcdoRecord->getItem("OIL_COMPRESSIBILITY")->getSIDouble(0); viscosity_[regionIdx] = pvcdoRecord->getItem("OIL_VISCOSITY")->getSIDouble(0); visc_comp_[regionIdx] = pvcdoRecord->getItem("OIL_VISCOSIBILITY")->getSIDouble(0); } }
void mirror_celldata(std::string keyword, Opm::DeckConstPtr deck, std::string direction, std::ofstream& out) { if ( ! deck->hasKeyword(keyword)) { std::cout << "Ignoring keyword " << keyword << " as it was not found." << std::endl; return; } // Get data from eclipse deck Opm::DeckRecordConstPtr specgridRecord = deck->getKeyword("SPECGRID")->getRecord(0); std::vector<int> dimensions(3); dimensions[0] = specgridRecord->getItem("NX")->getInt(0); dimensions[1] = specgridRecord->getItem("NY")->getInt(0); dimensions[2] = specgridRecord->getItem("NZ")->getInt(0); std::vector<T> values = getKeywordValues(keyword, deck, T(0.0)); std::vector<T> values_mirrored(2*dimensions[0]*dimensions[1]*dimensions[2], 0.0); // Handle the two directions differently due to ordering of the pillars. if (direction == "x") { typename std::vector<T>::iterator it_orig = values.begin(); typename std::vector<T>::iterator it_new = values_mirrored.begin(); // Loop through each line and copy old cell data and add new (which are the old reversed) for ( ; it_orig != values.end(); it_orig += dimensions[0]) { // Copy old cell data copy(it_orig, it_orig + dimensions[0], it_new); it_new += dimensions[0]; // Add new cell data std::vector<double> next_vec(it_orig, it_orig + dimensions[0]); std::vector<double> next_reversed = next_vec; reverse(next_reversed.begin(), next_reversed.end()); copy(next_reversed.begin(), next_reversed.end(), it_new); it_new += dimensions[0]; } } else if (direction =="y") { typename std::vector<T>::iterator it_orig = values.begin(); typename std::vector<T>::iterator it_new = values_mirrored.begin(); // Entries per layer const int entries_per_layer = dimensions[0]*dimensions[1]; // Loop through each layer and copy old cell data and add new (which are the old reordered) for ( ; it_orig != values.end(); it_orig += entries_per_layer) { // Copy old cell data copy(it_orig, it_orig + entries_per_layer, it_new); it_new += entries_per_layer; // Add new cell data std::vector<T> next_vec(it_orig, it_orig + entries_per_layer); std::vector<T> next_reordered(entries_per_layer, 0.0); typename std::vector<T>::iterator it_next = next_vec.end(); typename std::vector<T>::iterator it_reordered = next_reordered.begin(); // Reorder next entries for ( ; it_reordered != next_reordered.end(); it_reordered += dimensions[0]) { copy(it_next - dimensions[0], it_next, it_reordered); it_next -= dimensions[0]; } copy(next_reordered.begin(), next_reordered.end(), it_new); it_new += entries_per_layer; } } else { std::cerr << "Direction should be either x or y" << std::endl; exit(1); } // Write new keyword values to output file printKeywordValues(out, keyword, values_mirrored, 8); }
/// Mirror keyword ZCORN in deck void mirror_zcorn(Opm::DeckConstPtr deck, std::string direction, std::ofstream& out) { Opm::DeckRecordConstPtr specgridRecord = deck->getKeyword("SPECGRID")->getRecord(0); std::vector<int> dimensions(3); dimensions[0] = specgridRecord->getItem("NX")->getInt(0); dimensions[1] = specgridRecord->getItem("NY")->getInt(0); dimensions[2] = specgridRecord->getItem("NZ")->getInt(0); std::vector<double> zcorn = deck->getKeyword("ZCORN")->getRawDoubleData(); std::vector<double> zcorn_mirrored; // Handle the two directions differently due to ordering of the pillars. if (direction == "x") { // Total entries in mirrored ZCORN. Eight corners per cell. const int entries = dimensions[0]*2*dimensions[1]*dimensions[2]*8; zcorn_mirrored.assign(entries, 0.0); // Entries per line in x-direction. Two for each cell. const int entries_per_line = dimensions[0]*2; std::vector<double>::iterator it_new = zcorn_mirrored.begin(); std::vector<double>::iterator it_orig = zcorn.begin(); // Loop through each line and copy old corner-points and add new (which are the old reversed) for ( ; it_orig != zcorn.end(); it_orig += entries_per_line) { std::vector<double> next_vec(it_orig, it_orig + entries_per_line); std::vector<double> next_reversed = next_vec; reverse(next_reversed.begin(), next_reversed.end()); // Copy old corner-points copy(it_orig, it_orig + entries_per_line, it_new); it_new += entries_per_line; // Add new corner-points copy(next_reversed.begin(), next_reversed.end(), it_new); it_new += entries_per_line; } } else if (direction == "y") { // Total entries in mirrored ZCORN. Eight corners per cell. const int entries = dimensions[0]*dimensions[1]*2*dimensions[2]*8; zcorn_mirrored.assign(entries, 0.0); // Entries per line in x-direction. Two for each cell. const int entries_per_line_x = dimensions[0]*2; // Entries per layer of corner-points. Four for each cell const int entries_per_layer = dimensions[0]*dimensions[1]*4; std::vector<double>::iterator it_new = zcorn_mirrored.begin(); std::vector<double>::iterator it_orig = zcorn.begin(); // Loop through each layer and copy old corner-points and add new (which are the old reordered) for ( ; it_orig != zcorn.end(); it_orig += entries_per_layer) { // Copy old corner-points copy(it_orig, it_orig + entries_per_layer, it_new); it_new += entries_per_layer; // Add new corner-points std::vector<double> next_vec(it_orig, it_orig + entries_per_layer); std::vector<double> next_reordered(entries_per_layer, 0.0); std::vector<double>::iterator it_next = next_vec.end(); std::vector<double>::iterator it_reordered = next_reordered.begin(); // Reorder next entries for ( ; it_reordered != next_reordered.end(); it_reordered += entries_per_line_x) { copy(it_next - entries_per_line_x, it_next, it_reordered); it_next -= entries_per_line_x; } copy(next_reordered.begin(), next_reordered.end(), it_new); it_new += entries_per_layer; } } else { std::cerr << "Direction should be either x or y" << std::endl; exit(1); } // Write new ZCORN values to output file printKeywordValues(out, "ZCORN", zcorn_mirrored, 8); }
/// Mirror keyword COORD in deck void mirror_coord(Opm::DeckConstPtr deck, std::string direction, std::ofstream& out) { // We assume uniform spacing in x and y directions and parallel top and bottom faces Opm::DeckRecordConstPtr specgridRecord = deck->getKeyword("SPECGRID")->getRecord(0); std::vector<int> dimensions(3); dimensions[0] = specgridRecord->getItem("NX")->getInt(0); dimensions[1] = specgridRecord->getItem("NY")->getInt(0); dimensions[2] = specgridRecord->getItem("NZ")->getInt(0); std::vector<double> coord = deck->getKeyword("COORD")->getRawDoubleData(); const int entries_per_pillar = 6; std::vector<double> coord_mirrored; // Handle the two directions differently due to ordering of the pillars. if (direction == "x") { // Total entries in mirrored ZCORN. Number of pillars times 6 const int entries = (2*dimensions[0] + 1) * (dimensions[1] + 1) * entries_per_pillar; // Entries per line in x-direction. Number of pillars in x-direction times 6 const int entries_per_line = entries_per_pillar*(dimensions[0] + 1); coord_mirrored.assign(entries, 0.0); // Distance between pillars in x-directiion const double spacing = coord[entries_per_pillar]-coord[0]; std::vector<double>::iterator it_new = coord_mirrored.begin(); std::vector<double>::iterator it_orig; // Loop through each pillar line in the x-direction for (it_orig = coord.begin(); it_orig != coord.end(); it_orig += entries_per_line) { // Copy old pillars copy(it_orig, it_orig + entries_per_line, it_new); // Add new pillars in between it_new += entries_per_line; std::vector<double> next_vec(it_orig + entries_per_line - entries_per_pillar, it_orig + entries_per_line); for (int r=0; r < dimensions[0]; ++r) { next_vec[0] += spacing; next_vec[3] += spacing; copy(next_vec.begin(), next_vec.end(), it_new); it_new += entries_per_pillar; } } } else if (direction == "y") { // Total entries in mirrored ZCORN. Number of pillars times 6 const int entries = (dimensions[0] + 1) * (2*dimensions[1] + 1) * entries_per_pillar; // Entries per line in y-direction. Number of pillars in y-direction times 6 const int entries_per_line = entries_per_pillar*(dimensions[0] + 1); coord_mirrored.assign(entries, 0.0); // Distance between pillars in y-directiion const double spacing = coord[entries_per_line + 1]-coord[1]; std::vector<double>::iterator it_new = coord_mirrored.begin(); // Copy old pillars copy(coord.begin(), coord.end(), it_new); // Add new pillars at the end it_new += coord.size(); std::vector<double> next_vec(coord.end() - entries_per_line, coord.end()); for ( ; it_new != coord_mirrored.end(); it_new += entries_per_line) { for (int i = 1; i < entries_per_line; i += 3) { next_vec[i] += spacing; } copy(next_vec.begin(), next_vec.end(), it_new); } } else { std::cerr << "Direction should be either x or y" << std::endl; exit(1); } // Write new COORD values to output file printKeywordValues(out, "COORD", coord_mirrored, 6); }
/// set the tables which specify the temperature dependence of the water viscosity void initFromDeck(std::shared_ptr<const PvtInterface> isothermalPvt, Opm::DeckConstPtr deck, Opm::EclipseStateConstPtr eclipseState) { isothermalPvt_ = isothermalPvt; watvisctTables_ = 0; // stuff which we need to get from the PVTW keyword Opm::DeckKeywordConstPtr pvtwKeyword = deck->getKeyword("PVTW"); int numRegions = pvtwKeyword->size(); pvtwRefPress_.resize(numRegions); pvtwRefB_.resize(numRegions); pvtwCompressibility_.resize(numRegions); pvtwViscosity_.resize(numRegions); pvtwViscosibility_.resize(numRegions); for (int regionIdx = 0; regionIdx < numRegions; ++ regionIdx) { Opm::DeckRecordConstPtr pvtwRecord = pvtwKeyword->getRecord(regionIdx); pvtwRefPress_[regionIdx] = pvtwRecord->getItem("P_REF")->getSIDouble(0); pvtwRefB_[regionIdx] = pvtwRecord->getItem("WATER_VOL_FACTOR")->getSIDouble(0); pvtwViscosity_[regionIdx] = pvtwRecord->getItem("WATER_VISCOSITY")->getSIDouble(0); pvtwViscosibility_[regionIdx] = pvtwRecord->getItem("WATER_VISCOSIBILITY")->getSIDouble(0); } // quantities required for the temperature dependence of the viscosity // (basically we expect well-behaved VISCREF and WATVISCT keywords.) if (deck->hasKeyword("VISCREF")) { watvisctTables_ = &eclipseState->getWatvisctTables(); Opm::DeckKeywordConstPtr viscrefKeyword = deck->getKeyword("VISCREF"); assert(int(watvisctTables_->size()) == numRegions); assert(int(viscrefKeyword->size()) == numRegions); viscrefPress_.resize(numRegions); for (int regionIdx = 0; regionIdx < numRegions; ++ regionIdx) { Opm::DeckRecordConstPtr viscrefRecord = viscrefKeyword->getRecord(regionIdx); viscrefPress_[regionIdx] = viscrefRecord->getItem("REFERENCE_PRESSURE")->getSIDouble(0); } } // quantities required for the temperature dependence of the density if (deck->hasKeyword("WATDENT")) { DeckKeywordConstPtr watdentKeyword = deck->getKeyword("WATDENT"); assert(int(watdentKeyword->size()) == numRegions); watdentRefTemp_.resize(numRegions); watdentCT1_.resize(numRegions); watdentCT2_.resize(numRegions); for (int regionIdx = 0; regionIdx < numRegions; ++regionIdx) { Opm::DeckRecordConstPtr watdentRecord = watdentKeyword->getRecord(regionIdx); watdentRefTemp_[regionIdx] = watdentRecord->getItem("REFERENCE_TEMPERATURE")->getSIDouble(0); watdentCT1_[regionIdx] = watdentRecord->getItem("EXPANSION_COEFF_LINEAR")->getSIDouble(0); watdentCT2_[regionIdx] = watdentRecord->getItem("EXPANSION_COEFF_QUADRATIC")->getSIDouble(0); } } }