mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
flow_ebos: only instantiate the grid once
it now uses the grid object which gets created by ebos for everything which should make the parallelization efforts easier. I also tried to cut back the use of the legacy property objects (i.e., for the fluid, geologic and rock properties), but this effort ran aground because of the initialization and output code. (also, if those two were fixed, there would probably be issues with the Newton update.) I ran Norne with this and there did not seem to be any notable performance regressions or benefits.
This commit is contained in:
parent
28c36ef949
commit
5ebed2f500
@ -40,6 +40,7 @@ namespace Opm
|
||||
|
||||
typedef typename TTAG(EclFlowProblem) TypeTag;
|
||||
typedef typename GET_PROP_TYPE(TypeTag, Simulator) EbosSimulator;
|
||||
typedef typename GET_PROP_TYPE(TypeTag, Grid) Grid;
|
||||
|
||||
// Print startup message if on output rank.
|
||||
void printStartupMessage()
|
||||
@ -86,8 +87,26 @@ namespace Opm
|
||||
|
||||
Base::deck_ = ebosSimulator_->gridManager().deck();
|
||||
Base::eclipse_state_ = ebosSimulator_->gridManager().eclState();
|
||||
IOConfig& ioConfig = Base::eclipse_state_->getIOConfig();
|
||||
ioConfig.setOutputDir(Base::output_dir_);
|
||||
|
||||
try {
|
||||
if (Base::output_cout_) {
|
||||
MissingFeatures::checkKeywords(*Base::deck_);
|
||||
}
|
||||
|
||||
IOConfig& ioConfig = Base::eclipse_state_->getIOConfig();
|
||||
ioConfig.setOutputDir(Base::output_dir_);
|
||||
|
||||
// Possible to force initialization only behavior (NOSIM).
|
||||
if (Base::param_.has("nosim")) {
|
||||
const bool nosim = Base::param_.get<bool>("nosim");
|
||||
ioConfig.overrideNOSIM( nosim );
|
||||
}
|
||||
}
|
||||
catch (const std::invalid_argument& e) {
|
||||
std::cerr << "Failed to create valid EclipseState object. See logfile: " << logFile_ << std::endl;
|
||||
std::cerr << "Exception caught: " << e.what() << std::endl;
|
||||
throw;
|
||||
}
|
||||
|
||||
// Possibly override IOConfig setting (from deck) for how often RESTART files should get written to disk (every N report step)
|
||||
if (Base::param_.has("output_interval")) {
|
||||
@ -95,12 +114,136 @@ namespace Opm
|
||||
eclipse_state_->getRestartConfig().overrideRestartWriteInterval( size_t( output_interval ) );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Possible to force initialization only behavior (NOSIM).
|
||||
if (Base::param_.has("nosim")) {
|
||||
const bool nosim = Base::param_.get<bool>("nosim");
|
||||
ioConfig.overrideNOSIM( nosim );
|
||||
// Create grid and property objects.
|
||||
// Writes to:
|
||||
// grid_init_
|
||||
// material_law_manager_
|
||||
// fluidprops_
|
||||
// rock_comp_
|
||||
// gravity_
|
||||
// use_local_perm_
|
||||
// geoprops_
|
||||
void setupGridAndProps()
|
||||
{
|
||||
Dune::CpGrid& grid = ebosSimulator_->gridManager().grid();
|
||||
Base::material_law_manager_ = ebosSimulator_->problem().materialLawManager();
|
||||
grid_init_.reset(new GridInit<Grid>());
|
||||
grid_init_->setGrid(grid);
|
||||
|
||||
// create the legacy properties objects
|
||||
Base::fluidprops_.reset(new BlackoilPropsAdFromDeck(*deck_,
|
||||
*eclipse_state_,
|
||||
Base::material_law_manager_,
|
||||
grid));
|
||||
// Gravity.
|
||||
assert(UgGridHelpers::dimensions(grid) == 3);
|
||||
Base::gravity_.fill(0.0);
|
||||
Base::gravity_[2] = Base::deck_->hasKeyword("NOGRAV")
|
||||
? Base::param_.getDefault("gravity", 0.0)
|
||||
: Base::param_.getDefault("gravity", unit::gravity);
|
||||
|
||||
// Geological properties
|
||||
Base::use_local_perm_ = true;
|
||||
geoprops_.reset(new DerivedGeology(grid,
|
||||
*Base::fluidprops_,
|
||||
*Base::eclipse_state_,
|
||||
Base::use_local_perm_,
|
||||
Base::gravity_.data()));
|
||||
|
||||
}
|
||||
|
||||
// Initialise the reservoir state. Updated fluid props for SWATINIT.
|
||||
// Writes to:
|
||||
// state_
|
||||
// threshold_pressures_
|
||||
// fluidprops_ (if SWATINIT is used)
|
||||
void setupState()
|
||||
{
|
||||
const PhaseUsage pu = Opm::phaseUsageFromDeck(*deck_);
|
||||
const Grid& grid = Base::grid_init_->grid();
|
||||
|
||||
// Need old-style fluid object for init purposes (only).
|
||||
BlackoilPropertiesFromDeck props(*deck_,
|
||||
*Base::eclipse_state_,
|
||||
Base::material_law_manager_,
|
||||
grid.size(/*codim=*/0),
|
||||
grid.globalCell().data(),
|
||||
grid.logicalCartesianSize().data(),
|
||||
param_);
|
||||
|
||||
|
||||
// Init state variables (saturation and pressure).
|
||||
if (param_.has("init_saturation")) {
|
||||
state_.reset(new ReservoirState(grid.size(/*codim=*/0),
|
||||
grid.numFaces(),
|
||||
props.numPhases()));
|
||||
|
||||
initStateBasic(grid.size(/*codim=*/0),
|
||||
grid.globalCell().data(),
|
||||
grid.logicalCartesianSize().data(),
|
||||
grid.numFaces(),
|
||||
Opm::UgGridHelpers::faceCells(grid),
|
||||
Opm::UgGridHelpers::beginFaceCentroids(grid),
|
||||
Opm::UgGridHelpers::beginCellCentroids(grid),
|
||||
Grid::dimension,
|
||||
props, param_, gravity_[2], *state_);
|
||||
|
||||
initBlackoilSurfvol(Opm::UgGridHelpers::numCells(grid), props, *state_);
|
||||
|
||||
enum { Oil = BlackoilPhases::Liquid, Gas = BlackoilPhases::Vapour };
|
||||
if (pu.phase_used[Oil] && pu.phase_used[Gas]) {
|
||||
const int numPhases = props.numPhases();
|
||||
const int numCells = Opm::UgGridHelpers::numCells(grid);
|
||||
|
||||
// Uglyness 1: The state is a templated type, here we however make explicit use BlackoilState.
|
||||
auto& gor = state_->getCellData( BlackoilState::GASOILRATIO );
|
||||
const auto& surface_vol = state_->getCellData( BlackoilState::SURFACEVOL );
|
||||
for (int c = 0; c < numCells; ++c) {
|
||||
// Uglyness 2: Here we explicitly use the layout of the saturation in the surface_vol field.
|
||||
gor[c] = surface_vol[ c * numPhases + pu.phase_pos[Gas]] / surface_vol[ c * numPhases + pu.phase_pos[Oil]];
|
||||
}
|
||||
}
|
||||
} else if (deck_->hasKeyword("EQUIL")) {
|
||||
// Which state class are we really using - what a f... mess?
|
||||
state_.reset( new ReservoirState( Opm::UgGridHelpers::numCells(grid),
|
||||
Opm::UgGridHelpers::numFaces(grid),
|
||||
props.numPhases()));
|
||||
|
||||
initStateEquil(grid, props, *deck_, *Base::eclipse_state_, gravity_[2], *state_);
|
||||
//state_.faceflux().resize(Opm::UgGridHelpers::numFaces(grid), 0.0);
|
||||
} else {
|
||||
state_.reset( new ReservoirState( Opm::UgGridHelpers::numCells(grid),
|
||||
Opm::UgGridHelpers::numFaces(grid),
|
||||
props.numPhases()));
|
||||
initBlackoilStateFromDeck(Opm::UgGridHelpers::numCells(grid),
|
||||
Opm::UgGridHelpers::globalCell(grid),
|
||||
Opm::UgGridHelpers::numFaces(grid),
|
||||
Opm::UgGridHelpers::faceCells(grid),
|
||||
Opm::UgGridHelpers::beginFaceCentroids(grid),
|
||||
Opm::UgGridHelpers::beginCellCentroids(grid),
|
||||
Opm::UgGridHelpers::dimensions(grid),
|
||||
props, *deck_, gravity_[2], *state_);
|
||||
}
|
||||
|
||||
// Threshold pressures.
|
||||
std::map<std::pair<int, int>, double> maxDp;
|
||||
computeMaxDp(maxDp, *deck_, *Base::eclipse_state_, grid_init_->grid(), *state_, props, gravity_[2]);
|
||||
threshold_pressures_ = thresholdPressures(*deck_, *Base::eclipse_state_, grid, maxDp);
|
||||
std::vector<double> threshold_pressures_nnc = thresholdPressuresNNC(*Base::eclipse_state_, Base::eclipse_state_->getInputNNC(), maxDp);
|
||||
threshold_pressures_.insert(threshold_pressures_.end(), threshold_pressures_nnc.begin(), threshold_pressures_nnc.end());
|
||||
|
||||
// The capillary pressure is scaled in fluidprops_ to match the scaled capillary pressure in props.
|
||||
if (deck_->hasKeyword("SWATINIT")) {
|
||||
const int numCells = Opm::UgGridHelpers::numCells(grid);
|
||||
std::vector<int> cells(numCells);
|
||||
for (int c = 0; c < numCells; ++c) { cells[c] = c; }
|
||||
std::vector<double> pc = state_->saturation();
|
||||
props.capPress(numCells, state_->saturation().data(), cells.data(), pc.data(), nullptr);
|
||||
fluidprops_->setSwatInitScaling(state_->saturation(), pc);
|
||||
}
|
||||
initHydroCarbonState(*state_, pu, Opm::UgGridHelpers::numCells(grid), deck_->hasKeyword("DISGAS"), deck_->hasKeyword("VAPOIL"));
|
||||
}
|
||||
|
||||
// Setup linear solver.
|
||||
@ -123,7 +266,7 @@ namespace Opm
|
||||
Base::param_,
|
||||
*Base::geoprops_,
|
||||
*Base::fluidprops_,
|
||||
Base::rock_comp_->isActive() ? Base::rock_comp_.get() : nullptr,
|
||||
/*rockComp=*/nullptr,
|
||||
*Base::fis_solver_,
|
||||
Base::gravity_.data(),
|
||||
Base::deck_->hasKeyword("DISGAS"),
|
||||
|
@ -73,18 +73,42 @@ namespace Opm
|
||||
class GridInit<Dune::CpGrid>
|
||||
{
|
||||
public:
|
||||
GridInit()
|
||||
{
|
||||
gridSelfManaged_ = false;
|
||||
}
|
||||
|
||||
/// Initialize from a deck and/or an eclipse state and (logical cartesian) specified pore volumes.
|
||||
GridInit(const EclipseState& eclipse_state, const std::vector<double>& porv)
|
||||
{
|
||||
grid_.processEclipseFormat(eclipse_state.getInputGrid(), false, false, false, porv);
|
||||
gridSelfManaged_ = true;
|
||||
|
||||
grid_ = new Dune::CpGrid;
|
||||
grid_->processEclipseFormat(eclipse_state.getInputGrid(), false, false, false, porv);
|
||||
}
|
||||
|
||||
~GridInit()
|
||||
{
|
||||
if (gridSelfManaged_)
|
||||
delete grid_;
|
||||
}
|
||||
|
||||
/// Access the created grid. Note that mutable access may be required for load balancing.
|
||||
Dune::CpGrid& grid()
|
||||
{
|
||||
return grid_;
|
||||
return *grid_;
|
||||
}
|
||||
|
||||
/// set the grid from the outside
|
||||
void setGrid(Dune::CpGrid& newGrid)
|
||||
{
|
||||
gridSelfManaged_ = false;
|
||||
grid_ = &newGrid;
|
||||
}
|
||||
|
||||
private:
|
||||
Dune::CpGrid grid_;
|
||||
Dune::CpGrid* grid_;
|
||||
bool gridSelfManaged_;
|
||||
};
|
||||
#endif // HAVE_OPM_GRID
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user