diff --git a/examples/flow_polymer.cpp b/examples/flow_polymer.cpp index 58505a49b..70482c259 100644 --- a/examples/flow_polymer.cpp +++ b/examples/flow_polymer.cpp @@ -268,21 +268,22 @@ try std::vector threshold_pressures = thresholdPressures(eclipseState, *grid->c_grid()); - SimulatorFullyImplicitBlackoilPolymer simulator(param, - *grid->c_grid(), - geology, - *new_props, - polymer_props_ad, - rock_comp->isActive() ? rock_comp.get() : 0, - *fis_solver, - grav, - deck->hasKeyword("DISGAS"), - deck->hasKeyword("VAPOIL"), - polymer, - eclipseState, - outputWriter, - deck, - threshold_pressures); + SimulatorFullyImplicitBlackoilPolymer + simulator(param, + *grid->c_grid(), + geology, + *new_props, + polymer_props_ad, + rock_comp->isActive() ? rock_comp.get() : 0, + *fis_solver, + grav, + deck->hasKeyword("DISGAS"), + deck->hasKeyword("VAPOIL"), + polymer, + eclipseState, + outputWriter, + deck, + threshold_pressures); if (!schedule->initOnly()){ std::cout << "\n\n================ Starting main simulation loop ===============\n" diff --git a/examples/sim_poly_fi2p_comp_ad.cpp b/examples/sim_poly_fi2p_comp_ad.cpp index 57aa910d4..2208636bf 100644 --- a/examples/sim_poly_fi2p_comp_ad.cpp +++ b/examples/sim_poly_fi2p_comp_ad.cpp @@ -224,7 +224,7 @@ try SimulatorReport fullReport; // Create and run simulator. Opm::DerivedGeology geology(*grid->c_grid(), *new_props, eclipseState, grav); - SimulatorFullyImplicitCompressiblePolymer + SimulatorFullyImplicitCompressiblePolymer simulator(param, *grid->c_grid(), geology, diff --git a/opm/polymer/fullyimplicit/FullyImplicitCompressiblePolymerSolver.cpp b/opm/polymer/fullyimplicit/FullyImplicitCompressiblePolymerSolver.cpp index c9728d8c3..956ffdb26 100644 --- a/opm/polymer/fullyimplicit/FullyImplicitCompressiblePolymerSolver.cpp +++ b/opm/polymer/fullyimplicit/FullyImplicitCompressiblePolymerSolver.cpp @@ -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()) diff --git a/opm/polymer/fullyimplicit/FullyImplicitCompressiblePolymerSolver.hpp b/opm/polymer/fullyimplicit/FullyImplicitCompressiblePolymerSolver.hpp index 43e5f27a5..cf4a2693b 100644 --- a/opm/polymer/fullyimplicit/FullyImplicitCompressiblePolymerSolver.hpp +++ b/opm/polymer/fullyimplicit/FullyImplicitCompressiblePolymerSolver.hpp @@ -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 ADB; diff --git a/opm/polymer/fullyimplicit/SimulatorFullyImplicitBlackoilPolymer.hpp b/opm/polymer/fullyimplicit/SimulatorFullyImplicitBlackoilPolymer.hpp index ab78bcbb2..f213958de 100644 --- a/opm/polymer/fullyimplicit/SimulatorFullyImplicitBlackoilPolymer.hpp +++ b/opm/polymer/fullyimplicit/SimulatorFullyImplicitBlackoilPolymer.hpp @@ -78,32 +78,35 @@ namespace Opm { + template class SimulatorFullyImplicitBlackoilPolymer; - template<> - struct SimulatorTraits + template + struct SimulatorTraits > { typedef WellStateFullyImplicitBlackoilPolymer WellState; typedef PolymerBlackoilState ReservoirState; typedef BlackoilOutputWriter OutputWriter; - typedef UnstructuredGrid Grid; + typedef GridT Grid; typedef BlackoilPolymerModel Model; typedef NewtonSolver Solver; }; /// Class collecting all necessary components for a blackoil simulation with polymer /// injection. + template class SimulatorFullyImplicitBlackoilPolymer - : public SimulatorBase + : public SimulatorBase > { - typedef SimulatorFullyImplicitBlackoilPolymer ThisType; + typedef SimulatorFullyImplicitBlackoilPolymer ThisType; typedef SimulatorBase BaseType; typedef SimulatorTraits 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& threshold_pressures_by_face); - std::shared_ptr createSolver(const Wells* wells) - { - typedef typename Traits::Model Model; - typedef typename Model::ModelParameters ModelParams; - ModelParams modelParams( param_ ); - typedef NewtonSolver Solver; - - auto model = std::make_shared(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(solverParams, model); - } + std::shared_ptr 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 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 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_; diff --git a/opm/polymer/fullyimplicit/SimulatorFullyImplicitBlackoilPolymer_impl.hpp b/opm/polymer/fullyimplicit/SimulatorFullyImplicitBlackoilPolymer_impl.hpp index 30b1d6a6e..3ca6a319d 100644 --- a/opm/polymer/fullyimplicit/SimulatorFullyImplicitBlackoilPolymer_impl.hpp +++ b/opm/polymer/fullyimplicit/SimulatorFullyImplicitBlackoilPolymer_impl.hpp @@ -21,9 +21,10 @@ namespace Opm { - SimulatorFullyImplicitBlackoilPolymer:: + template + SimulatorFullyImplicitBlackoilPolymer:: 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 + auto SimulatorFullyImplicitBlackoilPolymer:: + createSolver(const Wells* wells) + -> std::shared_ptr + { + typedef typename Traits::Model Model; + typedef typename Model::ModelParameters ModelParams; + ModelParams modelParams( BaseType::param_ ); + typedef NewtonSolver Solver; + + auto model = std::make_shared(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(solverParams, model); + } + + template + void SimulatorFullyImplicitBlackoilPolymer:: + handleAdditionalWellInflow(SimulatorTimer& timer, + WellsManager& wells_manager, + typename BaseType::WellState& well_state, + const Wells* wells) + { + // compute polymer inflow + std::unique_ptr 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 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 diff --git a/opm/polymer/fullyimplicit/SimulatorFullyImplicitCompressiblePolymer.hpp b/opm/polymer/fullyimplicit/SimulatorFullyImplicitCompressiblePolymer.hpp index 94a8db36c..d15cfa0c7 100644 --- a/opm/polymer/fullyimplicit/SimulatorFullyImplicitCompressiblePolymer.hpp +++ b/opm/polymer/fullyimplicit/SimulatorFullyImplicitCompressiblePolymer.hpp @@ -68,29 +68,32 @@ namespace Opm { + template class SimulatorFullyImplicitCompressiblePolymer; - template <> - struct SimulatorTraits + template + struct SimulatorTraits > { 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 SimulatorFullyImplicitCompressiblePolymer - : public SimulatorBase + : public SimulatorBase > { typedef SimulatorFullyImplicitCompressiblePolymer ThisType; typedef SimulatorBase 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 createSolver(const Wells* wells) - { - return std::make_shared(BaseType::grid_, - BaseType::props_, - BaseType::geo_, - BaseType::rock_comp_props_, - polymer_props_, - *wells, - BaseType::solver_); - } + std::shared_ptr 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 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 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_; diff --git a/opm/polymer/fullyimplicit/SimulatorFullyImplicitCompressiblePolymer_impl.hpp b/opm/polymer/fullyimplicit/SimulatorFullyImplicitCompressiblePolymer_impl.hpp index e8af9fce5..57d31b095 100644 --- a/opm/polymer/fullyimplicit/SimulatorFullyImplicitCompressiblePolymer_impl.hpp +++ b/opm/polymer/fullyimplicit/SimulatorFullyImplicitCompressiblePolymer_impl.hpp @@ -24,9 +24,10 @@ namespace Opm { /// Class collecting all necessary components for a two-phase simulation. -SimulatorFullyImplicitCompressiblePolymer:: +template +SimulatorFullyImplicitCompressiblePolymer:: 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 +auto SimulatorFullyImplicitCompressiblePolymer:: +createSolver(const Wells* wells) + -> std::shared_ptr +{ + return std::make_shared(BaseType::grid_, + BaseType::props_, + BaseType::geo_, + BaseType::rock_comp_props_, + polymer_props_, + *wells, + BaseType::solver_); +} + +template +void SimulatorFullyImplicitCompressiblePolymer:: +handleAdditionalWellInflow(SimulatorTimer& timer, + WellsManager& wells_manager, + typename BaseType::WellState& well_state, + const Wells* wells) +{ + // compute polymer inflow + std::unique_ptr 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 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