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:
Andreas Lauser 2016-11-22 14:09:06 +01:00 committed by Robert Kloefkorn
parent 28c36ef949
commit 5ebed2f500
2 changed files with 177 additions and 10 deletions

View File

@ -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"),

View File

@ -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