22 #ifndef OPM_SIMULATORFULLYIMPLICITBLACKOILEBOS_HEADER_INCLUDED
23 #define OPM_SIMULATORFULLYIMPLICITBLACKOILEBOS_HEADER_INCLUDED
25 #include <opm/simulators/flow/NonlinearSolverEbos.hpp>
26 #include <opm/simulators/flow/BlackoilModelEbos.hpp>
27 #include <opm/simulators/flow/BlackoilModelParametersEbos.hpp>
28 #include <opm/simulators/wells/WellState.hpp>
29 #include <opm/simulators/aquifers/BlackoilAquiferModel.hpp>
30 #include <opm/simulators/utils/moduleVersion.hpp>
31 #include <opm/simulators/timestepping/AdaptiveTimeSteppingEbos.hpp>
32 #include <opm/grid/utility/StopWatch.hpp>
34 #include <opm/common/ErrorMacros.hpp>
36 namespace Opm::Properties {
38 template<
class TypeTag,
class MyTypeTag>
40 using type = UndefinedProperty;
42 template<
class TypeTag,
class MyTypeTag>
44 using type = UndefinedProperty;
47 template<
class TypeTag>
49 static constexpr
bool value =
true;
51 template<
class TypeTag>
53 static constexpr
bool value =
true;
55 template<
class TypeTag>
57 static constexpr
bool value =
false;
66 const std::string& title,
67 const std::string& version);
70 template<
class TypeTag>
74 using Simulator = GetPropType<TypeTag, Properties::Simulator>;
75 using Grid = GetPropType<TypeTag, Properties::Grid>;
76 using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>;
77 using ElementContext = GetPropType<TypeTag, Properties::ElementContext>;
78 using BlackoilIndices = GetPropType<TypeTag, Properties::Indices>;
79 using PrimaryVariables = GetPropType<TypeTag, Properties::PrimaryVariables>;
80 using MaterialLaw = GetPropType<TypeTag, Properties::MaterialLaw>;
81 using SolutionVector = GetPropType<TypeTag, Properties::SolutionVector>;
82 using MaterialLawParams = GetPropType<TypeTag, Properties::MaterialLawParams>;
85 typedef BlackOilPolymerModule<TypeTag> PolymerModule;
86 typedef BlackOilMICPModule<TypeTag> MICPModule;
118 : ebosSimulator_(ebosSimulator)
123 const auto& comm = grid().comm();
124 terminalOutput_ = EWOMS_GET_PARAM(TypeTag,
bool, EnableTerminalOutput);
125 terminalOutput_ = terminalOutput_ && (comm.rank() == 0);
128 static void registerParameters()
130 ModelParameters::registerParameters();
131 SolverParameters::registerParameters();
132 TimeStepper::registerParameters();
134 EWOMS_REGISTER_PARAM(TypeTag,
bool, EnableTerminalOutput,
135 "Print high-level information about the simulation's progress to the terminal");
136 EWOMS_REGISTER_PARAM(TypeTag,
bool, EnableAdaptiveTimeStepping,
137 "Use adaptive time stepping between report steps");
138 EWOMS_REGISTER_PARAM(TypeTag,
bool, EnableTuning,
139 "Honor some aspects of the TUNING keyword.");
152 while (!timer.
done()) {
153 bool continue_looping = runStep(timer);
154 if (!continue_looping)
break;
161 ebosSimulator_.setEpisodeIndex(-1);
164 solverTimer_ = std::make_unique<time::StopWatch>();
165 totalTimer_ = std::make_unique<time::StopWatch>();
166 totalTimer_->start();
169 bool enableAdaptive = EWOMS_GET_PARAM(TypeTag,
bool, EnableAdaptiveTimeStepping);
170 bool enableTUNING = EWOMS_GET_PARAM(TypeTag,
bool, EnableTuning);
171 if (enableAdaptive) {
172 const UnitSystem& unitSystem = this->ebosSimulator_.vanguard().eclState().getUnits();
175 auto max_next_tstep = sched_state.max_next_tstep();
176 adaptiveTimeStepping_ = std::make_unique<TimeStepper>(max_next_tstep,
177 sched_state.tuning(),
178 unitSystem, terminalOutput_);
181 adaptiveTimeStepping_ = std::make_unique<TimeStepper>(unitSystem, terminalOutput_);
187 adaptiveTimeStepping_->setSuggestedNextStep(ebosSimulator_.timeStepSize());
192 bool runStep(SimulatorTimer& timer)
194 if (schedule().exitStatus().has_value()) {
195 if (terminalOutput_) {
196 OpmLog::info(
"Stopping simulation since EXIT was triggered by an action keyword.");
198 report_.success.exit_status = schedule().exitStatus().value();
203 if (terminalOutput_) {
204 std::ostringstream ss;
206 OpmLog::debug(ss.str());
209 if (terminalOutput_) {
210 outputReportStep(timer);
214 if (timer.initialStep()) {
215 Dune::Timer perfTimer;
218 ebosSimulator_.setEpisodeIndex(-1);
219 ebosSimulator_.setEpisodeLength(0.0);
220 ebosSimulator_.setTimeStepSize(0.0);
222 wellModel_().beginReportStep(timer.currentStepNum());
223 ebosSimulator_.problem().writeOutput();
225 report_.success.output_write_time += perfTimer.stop();
229 solverTimer_->start();
231 auto solver = createSolver(wellModel_());
233 ebosSimulator_.startNextEpisode(
234 ebosSimulator_.startTime()
235 + schedule().seconds(timer.currentStepNum()),
236 timer.currentStepLength());
237 ebosSimulator_.setEpisodeIndex(timer.currentStepNum());
238 solver->model().beginReportStep();
239 bool enableTUNING = EWOMS_GET_PARAM(TypeTag,
bool, EnableTuning);
246 if (adaptiveTimeStepping_) {
247 const auto& events = schedule()[timer.currentStepNum()].events();
249 if (events.hasEvent(ScheduleEvents::TUNING_CHANGE)) {
250 const auto& sched_state = schedule()[timer.currentStepNum()];
251 const auto& tuning = sched_state.tuning();
252 const auto& max_next_tstep = sched_state.max_next_tstep();
253 adaptiveTimeStepping_->updateTUNING(max_next_tstep, tuning);
256 bool event = events.hasEvent(ScheduleEvents::NEW_WELL) ||
257 events.hasEvent(ScheduleEvents::INJECTION_TYPE_CHANGED) ||
258 events.hasEvent(ScheduleEvents::WELL_SWITCHED_INJECTOR_PRODUCER) ||
259 events.hasEvent(ScheduleEvents::WELL_STATUS_CHANGE);
260 auto stepReport = adaptiveTimeStepping_->step(timer, *solver, event,
nullptr);
261 report_ += stepReport;
263 ebosSimulator_.problem().setSimulationReport(report_);
266 auto stepReport = solver->step(timer);
267 report_ += stepReport;
268 if (terminalOutput_) {
269 std::ostringstream ss;
270 stepReport.reportStep(ss);
271 OpmLog::info(ss.str());
276 Dune::Timer perfTimer;
278 const double nextstep = adaptiveTimeStepping_ ? adaptiveTimeStepping_->suggestedNextStep() : -1.0;
279 ebosSimulator_.problem().setNextTimeStepSize(nextstep);
280 ebosSimulator_.problem().writeOutput();
281 report_.success.output_write_time += perfTimer.stop();
283 solver->model().endReportStep();
286 solverTimer_->stop();
289 report_.success.solver_time += solverTimer_->secsSinceStart();
294 if (terminalOutput_) {
295 if (!timer.initialStep()) {
297 outputTimestampFIP(timer, eclState().getTitle(), version);
301 if (terminalOutput_) {
303 "Time step took " + std::to_string(solverTimer_->secsSinceStart()) +
" seconds; "
304 "total solver time " + std::to_string(report_.success.solver_time) +
" seconds.";
310 SimulatorReport finalize()
314 Dune::Timer finalOutputTimer;
315 finalOutputTimer.start();
317 ebosSimulator_.problem().finalizeOutput();
318 report_.success.output_write_time += finalOutputTimer.stop();
323 report_.success.total_time = totalTimer_->secsSinceStart();
324 report_.success.converged =
true;
329 const Grid& grid()
const
330 {
return ebosSimulator_.vanguard().grid(); }
334 std::unique_ptr<Solver> createSolver(WellModel& wellModel)
336 auto model = std::make_unique<Model>(ebosSimulator_,
341 return std::make_unique<Solver>(solverParam_, std::move(model));
344 const EclipseState& eclState()
const
345 {
return ebosSimulator_.vanguard().eclState(); }
348 const Schedule& schedule()
const
349 {
return ebosSimulator_.vanguard().schedule(); }
351 bool isRestart()
const
353 const auto& initconfig = eclState().getInitConfig();
354 return initconfig.restartRequested();
357 WellModel& wellModel_()
358 {
return ebosSimulator_.problem().wellModel(); }
360 const WellModel& wellModel_()
const
361 {
return ebosSimulator_.problem().wellModel(); }
364 Simulator& ebosSimulator_;
365 std::unique_ptr<WellConnectionAuxiliaryModule<TypeTag>> wellAuxMod_;
367 ModelParameters modelParam_;
368 SolverParameters solverParam_;
371 PhaseUsage phaseUsage_;
373 bool terminalOutput_;
375 SimulatorReport report_;
376 std::unique_ptr<time::StopWatch> solverTimer_;
377 std::unique_ptr<time::StopWatch> totalTimer_;
378 std::unique_ptr<TimeStepper> adaptiveTimeStepping_;
Definition: AdaptiveTimeSteppingEbos.hpp:238
Class for handling the blackoil well model.
Definition: BlackoilAquiferModel.hpp:81
A model implementation for three-phase black oil.
Definition: BlackoilModelEbos.hpp:158
Class for handling the blackoil well model.
Definition: BlackoilWellModel.hpp:94
A nonlinear solver class suitable for general fully-implicit models, as well as pressure,...
Definition: NonlinearSolverEbos.hpp:89
a simulator for the blackoil model
Definition: SimulatorFullyImplicitBlackoilEbos.hpp:72
SimulatorReport run(SimulatorTimer &timer)
Run the simulation.
Definition: SimulatorFullyImplicitBlackoilEbos.hpp:148
SimulatorFullyImplicitBlackoilEbos(Simulator &ebosSimulator)
Initialise from parameters and objects to observe.
Definition: SimulatorFullyImplicitBlackoilEbos.hpp:117
Definition: SimulatorTimer.hpp:37
int currentStepNum() const override
Current step number.
Definition: SimulatorTimer.cpp:80
bool done() const override
Return true if op++() has been called numSteps() times.
Definition: SimulatorTimer.cpp:153
This file contains a set of helper functions used by VFPProd / VFPInj.
Definition: BlackoilPhases.hpp:27
std::string moduleVersionName()
Return the version name of the module, for example "2015.10" (for a release branch) or "2016....
Definition: moduleVersion.cpp:29
PhaseUsage phaseUsageFromDeck(const EclipseState &eclipseState)
Looks at presence of WATER, OIL and GAS keywords in state object to determine active phases.
Definition: phaseUsageFromDeck.cpp:141
Solver parameters for the BlackoilModel.
Definition: BlackoilModelParametersEbos.hpp:327
Definition: NonlinearSolverEbos.hpp:101
Definition: SimulatorFullyImplicitBlackoilEbos.hpp:39
Definition: BlackoilWellModel.hpp:82
Definition: SimulatorFullyImplicitBlackoilEbos.hpp:43
Definition: SimulatorReport.hpp:69