My Project
FlowMainEbos.hpp
1/*
2 Copyright 2013, 2014, 2015 SINTEF ICT, Applied Mathematics.
3 Copyright 2014 Dr. Blatt - HPC-Simulation-Software & Services
4 Copyright 2015 IRIS AS
5 Copyright 2014 STATOIL ASA.
6
7 This file is part of the Open Porous Media project (OPM).
8
9 OPM is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14 OPM is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with OPM. If not, see <http://www.gnu.org/licenses/>.
21*/
22#ifndef OPM_FLOW_MAIN_EBOS_HEADER_INCLUDED
23#define OPM_FLOW_MAIN_EBOS_HEADER_INCLUDED
24
25
26#include <sys/utsname.h>
27
28#include <opm/simulators/flow/SimulatorFullyImplicitBlackoilEbos.hpp>
29#include <opm/simulators/utils/ParallelFileMerger.hpp>
30#include <opm/simulators/utils/moduleVersion.hpp>
31#include <opm/simulators/utils/ParallelEclipseState.hpp>
32#include <flow/flow_ebos_blackoil.hpp>
33
34#include <opm/input/eclipse/EclipseState/EclipseState.hpp>
35#include <opm/input/eclipse/EclipseState/IOConfig/IOConfig.hpp>
36#include <opm/input/eclipse/EclipseState/InitConfig/InitConfig.hpp>
37#include <opm/input/eclipse/Schedule/UDQ/UDQState.hpp>
38#include <opm/common/utility/String.hpp>
39
40#include <fmt/format.h>
41#include <filesystem>
42
43#if HAVE_DUNE_FEM
44#include <dune/fem/misc/mpimanager.hh>
45#else
46#include <dune/common/parallel/mpihelper.hh>
47#endif
48
49namespace Opm::Properties {
50
51template<class TypeTag, class MyTypeTag>
53 using type = UndefinedProperty;
54};
55template<class TypeTag, class MyTypeTag>
57 using type = UndefinedProperty;
58};
59template<class TypeTag, class MyTypeTag>
61 using type = UndefinedProperty;
62};
63
64// TODO: enumeration parameters. we use strings for now.
65template<class TypeTag>
66struct EnableDryRun<TypeTag, TTag::EclFlowProblem> {
67 static constexpr auto value = "auto";
68};
69// Do not merge parallel output files or warn about them
70template<class TypeTag>
71struct EnableLoggingFalloutWarning<TypeTag, TTag::EclFlowProblem> {
72 static constexpr bool value = false;
73};
74template<class TypeTag>
75struct OutputInterval<TypeTag, TTag::EclFlowProblem> {
76 static constexpr int value = 1;
77};
78
79} // namespace Opm::Properties
80
81namespace Opm
82{
83
84 class Deck;
85
86 // The FlowMain class is the ebos based black-oil simulator.
87 template <class TypeTag>
89 {
90 public:
91 using MaterialLawManager = typename GetProp<TypeTag, Properties::MaterialLaw>::EclMaterialLawManager;
92 using EbosSimulator = GetPropType<TypeTag, Properties::Simulator>;
93 using Grid = GetPropType<TypeTag, Properties::Grid>;
94 using GridView = GetPropType<TypeTag, Properties::GridView>;
95 using Problem = GetPropType<TypeTag, Properties::Problem>;
96 using Scalar = GetPropType<TypeTag, Properties::Scalar>;
97 using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>;
98
100
101 FlowMainEbos(int argc, char **argv, bool output_cout, bool output_files )
102 : argc_{argc}, argv_{argv},
103 output_cout_{output_cout}, output_files_{output_files}
104 {
105
106 }
107
108 // Read the command line parameters. Throws an exception if something goes wrong.
109 static int setupParameters_(int argc, char** argv, Parallel::Communication comm)
110 {
111 using ParamsMeta = GetProp<TypeTag, Properties::ParameterMetaData>;
112 if (!ParamsMeta::registrationOpen()) {
113 // We have already successfully run setupParameters_().
114 // For the dynamically chosen runs (as from the main flow
115 // executable) we must run this function again with the
116 // real typetag to be used, as the first time was with the
117 // "FlowEarlyBird" typetag. However, for the static ones (such
118 // as 'flow_onephase_energy') it has already been run with the
119 // correct typetag.
120 return EXIT_SUCCESS;
121 }
122 // register the flow specific parameters
123 EWOMS_REGISTER_PARAM(TypeTag, std::string, EnableDryRun,
124 "Specify if the simulation ought to be actually run, or just pretended to be");
125 EWOMS_REGISTER_PARAM(TypeTag, int, OutputInterval,
126 "Specify the number of report steps between two consecutive writes of restart data");
127 EWOMS_REGISTER_PARAM(TypeTag, bool, EnableLoggingFalloutWarning,
128 "Developer option to see whether logging was on non-root processors. In that case it will be appended to the *.DBG or *.PRT files");
129
130 Simulator::registerParameters();
131
132 // register the parameters inherited from ebos
133 registerAllParameters_<TypeTag>(/*finalizeRegistration=*/false);
134
135 // hide the parameters unused by flow. TODO: this is a pain to maintain
136 EWOMS_HIDE_PARAM(TypeTag, EnableGravity);
137 EWOMS_HIDE_PARAM(TypeTag, EnableGridAdaptation);
138
139 // this parameter is actually used in eWoms, but the flow well model
140 // hard-codes the assumption that the intensive quantities cache is enabled,
141 // so flow crashes. Let's hide the parameter for that reason.
142 EWOMS_HIDE_PARAM(TypeTag, EnableIntensiveQuantityCache);
143
144 // thermodynamic hints are not implemented/required by the eWoms blackoil
145 // model
146 EWOMS_HIDE_PARAM(TypeTag, EnableThermodynamicHints);
147
148 // in flow only the deck file determines the end time of the simulation
149 EWOMS_HIDE_PARAM(TypeTag, EndTime);
150
151 // time stepping is not done by the eWoms code in flow
152 EWOMS_HIDE_PARAM(TypeTag, InitialTimeStepSize);
153 EWOMS_HIDE_PARAM(TypeTag, MaxTimeStepDivisions);
154 EWOMS_HIDE_PARAM(TypeTag, MaxTimeStepSize);
155 EWOMS_HIDE_PARAM(TypeTag, MinTimeStepSize);
156 EWOMS_HIDE_PARAM(TypeTag, PredeterminedTimeStepsFile);
157
158 EWOMS_HIDE_PARAM(TypeTag, EclMaxTimeStepSizeAfterWellEvent);
159 EWOMS_HIDE_PARAM(TypeTag, EclRestartShrinkFactor);
160 EWOMS_HIDE_PARAM(TypeTag, EclEnableTuning);
161
162 // flow also does not use the eWoms Newton method
163 EWOMS_HIDE_PARAM(TypeTag, NewtonMaxError);
164 EWOMS_HIDE_PARAM(TypeTag, NewtonMaxIterations);
165 EWOMS_HIDE_PARAM(TypeTag, NewtonTolerance);
166 EWOMS_HIDE_PARAM(TypeTag, NewtonTargetIterations);
167 EWOMS_HIDE_PARAM(TypeTag, NewtonVerbose);
168 EWOMS_HIDE_PARAM(TypeTag, NewtonWriteConvergence);
169 EWOMS_HIDE_PARAM(TypeTag, EclNewtonSumTolerance);
170 EWOMS_HIDE_PARAM(TypeTag, EclNewtonSumToleranceExponent);
171 EWOMS_HIDE_PARAM(TypeTag, EclNewtonStrictIterations);
172 EWOMS_HIDE_PARAM(TypeTag, EclNewtonRelaxedVolumeFraction);
173 EWOMS_HIDE_PARAM(TypeTag, EclNewtonRelaxedTolerance);
174
175 // the default eWoms checkpoint/restart mechanism does not work with flow
176 EWOMS_HIDE_PARAM(TypeTag, RestartTime);
177 EWOMS_HIDE_PARAM(TypeTag, RestartWritingInterval);
178 // hide all vtk related it is not currently possible to do this dependet on if the vtk writing is used
179 //if(not(EWOMS_GET_PARAM(TypeTag,bool,EnableVtkOutput))){
180 EWOMS_HIDE_PARAM(TypeTag, VtkWriteOilFormationVolumeFactor);
181 EWOMS_HIDE_PARAM(TypeTag, VtkWriteOilSaturationPressure);
182 EWOMS_HIDE_PARAM(TypeTag, VtkWriteOilVaporizationFactor);
183 EWOMS_HIDE_PARAM(TypeTag, VtkWritePorosity);
184 EWOMS_HIDE_PARAM(TypeTag, VtkWritePotentialGradients);
185 EWOMS_HIDE_PARAM(TypeTag, VtkWritePressures);
186 EWOMS_HIDE_PARAM(TypeTag, VtkWritePrimaryVars);
187 EWOMS_HIDE_PARAM(TypeTag, VtkWritePrimaryVarsMeaning);
188 EWOMS_HIDE_PARAM(TypeTag, VtkWriteProcessRank);
189 EWOMS_HIDE_PARAM(TypeTag, VtkWriteRelativePermeabilities);
190 EWOMS_HIDE_PARAM(TypeTag, VtkWriteSaturatedGasOilVaporizationFactor);
191 EWOMS_HIDE_PARAM(TypeTag, VtkWriteSaturatedOilGasDissolutionFactor);
192 EWOMS_HIDE_PARAM(TypeTag, VtkWriteSaturationRatios);
193 EWOMS_HIDE_PARAM(TypeTag, VtkWriteSaturations);
194 EWOMS_HIDE_PARAM(TypeTag, VtkWriteTemperature);
195 EWOMS_HIDE_PARAM(TypeTag, VtkWriteViscosities);
196 EWOMS_HIDE_PARAM(TypeTag, VtkWriteWaterFormationVolumeFactor);
197 EWOMS_HIDE_PARAM(TypeTag, VtkWriteGasDissolutionFactor);
198 EWOMS_HIDE_PARAM(TypeTag, VtkWriteGasFormationVolumeFactor);
199 EWOMS_HIDE_PARAM(TypeTag, VtkWriteGasSaturationPressure);
200 EWOMS_HIDE_PARAM(TypeTag, VtkWriteIntrinsicPermeabilities);
201 EWOMS_HIDE_PARAM(TypeTag, VtkWriteEclTracerConcentration);
202 EWOMS_HIDE_PARAM(TypeTag, VtkWriteExtrusionFactor);
203 EWOMS_HIDE_PARAM(TypeTag, VtkWriteFilterVelocities);
204 EWOMS_HIDE_PARAM(TypeTag, VtkWriteDensities);
205 EWOMS_HIDE_PARAM(TypeTag, VtkWriteDofIndex);
206 EWOMS_HIDE_PARAM(TypeTag, VtkWriteMobilities);
207 //}
208 EWOMS_HIDE_PARAM(TypeTag, VtkWriteAverageMolarMasses);
209 EWOMS_HIDE_PARAM(TypeTag, VtkWriteFugacities);
210 EWOMS_HIDE_PARAM(TypeTag, VtkWriteFugacityCoeffs);
211 EWOMS_HIDE_PARAM(TypeTag, VtkWriteMassFractions);
212 EWOMS_HIDE_PARAM(TypeTag, VtkWriteMolarities);
213 EWOMS_HIDE_PARAM(TypeTag, VtkWriteMoleFractions);
214 EWOMS_HIDE_PARAM(TypeTag, VtkWriteTotalMassFractions);
215 EWOMS_HIDE_PARAM(TypeTag, VtkWriteTotalMoleFractions);
216
217 EWOMS_HIDE_PARAM(TypeTag, VtkWriteTortuosities);
218 EWOMS_HIDE_PARAM(TypeTag, VtkWriteDiffusionCoefficients);
219 EWOMS_HIDE_PARAM(TypeTag, VtkWriteEffectiveDiffusionCoefficients);
220
221 EWOMS_END_PARAM_REGISTRATION(TypeTag);
222
223 int mpiRank = comm.rank();
224
225 // read in the command line parameters
226 int status = ::Opm::setupParameters_<TypeTag>(argc, const_cast<const char**>(argv), /*doRegistration=*/false, /*allowUnused=*/true, /*handleHelp=*/(mpiRank==0));
227 if (status == 0) {
228
229 // deal with unknown parameters.
230
231 int unknownKeyWords = 0;
232 if (mpiRank == 0) {
233 unknownKeyWords = Parameters::printUnused<TypeTag>(std::cerr);
234 }
235 int globalUnknownKeyWords = comm.sum(unknownKeyWords);
236 unknownKeyWords = globalUnknownKeyWords;
237 if ( unknownKeyWords )
238 {
239 if ( mpiRank == 0 )
240 {
241 std::string msg = "Aborting simulation due to unknown "
242 "parameters. Please query \"flow --help\" for "
243 "supported command line parameters.";
244 if (OpmLog::hasBackend("STREAMLOG"))
245 {
246 OpmLog::error(msg);
247 }
248 else {
249 std::cerr << msg << std::endl;
250 }
251 }
252 return EXIT_FAILURE;
253 }
254
255 // deal with --print-properties and --print-parameters and unknown parameters.
256
257 bool doExit = false;
258
259 if (EWOMS_GET_PARAM(TypeTag, int, PrintProperties) == 1) {
260 doExit = true;
261 if (mpiRank == 0)
262 Properties::printValues<TypeTag>();
263 }
264
265 if (EWOMS_GET_PARAM(TypeTag, int, PrintParameters) == 1) {
266 doExit = true;
267 if (mpiRank == 0)
268 Parameters::printValues<TypeTag>();
269 }
270
271 if (doExit)
272 return -1;
273 }
274
275 return status;
276 }
277
278 static void printBanner(Parallel::Communication comm)
279 {
280 const int lineLen = 70;
281 const std::string version = moduleVersionName();
282 const std::string banner = "This is flow "+version;
283 const int bannerPreLen = (lineLen - 2 - banner.size())/2;
284 const int bannerPostLen = bannerPreLen + (lineLen - 2 - banner.size())%2;
285 std::cout << "**********************************************************************\n";
286 std::cout << "* *\n";
287 std::cout << "*" << std::string(bannerPreLen, ' ') << banner << std::string(bannerPostLen, ' ') << "*\n";
288 std::cout << "* *\n";
289 std::cout << "* Flow is a simulator for fully implicit three-phase black-oil flow, *\n";
290 std::cout << "* including solvent and polymer capabilities. *\n";
291 std::cout << "* For more information, see https://opm-project.org *\n";
292 std::cout << "* *\n";
293 std::cout << "**********************************************************************\n\n";
294
295 int threads = 1;
296
297#ifdef _OPENMP
298 // This function is called before the parallel OpenMP stuff gets initialized.
299 // That initialization happends after the deck is read and we want this message.
300 // Hence we duplicate the code of setupParallelism to get the number of threads.
301 if (getenv("OMP_NUM_THREADS"))
302 threads = omp_get_max_threads();
303 else
304 threads = std::min(2, omp_get_max_threads());
305
306 const int input_threads = EWOMS_GET_PARAM(TypeTag, int, ThreadsPerProcess);
307
308 if (input_threads > 0)
309 threads = std::min(input_threads, omp_get_max_threads());
310#endif
311
312 int mpiSize = comm.size();
313
314 std::cout << "Using "<< mpiSize << " MPI processes with "<< threads <<" OMP threads on each \n\n";
315 }
316
321 {
322 return execute_(&FlowMainEbos::runSimulator, /*cleanup=*/true);
323 }
324
325 int executeInitStep()
326 {
327 return execute_(&FlowMainEbos::runSimulatorInit, /*cleanup=*/false);
328 }
329
330 // Returns true unless "EXIT" was encountered in the schedule
331 // section of the input datafile.
332 int executeStep()
333 {
334 return simulator_->runStep(*simtimer_);
335 }
336
337 // Called from Python to cleanup after having executed the last
338 // executeStep()
339 int executeStepsCleanup()
340 {
341 SimulatorReport report = simulator_->finalize();
342 runSimulatorAfterSim_(report);
343 return report.success.exit_status;
344 }
345
346 // Print an ASCII-art header to the PRT and DEBUG files.
347 // \return Whether unkown keywords were seen during parsing.
348 static void printPRTHeader(bool output_cout)
349 {
350 if (output_cout) {
351 const std::string version = moduleVersion();
352 const double megabyte = 1024 * 1024;
353 unsigned num_cpu = std::thread::hardware_concurrency();
354 struct utsname arch;
355 const char* user = getlogin();
356 time_t now = std::time(0);
357 struct tm tstruct;
358 char tmstr[80];
359 tstruct = *localtime(&now);
360 strftime(tmstr, sizeof(tmstr), "%d-%m-%Y at %X", &tstruct);
361 const double mem_size = getTotalSystemMemory() / megabyte;
362 std::ostringstream ss;
363 ss << "\n\n\n";
364 ss << " ######## # ###### # #\n";
365 ss << " # # # # # # \n";
366 ss << " ##### # # # # # # \n";
367 ss << " # # # # # # # # \n";
368 ss << " # ####### ###### # # \n\n";
369 ss << "Flow is a simulator for fully implicit three-phase black-oil flow,";
370 ss << " and is part of OPM.\nFor more information visit: https://opm-project.org \n\n";
371 ss << "Flow Version = " + version + "\n";
372 if (uname(&arch) == 0) {
373 ss << "Machine name = " << arch.nodename << " (Number of logical cores: " << num_cpu;
374 ss << ", Memory size: " << std::fixed << std::setprecision (2) << mem_size << " MB) \n";
375 ss << "Operating system = " << arch.sysname << " " << arch.machine << " (Kernel: " << arch.release;
376 ss << ", " << arch.version << " )\n";
377 ss << "Build time = " << compileTimestamp() << "\n";
378 }
379 if (user) {
380 ss << "User = " << user << std::endl;
381 }
382 ss << "Simulation started on " << tmstr << " hrs\n";
383
384 ss << "Parameters used by Flow:\n";
385 Parameters::printValues<TypeTag>(ss);
386
387 OpmLog::note(ss.str());
388 }
389 }
390
391 EbosSimulator *getSimulatorPtr() {
392 return ebosSimulator_.get();
393 }
394
395 SimulatorTimer* getSimTimer() {
396 return simtimer_.get();
397 }
398
399 private:
400 // called by execute() or executeInitStep()
401 int execute_(int (FlowMainEbos::* runOrInitFunc)(), bool cleanup)
402 {
403 try {
404 // deal with some administrative boilerplate
405
406 int status = setupParameters_(this->argc_, this->argv_, EclGenericVanguard::comm());
407 if (status)
408 return status;
409
410 setupParallelism();
411 setupEbosSimulator();
413
414 // if run, do the actual work, else just initialize
415 int exitCode = (this->*runOrInitFunc)();
416 if (cleanup) {
417 executeCleanup_();
418 }
419 return exitCode;
420 }
421 catch (const std::exception& e) {
422 std::ostringstream message;
423 message << "Program threw an exception: " << e.what();
424
425 if (this->output_cout_) {
426 // in some cases exceptions are thrown before the logging system is set
427 // up.
428 if (OpmLog::hasBackend("STREAMLOG")) {
429 OpmLog::error(message.str());
430 }
431 else {
432 std::cout << message.str() << "\n";
433 }
434 }
435#if HAVE_MPI
436 if (this->mpi_size_ > 1)
437 MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE);
438#endif
439 return EXIT_FAILURE;
440 }
441 }
442
443 void executeCleanup_() {
444 // clean up
445 mergeParallelLogFiles();
446 }
447
448 protected:
449 void setupParallelism()
450 {
451 // determine the rank of the current process and the number of processes
452 // involved in the simulation. MPI must have already been initialized
453 // here. (yes, the name of this method is misleading.)
454 auto comm = EclGenericVanguard::comm();
455 mpi_rank_ = comm.rank();
456 mpi_size_ = comm.size();
457
458#if _OPENMP
459 // if openMP is available, default to 2 threads per process.
460 if (!getenv("OMP_NUM_THREADS"))
461 omp_set_num_threads(std::min(2, omp_get_num_procs()));
462#endif
463
464 using ThreadManager = GetPropType<TypeTag, Properties::ThreadManager>;
465 ThreadManager::init();
466 }
467
468
469
470 void mergeParallelLogFiles()
471 {
472 // force closing of all log files.
473 OpmLog::removeAllBackends();
474
475 if (mpi_rank_ != 0 || mpi_size_ < 2 || !this->output_files_) {
476 return;
477 }
478
479 namespace fs = ::std::filesystem;
480 const std::string& output_dir = eclState().getIOConfig().getOutputDir();
481 fs::path output_path(output_dir);
482 fs::path deck_filename(EWOMS_GET_PARAM(TypeTag, std::string, EclDeckFileName));
483 std::string basename;
484 // Strip extension "." and ".DATA"
485 std::string extension = uppercase(deck_filename.extension().string());
486 if ( extension == ".DATA" || extension == "." )
487 {
488 basename = uppercase(deck_filename.stem().string());
489 }
490 else
491 {
492 basename = uppercase(deck_filename.filename().string());
493 }
494 std::for_each(fs::directory_iterator(output_path),
495 fs::directory_iterator(),
496 detail::ParallelFileMerger(output_path, basename,
497 EWOMS_GET_PARAM(TypeTag, bool, EnableLoggingFalloutWarning)));
498 }
499
500 void setupEbosSimulator()
501 {
502 ebosSimulator_.reset(new EbosSimulator(EclGenericVanguard::comm(), /*verbose=*/false));
503 ebosSimulator_->executionTimer().start();
504 ebosSimulator_->model().applyInitialSolution();
505
506 try {
507 // Possible to force initialization only behavior (NOSIM).
508 const std::string& dryRunString = EWOMS_GET_PARAM(TypeTag, std::string, EnableDryRun);
509 if (dryRunString != "" && dryRunString != "auto") {
510 bool yesno;
511 if (dryRunString == "true"
512 || dryRunString == "t"
513 || dryRunString == "1")
514 yesno = true;
515 else if (dryRunString == "false"
516 || dryRunString == "f"
517 || dryRunString == "0")
518 yesno = false;
519 else
520 throw std::invalid_argument("Invalid value for parameter EnableDryRun: '"
521 +dryRunString+"'");
522 auto& ioConfig = eclState().getIOConfig();
523 ioConfig.overrideNOSIM(yesno);
524 }
525 }
526 catch (const std::invalid_argument& e) {
527 std::cerr << "Failed to create valid EclipseState object" << std::endl;
528 std::cerr << "Exception caught: " << e.what() << std::endl;
529 throw;
530 }
531 }
532
533 const Deck& deck() const
534 { return ebosSimulator_->vanguard().deck(); }
535
536 Deck& deck()
537 { return ebosSimulator_->vanguard().deck(); }
538
539 const EclipseState& eclState() const
540 { return ebosSimulator_->vanguard().eclState(); }
541
542 EclipseState& eclState()
543 { return ebosSimulator_->vanguard().eclState(); }
544
545 const Schedule& schedule() const
546 { return ebosSimulator_->vanguard().schedule(); }
547
548 // Run the simulator.
549 int runSimulator()
550 {
551 return runSimulatorInitOrRun_(&FlowMainEbos::runSimulatorRunCallback_);
552 }
553
554 int runSimulatorInit()
555 {
556 return runSimulatorInitOrRun_(&FlowMainEbos::runSimulatorInitCallback_);
557 }
558
559 private:
560 // Callback that will be called from runSimulatorInitOrRun_().
561 int runSimulatorRunCallback_()
562 {
563 SimulatorReport report = simulator_->run(*simtimer_);
564 runSimulatorAfterSim_(report);
565 return report.success.exit_status;
566 }
567
568 // Callback that will be called from runSimulatorInitOrRun_().
569 int runSimulatorInitCallback_()
570 {
571 simulator_->init(*simtimer_);
572 return EXIT_SUCCESS;
573 }
574
575 // Output summary after simulation has completed
576 void runSimulatorAfterSim_(SimulatorReport &report)
577 {
578 if (this->output_cout_) {
579 std::ostringstream ss;
580 ss << "\n\n================ End of simulation ===============\n\n";
581 ss << fmt::format("Number of MPI processes: {:9}\n", mpi_size_ );
582#if _OPENMP
583 int threads = omp_get_max_threads();
584#else
585 int threads = 1;
586#endif
587 ss << fmt::format("Threads per MPI process: {:9}\n", threads);
588 report.reportFullyImplicit(ss);
589 OpmLog::info(ss.str());
590 const std::string dir = eclState().getIOConfig().getOutputDir();
591 namespace fs = ::std::filesystem;
592 fs::path output_dir(dir);
593 {
594 std::string filename = eclState().getIOConfig().getBaseName() + ".INFOSTEP";
595 fs::path fullpath = output_dir / filename;
596 std::ofstream os(fullpath.string());
597 report.fullReports(os);
598 }
599 }
600 }
601
602 // Run the simulator.
603 int runSimulatorInitOrRun_(int (FlowMainEbos::* initOrRunFunc)())
604 {
605
606 const auto& schedule = this->schedule();
607 auto& ioConfig = eclState().getIOConfig();
608 simtimer_ = std::make_unique<SimulatorTimer>();
609
610 // initialize variables
611 const auto& initConfig = eclState().getInitConfig();
612 simtimer_->init(schedule, (size_t)initConfig.getRestartStep());
613
614 if (this->output_cout_) {
615 std::ostringstream oss;
616
617 // This allows a user to catch typos and misunderstandings in the
618 // use of simulator parameters.
619 if (Parameters::printUnused<TypeTag>(oss)) {
620 std::cout << "----------------- Unrecognized parameters: -----------------\n";
621 std::cout << oss.str();
622 std::cout << "----------------------------------------------------------------" << std::endl;
623 }
624 }
625
626 if (!ioConfig.initOnly()) {
627 if (this->output_cout_) {
628 std::string msg;
629 msg = "\n\n================ Starting main simulation loop ===============\n";
630 OpmLog::info(msg);
631 }
632
633 return (this->*initOrRunFunc)();
634 }
635 else {
636 if (this->output_cout_) {
637 std::cout << "\n\n================ Simulation turned off ===============\n" << std::flush;
638 }
639 return EXIT_SUCCESS;
640 }
641 }
642
643 protected:
644
646 // Create simulator instance.
647 // Writes to:
648 // simulator_
650 {
651 // Create the simulator instance.
652 simulator_.reset(new Simulator(*ebosSimulator_));
653 }
654
655 static unsigned long long getTotalSystemMemory()
656 {
657 long pages = sysconf(_SC_PHYS_PAGES);
658 long page_size = sysconf(_SC_PAGE_SIZE);
659 return pages * page_size;
660 }
661
662
663 Grid& grid()
664 { return ebosSimulator_->vanguard().grid(); }
665
666 private:
667 std::unique_ptr<EbosSimulator> ebosSimulator_;
668 int mpi_rank_ = 0;
669 int mpi_size_ = 1;
670 std::any parallel_information_;
671 std::unique_ptr<Simulator> simulator_;
672 std::unique_ptr<SimulatorTimer> simtimer_;
673 int argc_;
674 char **argv_;
675 bool output_cout_;
676 bool output_files_;
677 };
678} // namespace Opm
679
680#endif // OPM_FLOW_MAIN_EBOS_HEADER_INCLUDED
Definition: FlowMainEbos.hpp:89
int execute()
This is the main function of Flow.
Definition: FlowMainEbos.hpp:320
void createSimulator()
This is the main function of Flow.
Definition: FlowMainEbos.hpp:649
a simulator for the blackoil model
Definition: SimulatorFullyImplicitBlackoilEbos.hpp:72
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:34
std::string compileTimestamp()
Return a string "dd-mm-yyyy at HH::MM::SS hrs" which is the time the binary was compiled.
Definition: moduleVersion.cpp:57
std::string moduleVersion()
Return a string containing both the name and hash, if N is the name and H is the hash it will be "N (...
Definition: moduleVersion.cpp:50
Definition: FlowMainEbos.hpp:52
Definition: FlowMainEbos.hpp:60
Definition: FlowMainEbos.hpp:56