114 using ModelParameters =
typename Model::ModelParameters;
121 : simulator_(simulator)
125 Parameters::Get<Parameters::SaveStep>(),
126 Parameters::Get<Parameters::LoadStep>(),
127 Parameters::Get<Parameters::SaveFile>(),
128 Parameters::Get<Parameters::LoadFile>())
132 this->terminalOutput_ =
false;
133 if (this->grid().comm().rank() == 0) {
134 this->terminalOutput_ = Parameters::Get<Parameters::EnableTerminalOutput>();
137 [compNames =
typename Model::ComponentName{}](
const int compIdx)
138 {
return std::string_view { compNames.name(
compIdx) }; }
141 if (!simulator_.vanguard().eclState().getIOConfig().initOnly()) {
142 this->convergence_output_.
143 startThread(this->simulator_.vanguard().eclState(),
144 Parameters::Get<Parameters::OutputExtraConvergenceInfo>(),
145 R
"(OutputExtraConvergenceInfo (--output-extra-convergence-info))",
157 static void registerParameters()
159 ModelParameters::registerParameters();
160 SolverParameters::registerParameters();
161 TimeStepper::registerParameters();
162 detail::registerSimulatorParameters();
171#ifdef RESERVOIR_COUPLING_ENABLED
172 SimulatorReport
run(SimulatorTimer& timer,
int argc,
char**
argv)
183 simulator_.model().invalidateAndUpdateIntensiveQuantities(0);
185 while (!timer.
done()) {
186 simulator_.problem().writeReports(timer);
190 simulator_.problem().writeReports(timer);
194#ifdef RESERVOIR_COUPLING_ENABLED
201 for (std::size_t report_step = 0; report_step < this->schedule().size(); ++report_step) {
202 auto rescoup = this->schedule()[report_step].rescoup();
212 "Inconsistent reservoir coupling master schedule: "
213 "Slave count is greater than 0 but master group count is 0"
218 "Inconsistent reservoir coupling master schedule: "
219 "Master group count is greater than 0 but slave count is 0"
227#ifdef RESERVOIR_COUPLING_ENABLED
229 void init(
const SimulatorTimer& timer,
int argc,
char**
argv)
231 auto slave_mode = Parameters::Get<Parameters::Slave>();
234 std::make_unique<ReservoirCouplingSlave>(
236 this->schedule(), timer
246 std::make_unique<ReservoirCouplingMaster>(
256 void init(
const SimulatorTimer& timer)
259 simulator_.setEpisodeIndex(-1);
262 solverTimer_ = std::make_unique<time::StopWatch>();
263 totalTimer_ = std::make_unique<time::StopWatch>();
264 totalTimer_->start();
267 bool enableAdaptive = Parameters::Get<Parameters::EnableAdaptiveTimeStepping>();
268 bool enableTUNING = Parameters::Get<Parameters::EnableTuning>();
271 const auto&
sched_state = schedule()[timer.currentStepNum()];
274 adaptiveTimeStepping_ = std::make_unique<TimeStepper>(
max_next_tstep,
284 adaptiveTimeStepping_->setSuggestedNextStep(simulator_.timeStepSize());
291 modelParam_.tolerance_cnv_ =
tuning.TRGCNV;
292 modelParam_.tolerance_cnv_relaxed_ =
tuning.XXXCNV;
293 modelParam_.tolerance_mb_ =
tuning.TRGMBE;
294 modelParam_.tolerance_mb_relaxed_ =
tuning.XXXMBE;
295 modelParam_.newton_max_iter_ =
tuning.NEWTMX;
296 modelParam_.newton_min_iter_ =
tuning.NEWTMN;
297 if (terminalOutput_) {
298 const auto msg = fmt::format(
"Tuning values: "
299 "MB: {:.2e}, CNV: {:.2e}, NEWTMN: {}, NEWTMX: {}",
302 if (
tuning.TRGTTE_has_value) {
303 OpmLog::warning(
"Tuning item 2-1 (TRGTTE) is not supported.");
305 if (
tuning.TRGLCV_has_value) {
306 OpmLog::warning(
"Tuning item 2-4 (TRGLCV) is not supported.");
308 if (
tuning.XXXTTE_has_value) {
309 OpmLog::warning(
"Tuning item 2-5 (XXXTTE) is not supported.");
311 if (
tuning.XXXLCV_has_value) {
312 OpmLog::warning(
"Tuning item 2-8 (XXXLCV) is not supported.");
314 if (
tuning.XXXWFL_has_value) {
315 OpmLog::warning(
"Tuning item 2-9 (XXXWFL) is not supported.");
317 if (
tuning.TRGFIP_has_value) {
318 OpmLog::warning(
"Tuning item 2-10 (TRGFIP) is not supported.");
320 if (
tuning.TRGSFT_has_value) {
321 OpmLog::warning(
"Tuning item 2-11 (TRGSFT) is not supported.");
323 if (
tuning.THIONX_has_value) {
324 OpmLog::warning(
"Tuning item 2-12 (THIONX) is not supported.");
326 if (
tuning.TRWGHT_has_value) {
327 OpmLog::warning(
"Tuning item 2-13 (TRWGHT) is not supported.");
329 if (
tuning.LITMAX_has_value) {
330 OpmLog::warning(
"Tuning item 3-3 (LITMAX) is not supported.");
332 if (
tuning.LITMIN_has_value) {
333 OpmLog::warning(
"Tuning item 3-4 (LITMIN) is not supported.");
335 if (
tuning.MXWSIT_has_value) {
336 OpmLog::warning(
"Tuning item 3-5 (MXWSIT) is not supported.");
338 if (
tuning.MXWPIT_has_value) {
339 OpmLog::warning(
"Tuning item 3-6 (MXWPIT) is not supported.");
341 if (
tuning.DDPLIM_has_value) {
342 OpmLog::warning(
"Tuning item 3-7 (DDPLIM) is not supported.");
344 if (
tuning.DDSLIM_has_value) {
345 OpmLog::warning(
"Tuning item 3-8 (DDSLIM) is not supported.");
347 if (
tuning.TRGDPR_has_value) {
348 OpmLog::warning(
"Tuning item 3-9 (TRGDPR) is not supported.");
350 if (
tuning.XXXDPR_has_value) {
351 OpmLog::warning(
"Tuning item 3-10 (XXXDPR) is not supported.");
353 if (
tuning.MNWRFP_has_value) {
354 OpmLog::warning(
"Tuning item 3-11 (MNWRFP) is not supported.");
359 bool runStep(SimulatorTimer& timer)
362 if (terminalOutput_) {
363 OpmLog::info(
"Stopping simulation since EXIT was triggered by an action keyword.");
365 report_.success.exit_status = schedule().exitStatus().value();
374 if (terminalOutput_) {
375 std::ostringstream
ss;
377 OpmLog::debug(
ss.str());
378 details::outputReportStep(timer);
382 if (timer.initialStep()) {
386 simulator_.setEpisodeIndex(-1);
387 simulator_.setEpisodeLength(0.0);
388 simulator_.setTimeStepSize(0.0);
389 wellModel_().beginReportStep(timer.currentStepNum());
390 simulator_.problem().writeOutput(
true);
392 report_.success.output_write_time +=
perfTimer.stop();
396 solverTimer_->start();
399 solver_ = createSolver(wellModel_());
402 simulator_.startNextEpisode(
403 simulator_.startTime()
404 + schedule().
seconds(timer.currentStepNum()),
405 timer.currentStepLength());
406 simulator_.setEpisodeIndex(timer.currentStepNum());
409 wellModel_().prepareDeserialize(serializer_.
loadStep() - 1);
411 simulator_.model().invalidateAndUpdateIntensiveQuantities(0);
414 this->solver_->model().beginReportStep();
416 const bool enableTUNING = Parameters::Get<Parameters::EnableTuning>();
423 if (adaptiveTimeStepping_) {
425 reportStep = timer.currentStepNum()](
const double curr_time,
428 auto& schedule = this->simulator_.vanguard().schedule();
429 auto& events = this->schedule()[reportStep].events();
432 if (events.hasEvent(ScheduleEvents::TUNING_CHANGE)) {
434 schedule.clear_event(ScheduleEvents::TUNING_CHANGE, reportStep);
443 solver_->model().updateTUNING(
tuning);
444 this->updateTUNING(
tuning);
445 dt = this->adaptiveTimeStepping_->suggestedNextStep();
453 const auto&
wcycle = schedule[reportStep].wcycle.get();
458 const auto&
wmatcher = schedule.wellMatcher(reportStep);
463 this->wellModel_().wellOpenTimes(),
464 this->wellModel_().wellCloseTimes(),
466 &
wg_events = this->wellModel_().reportStepStartEvents()]
467 (
const std::string& name)
472 return wg_events.hasEvent(name, ScheduleEvents::REQUEST_OPEN_WELL);
485 this->adaptiveTimeStepping_->suggestedNextStep(), 0);
487#ifdef RESERVOIR_COUPLING_ENABLED
496 const auto& events = schedule()[timer.currentStepNum()].events();
497 bool event = events.hasEvent(ScheduleEvents::NEW_WELL) ||
498 events.hasEvent(ScheduleEvents::INJECTION_TYPE_CHANGED) ||
499 events.hasEvent(ScheduleEvents::WELL_SWITCHED_INJECTOR_PRODUCER) ||
500 events.hasEvent(ScheduleEvents::PRODUCTION_UPDATE) ||
501 events.hasEvent(ScheduleEvents::INJECTION_UPDATE) ||
502 events.hasEvent(ScheduleEvents::WELL_STATUS_CHANGE);
506 simulator_.problem().setSimulationReport(report_);
509 auto stepReport = solver_->step(timer,
nullptr);
511 if (terminalOutput_) {
512 std::ostringstream
ss;
514 OpmLog::info(
ss.str());
521 const double nextstep = adaptiveTimeStepping_ ? adaptiveTimeStepping_->suggestedNextStep() : -1.0;
522 simulator_.problem().setNextTimeStepSize(
nextstep);
523 simulator_.problem().writeOutput(
true);
524 report_.success.output_write_time +=
perfTimer.stop();
526 solver_->model().endReportStep();
529 solverTimer_->stop();
532 report_.success.solver_time += solverTimer_->secsSinceStart();
534 if (this->grid().comm().rank() == 0) {
537 const auto&
reps = this->solver_->model().stepReports();
544 if (terminalOutput_) {
546 "Time step took " + std::to_string(solverTimer_->secsSinceStart()) +
" seconds; "
547 "total solver time " + std::to_string(report_.success.solver_time) +
" seconds.";
551 serializer_.
save(timer);
556 SimulatorReport finalize()
563 simulator_.problem().finalizeOutput();
569 report_.success.total_time = totalTimer_->secsSinceStart();
570 report_.success.converged =
true;
575 const Grid& grid()
const
576 {
return simulator_.vanguard().grid(); }
578 template<
class Serializer>
586 const Model& model()
const
587 {
return solver_->model(); }
611 std::ostringstream
str;
612 Parameters::printValues(
str);
616 simulator_.vanguard().caseName(),
623 return simulator_.vanguard().globalCell();
626 std::unique_ptr<Solver> createSolver(WellModel& wellModel)
628 auto model = std::make_unique<Model>(simulator_,
633 if (this->modelParam_.write_partitions_) {
634 const auto&
iocfg = this->eclState().cfg().io();
637 / std::filesystem::path {
"partition" }
638 /
iocfg.getBaseName();
640 if (this->grid().comm().rank() == 0) {
644 this->grid().comm().barrier();
646 model->writePartitions(
odir);
648 this->modelParam_.write_partitions_ =
false;
651 return std::make_unique<Solver>(solverParam_, std::move(model));
654 const EclipseState& eclState()
const
655 {
return simulator_.vanguard().eclState(); }
659 {
return simulator_.vanguard().schedule(); }
661 bool isRestart()
const
663 const auto&
initconfig = eclState().getInitConfig();
667 WellModel& wellModel_()
668 {
return simulator_.problem().wellModel(); }
670 const WellModel& wellModel_()
const
671 {
return simulator_.problem().wellModel(); }
674 Simulator& simulator_;
676 ModelParameters modelParam_;
677 SolverParameters solverParam_;
679 std::unique_ptr<Solver> solver_;
683 bool terminalOutput_;
685 SimulatorReport report_;
686 std::unique_ptr<time::StopWatch> solverTimer_;
687 std::unique_ptr<time::StopWatch> totalTimer_;
688 std::unique_ptr<TimeStepper> adaptiveTimeStepping_;
690 SimulatorConvergenceOutput convergence_output_{};
692#ifdef RESERVOIR_COUPLING_ENABLED
698 SimulatorSerializer serializer_;