diff --git a/examples/flow_sequential.cpp b/examples/flow_sequential.cpp index 0d4a89847..5eef64dad 100644 --- a/examples/flow_sequential.cpp +++ b/examples/flow_sequential.cpp @@ -25,6 +25,9 @@ #include #include #include +#include +#include +#include // ----------------- Main program ----------------- @@ -32,7 +35,8 @@ int main(int argc, char** argv) { typedef UnstructuredGrid Grid; - typedef Opm::SimulatorSequentialBlackoil Simulator; + typedef Opm::StandardWells WellModel; + typedef Opm::SimulatorSequentialBlackoil Simulator; Opm::FlowMainSequential mainfunc; return mainfunc.execute(argc, argv); diff --git a/opm/autodiff/BlackoilSequentialModel.hpp b/opm/autodiff/BlackoilSequentialModel.hpp index 895b38196..4547a7a3e 100644 --- a/opm/autodiff/BlackoilSequentialModel.hpp +++ b/opm/autodiff/BlackoilSequentialModel.hpp @@ -23,8 +23,6 @@ #include -#include -#include #include #include #include @@ -44,7 +42,9 @@ namespace Opm { /// A sequential splitting model implementation for three-phase black oil. - template + template class PressureModelT, + template class TransportModelT> class BlackoilSequentialModel { public: @@ -53,8 +53,11 @@ namespace Opm { typedef BlackoilSequentialModelParameters ModelParameters; typedef DefaultBlackoilSolutionState SolutionState; - typedef BlackoilPressureModel PressureModel; - typedef BlackoilTransportModel TransportModel; + typedef PressureModelT PressureModel; + typedef TransportModelT TransportModel; + typedef NonlinearSolver PressureSolver; + typedef NonlinearSolver TransportSolver; + typedef typename TransportModel::SimulatorData SimulatorData; typedef typename TransportModel::FIPDataType FIPDataType; @@ -88,11 +91,18 @@ namespace Opm { linsolver, eclState, has_disgas, has_vapoil, terminal_output)), transport_model_(new TransportModel(param, grid, fluid, geo, rock_comp_props, well_model, linsolver, eclState, has_disgas, has_vapoil, terminal_output)), + // TODO: fix solver parameters for pressure and transport solver. pressure_solver_(typename PressureSolver::SolverParameters(), std::move(pressure_model_)), transport_solver_(typename TransportSolver::SolverParameters(), std::move(transport_model_)), initial_reservoir_state_(0, 0, 0), // will be overwritten iterate_to_fully_implicit_(param.iterate_to_fully_implicit) { + typename PressureSolver::SolverParameters pp; + pp.min_iter_ = 0; + pressure_solver_.setParameters(pp); + typename TransportSolver::SolverParameters tp; + tp.min_iter_ = 0; + transport_solver_.setParameters(tp); } @@ -174,7 +184,8 @@ namespace Opm { if (terminalOutputEnabled()) { OpmLog::info("Solving the pressure equation."); } - const SimulatorReport& pressure_report = pressure_solver_.step(timer, initial_reservoir_state_, initial_well_state_, reservoir_state, well_state); + + const SimulatorReport pressure_report = pressure_solver_.step(timer, initial_reservoir_state_, initial_well_state_, reservoir_state, well_state); const int pressure_liniter = pressure_report.total_linear_iterations; if (pressure_liniter == -1) { OPM_THROW(std::runtime_error, "Pressure solver failed to converge."); @@ -184,14 +195,26 @@ namespace Opm { if (terminalOutputEnabled()) { OpmLog::info("Solving the transport equations."); } - const SimulatorReport& transport_report = transport_solver_.step(timer, initial_reservoir_state_, initial_well_state_, reservoir_state, well_state); + const SimulatorReport transport_report = transport_solver_.step(timer, initial_reservoir_state_, initial_well_state_, reservoir_state, well_state); const int transport_liniter = transport_report.total_linear_iterations; if (transport_liniter == -1) { OPM_THROW(std::runtime_error, "Transport solver failed to converge."); } + // Revisit pressure equation to check if it is still converged. + bool done = false; + { + auto rstate = reservoir_state; + auto wstate = well_state; + pressure_solver_.model().prepareStep(timer, initial_reservoir_state_, initial_well_state_); + SimulatorReport rep = pressure_solver_.model().nonlinearIteration(0, timer, pressure_solver_, rstate, wstate); + if (rep.converged && rep.total_newton_iterations == 0) { + done = true; + } + } + SimulatorReport report; - report.converged = iteration >= 3; // TODO: replace this with a proper convergence check + report.converged = done; report.total_linear_iterations = pressure_liniter + transport_liniter; return report; } @@ -290,9 +313,6 @@ namespace Opm { { return failureReport_; } protected: - typedef NonlinearSolver PressureSolver; - typedef NonlinearSolver TransportSolver; - SimulatorReport failureReport_; std::unique_ptr pressure_model_; diff --git a/opm/autodiff/NonlinearSolver.hpp b/opm/autodiff/NonlinearSolver.hpp index ff8a5f7e2..632cbd02e 100644 --- a/opm/autodiff/NonlinearSolver.hpp +++ b/opm/autodiff/NonlinearSolver.hpp @@ -169,10 +169,13 @@ namespace Opm { double relaxRelTol() const { return param_.relax_rel_tol_; } /// The maximum number of nonlinear iterations allowed. - int maxIter() const { return param_.max_iter_; } + int maxIter() const { return param_.max_iter_; } /// The minimum number of nonlinear iterations allowed. - double minIter() const { return param_.min_iter_; } + int minIter() const { return param_.min_iter_; } + + /// Set parameters to override those given at construction time. + void setParameters(const SolverParameters& param) { param_ = param; } private: // --------- Data members --------- diff --git a/opm/autodiff/SimulatorSequentialBlackoil.hpp b/opm/autodiff/SimulatorSequentialBlackoil.hpp index 249d8b703..aed5c8383 100644 --- a/opm/autodiff/SimulatorSequentialBlackoil.hpp +++ b/opm/autodiff/SimulatorSequentialBlackoil.hpp @@ -24,32 +24,36 @@ #include #include #include -#include namespace Opm { -template +template class PressureModel, + template class TransportModel> class SimulatorSequentialBlackoil; -class StandardWells; -template -struct SimulatorTraits > +template class PressureModel, + template class TransportModel> +struct SimulatorTraits > { typedef WellStateFullyImplicitBlackoil WellState; typedef BlackoilState ReservoirState; typedef BlackoilOutputWriter OutputWriter; typedef GridT Grid; - typedef BlackoilSequentialModel Model; + typedef BlackoilSequentialModel Model; typedef NonlinearSolver Solver; - typedef StandardWells WellModel; + typedef WellModelT WellModel; }; /// a simulator for the blackoil model -template +template class PressureModel, + template class TransportModel> class SimulatorSequentialBlackoil - : public SimulatorBase > + : public SimulatorBase > { - typedef SimulatorBase > Base; + typedef SimulatorBase > Base; public: // forward the constructor to the base class SimulatorSequentialBlackoil(const ParameterGroup& param,