fully implicit simulators: various cleanups

these are mostly stylistic: the function bodies of most new methods
have been moved to the _impl.hpp file and the Simulator classes are
now templated on the grid type, so it should be not too hard to switch
them to Dune::CpGrid.
This commit is contained in:
Andreas Lauser
2015-05-28 13:15:42 +02:00
parent 01555da823
commit 2b085e0062
8 changed files with 154 additions and 117 deletions

View File

@@ -268,7 +268,8 @@ try
std::vector<double> threshold_pressures = thresholdPressures(eclipseState, *grid->c_grid());
SimulatorFullyImplicitBlackoilPolymer simulator(param,
SimulatorFullyImplicitBlackoilPolymer<UnstructuredGrid>
simulator(param,
*grid->c_grid(),
geology,
*new_props,

View File

@@ -224,7 +224,7 @@ try
SimulatorReport fullReport;
// Create and run simulator.
Opm::DerivedGeology geology(*grid->c_grid(), *new_props, eclipseState, grav);
SimulatorFullyImplicitCompressiblePolymer
SimulatorFullyImplicitCompressiblePolymer<UnstructuredGrid>
simulator(param,
*grid->c_grid(),
geology,

View File

@@ -255,9 +255,15 @@ namespace {
return it;
}
int FullyImplicitCompressiblePolymerSolver::newtonIterations() const
{
return newtonIterations_;
}
int FullyImplicitCompressiblePolymerSolver::linearIterations() const
{
return linearIterations_;
}
FullyImplicitCompressiblePolymerSolver::ReservoirResidualQuant::ReservoirResidualQuant()
: accum(2, ADB::null())

View File

@@ -85,10 +85,8 @@ namespace Opm {
PolymerBlackoilState& state ,
WellStateFullyImplicitBlackoilPolymer& wstate);
int newtonIterations() const
{ return newtonIterations_; }
int linearIterations() const
{ return linearIterations_; }
int newtonIterations() const;
int linearIterations() const;
private:
typedef AutoDiffBlock<double> ADB;

View File

@@ -78,32 +78,35 @@
namespace Opm
{
template <class GridT>
class SimulatorFullyImplicitBlackoilPolymer;
template<>
struct SimulatorTraits<SimulatorFullyImplicitBlackoilPolymer>
template<class GridT>
struct SimulatorTraits<SimulatorFullyImplicitBlackoilPolymer<GridT> >
{
typedef WellStateFullyImplicitBlackoilPolymer WellState;
typedef PolymerBlackoilState ReservoirState;
typedef BlackoilOutputWriter OutputWriter;
typedef UnstructuredGrid Grid;
typedef GridT Grid;
typedef BlackoilPolymerModel<Grid> Model;
typedef NewtonSolver<Model> Solver;
};
/// Class collecting all necessary components for a blackoil simulation with polymer
/// injection.
template <class GridT>
class SimulatorFullyImplicitBlackoilPolymer
: public SimulatorBase<SimulatorFullyImplicitBlackoilPolymer >
: public SimulatorBase<SimulatorFullyImplicitBlackoilPolymer<GridT> >
{
typedef SimulatorFullyImplicitBlackoilPolymer ThisType;
typedef SimulatorFullyImplicitBlackoilPolymer<GridT> ThisType;
typedef SimulatorBase<ThisType> BaseType;
typedef SimulatorTraits<ThisType> Traits;
typedef typename Traits::Solver Solver;
public:
SimulatorFullyImplicitBlackoilPolymer(const parameter::ParameterGroup& param,
const typename BaseType::Grid& grid,
const GridT& grid,
const DerivedGeology& geo,
BlackoilPropsAdInterface& props,
const PolymerPropsAd& polymer_props,
@@ -118,58 +121,12 @@ namespace Opm
Opm::DeckConstPtr& deck,
const std::vector<double>& threshold_pressures_by_face);
std::shared_ptr<Solver> createSolver(const Wells* wells)
{
typedef typename Traits::Model Model;
typedef typename Model::ModelParameters ModelParams;
ModelParams modelParams( param_ );
typedef NewtonSolver<Model> Solver;
auto model = std::make_shared<Model>(modelParams,
BaseType::grid_,
BaseType::props_,
BaseType::geo_,
BaseType::rock_comp_props_,
polymer_props_,
wells,
BaseType::solver_,
BaseType::has_disgas_,
BaseType::has_vapoil_,
has_polymer_,
BaseType::terminal_output_);
if (!threshold_pressures_by_face_.empty()) {
model->setThresholdPressures(threshold_pressures_by_face_);
}
typedef typename Solver::SolverParameters SolverParams;
SolverParams solverParams( param_ );
return std::make_shared<Solver>(solverParams, model);
}
std::shared_ptr<Solver> createSolver(const Wells* wells);
void handleAdditionalWellInflow(SimulatorTimer& timer,
WellsManager& wells_manager,
typename BaseType::WellState& well_state,
const Wells* wells)
{
// compute polymer inflow
std::unique_ptr<PolymerInflowInterface> polymer_inflow_ptr;
if (deck_->hasKeyword("WPOLYMER")) {
if (wells_manager.c_wells() == 0) {
OPM_THROW(std::runtime_error, "Cannot control polymer injection via WPOLYMER without wells.");
}
polymer_inflow_ptr.reset(new PolymerInflowFromDeck(deck_, BaseType::eclipse_state_, *wells, Opm::UgGridHelpers::numCells(BaseType::grid_), timer.currentStepNum()));
} else {
polymer_inflow_ptr.reset(new PolymerInflowBasic(0.0*Opm::unit::day,
1.0*Opm::unit::day,
0.0));
}
std::vector<double> polymer_inflow_c(Opm::UgGridHelpers::numCells(BaseType::grid_));
polymer_inflow_ptr->getInflowValues(timer.simulationTimeElapsed(),
timer.simulationTimeElapsed() + timer.currentStepLength(),
polymer_inflow_c);
well_state.polymerInflow() = polymer_inflow_c;
}
const Wells* wells);
private:
const PolymerPropsAd& polymer_props_;

View File

@@ -21,9 +21,10 @@
namespace Opm
{
SimulatorFullyImplicitBlackoilPolymer::
template <class GridT>
SimulatorFullyImplicitBlackoilPolymer<GridT>::
SimulatorFullyImplicitBlackoilPolymer(const parameter::ParameterGroup& param,
const Grid& grid,
const GridT& grid,
const DerivedGeology& geo,
BlackoilPropsAdInterface& props,
const PolymerPropsAd& polymer_props,
@@ -54,4 +55,63 @@ namespace Opm
, deck_(deck)
{
}
template <class GridT>
auto SimulatorFullyImplicitBlackoilPolymer<GridT>::
createSolver(const Wells* wells)
-> std::shared_ptr<Solver>
{
typedef typename Traits::Model Model;
typedef typename Model::ModelParameters ModelParams;
ModelParams modelParams( BaseType::param_ );
typedef NewtonSolver<Model> Solver;
auto model = std::make_shared<Model>(modelParams,
BaseType::grid_,
BaseType::props_,
BaseType::geo_,
BaseType::rock_comp_props_,
polymer_props_,
wells,
BaseType::solver_,
BaseType::has_disgas_,
BaseType::has_vapoil_,
has_polymer_,
BaseType::terminal_output_);
if (!BaseType::threshold_pressures_by_face_.empty()) {
model->setThresholdPressures(BaseType::threshold_pressures_by_face_);
}
typedef typename Solver::SolverParameters SolverParams;
SolverParams solverParams( BaseType::param_ );
return std::make_shared<Solver>(solverParams, model);
}
template <class GridT>
void SimulatorFullyImplicitBlackoilPolymer<GridT>::
handleAdditionalWellInflow(SimulatorTimer& timer,
WellsManager& wells_manager,
typename BaseType::WellState& well_state,
const Wells* wells)
{
// compute polymer inflow
std::unique_ptr<PolymerInflowInterface> polymer_inflow_ptr;
if (deck_->hasKeyword("WPOLYMER")) {
if (wells_manager.c_wells() == 0) {
OPM_THROW(std::runtime_error, "Cannot control polymer injection via WPOLYMER without wells.");
}
polymer_inflow_ptr.reset(new PolymerInflowFromDeck(deck_, BaseType::eclipse_state_, *wells, Opm::UgGridHelpers::numCells(BaseType::grid_), timer.currentStepNum()));
} else {
polymer_inflow_ptr.reset(new PolymerInflowBasic(0.0*Opm::unit::day,
1.0*Opm::unit::day,
0.0));
}
std::vector<double> polymer_inflow_c(Opm::UgGridHelpers::numCells(BaseType::grid_));
polymer_inflow_ptr->getInflowValues(timer.simulationTimeElapsed(),
timer.simulationTimeElapsed() + timer.currentStepLength(),
polymer_inflow_c);
well_state.polymerInflow() = polymer_inflow_c;
}
} // namespace Opm

View File

@@ -68,29 +68,32 @@
namespace Opm
{
template <class GridT>
class SimulatorFullyImplicitCompressiblePolymer;
template <>
struct SimulatorTraits<SimulatorFullyImplicitCompressiblePolymer>
template <class GridT>
struct SimulatorTraits<SimulatorFullyImplicitCompressiblePolymer<GridT> >
{
typedef PolymerBlackoilState ReservoirState;
typedef WellStateFullyImplicitBlackoilPolymer WellState;
typedef BlackoilOutputWriter OutputWriter;
typedef UnstructuredGrid Grid;
typedef GridT Grid;
typedef FullyImplicitCompressiblePolymerSolver Solver;
};
/// Class collecting all necessary components for a two-phase simulation.
template <class GridT>
class SimulatorFullyImplicitCompressiblePolymer
: public SimulatorBase<SimulatorFullyImplicitCompressiblePolymer>
: public SimulatorBase<SimulatorFullyImplicitCompressiblePolymer<GridT> >
{
typedef SimulatorFullyImplicitCompressiblePolymer ThisType;
typedef SimulatorBase<ThisType> BaseType;
typedef typename BaseType::Solver Solver;
public:
/// Initialise from parameters and objects to observe.
SimulatorFullyImplicitCompressiblePolymer(const parameter::ParameterGroup& param,
const UnstructuredGrid& grid,
const GridT& grid,
const DerivedGeology& geo,
BlackoilPropsAdInterface& props,
const PolymerPropsAd& polymer_props,
@@ -101,42 +104,12 @@ namespace Opm
NewtonIterationBlackoilInterface& linsolver,
const double* gravity);
std::shared_ptr<Solver> createSolver(const Wells* wells)
{
return std::make_shared<Solver>(BaseType::grid_,
BaseType::props_,
BaseType::geo_,
BaseType::rock_comp_props_,
polymer_props_,
*wells,
BaseType::solver_);
}
std::shared_ptr<Solver> createSolver(const Wells* wells);
void handleAdditionalWellInflow(SimulatorTimer& timer,
WellsManager& wells_manager,
typename BaseType::WellState& well_state,
const Wells* wells)
{
// compute polymer inflow
std::unique_ptr<PolymerInflowInterface> polymer_inflow_ptr;
if (deck_->hasKeyword("WPOLYMER")) {
if (wells_manager.c_wells() == 0) {
OPM_THROW(std::runtime_error, "Cannot control polymer injection via WPOLYMER without wells.");
}
polymer_inflow_ptr.reset(new PolymerInflowFromDeck(deck_, BaseType::eclipse_state_, *wells, Opm::UgGridHelpers::numCells(BaseType::grid_), timer.currentStepNum()));
} else {
polymer_inflow_ptr.reset(new PolymerInflowBasic(0.0*Opm::unit::day,
1.0*Opm::unit::day,
0.0));
}
std::vector<double> polymer_inflow_c(Opm::UgGridHelpers::numCells(BaseType::grid_));
polymer_inflow_ptr->getInflowValues(timer.simulationTimeElapsed(),
timer.simulationTimeElapsed() + timer.currentStepLength(),
polymer_inflow_c);
well_state.polymerInflow() = polymer_inflow_c;
}
const Wells* wells);
private:
Opm::DeckConstPtr deck_;
const PolymerPropsAd& polymer_props_;

View File

@@ -24,9 +24,10 @@ namespace Opm
{
/// Class collecting all necessary components for a two-phase simulation.
SimulatorFullyImplicitCompressiblePolymer::
template <class GridT>
SimulatorFullyImplicitCompressiblePolymer<GridT>::
SimulatorFullyImplicitCompressiblePolymer(const parameter::ParameterGroup& param,
const UnstructuredGrid& grid,
const GridT& grid,
const DerivedGeology& geo,
BlackoilPropsAdInterface& props,
const PolymerPropsAd& polymer_props,
@@ -54,6 +55,47 @@ SimulatorFullyImplicitCompressiblePolymer(const parameter::ParameterGroup& param
{
}
template <class GridT>
auto SimulatorFullyImplicitCompressiblePolymer<GridT>::
createSolver(const Wells* wells)
-> std::shared_ptr<Solver>
{
return std::make_shared<Solver>(BaseType::grid_,
BaseType::props_,
BaseType::geo_,
BaseType::rock_comp_props_,
polymer_props_,
*wells,
BaseType::solver_);
}
template <class GridT>
void SimulatorFullyImplicitCompressiblePolymer<GridT>::
handleAdditionalWellInflow(SimulatorTimer& timer,
WellsManager& wells_manager,
typename BaseType::WellState& well_state,
const Wells* wells)
{
// compute polymer inflow
std::unique_ptr<PolymerInflowInterface> polymer_inflow_ptr;
if (deck_->hasKeyword("WPOLYMER")) {
if (wells_manager.c_wells() == 0) {
OPM_THROW(std::runtime_error, "Cannot control polymer injection via WPOLYMER without wells.");
}
polymer_inflow_ptr.reset(new PolymerInflowFromDeck(deck_, BaseType::eclipse_state_, *wells, Opm::UgGridHelpers::numCells(BaseType::grid_), timer.currentStepNum()));
} else {
polymer_inflow_ptr.reset(new PolymerInflowBasic(0.0*Opm::unit::day,
1.0*Opm::unit::day,
0.0));
}
std::vector<double> polymer_inflow_c(Opm::UgGridHelpers::numCells(BaseType::grid_));
polymer_inflow_ptr->getInflowValues(timer.simulationTimeElapsed(),
timer.simulationTimeElapsed() + timer.currentStepLength(),
polymer_inflow_c);
well_state.polymerInflow() = polymer_inflow_c;
}
} // namespace Opm
#endif // OPM_SIMULATORFULLYIMPLICITCOMPRESSIBLEPOLYMER_HEADER_INCLUDED