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