Main.hpp
Go to the documentation of this file.
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 Copyright 2023 Inria
7
8 This file is part of the Open Porous Media project (OPM).
9
10 OPM is free software: you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation, either version 3 of the License, or
13 (at your option) any later version.
14
15 OPM is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with OPM. If not, see <http://www.gnu.org/licenses/>.
22*/
23#ifndef OPM_MAIN_HEADER_INCLUDED
24#define OPM_MAIN_HEADER_INCLUDED
25
26#include <flow/flow_blackoil.hpp>
27#include <flow/flow_blackoil_legacyassembly.hpp>
28
29#include <flow/flow_gasoil.hpp>
30#include <flow/flow_gasoildiffuse.hpp>
31#include <flow/flow_gasoil_energy.hpp>
32#include <flow/flow_oilwater.hpp>
33#include <flow/flow_gaswater.hpp>
34#include <flow/flow_gaswater_solvent.hpp>
35#include <flow/flow_solvent.hpp>
36#include <flow/flow_solvent_foam.hpp>
37#include <flow/flow_polymer.hpp>
38#include <flow/flow_extbo.hpp>
39#include <flow/flow_foam.hpp>
40#include <flow/flow_brine.hpp>
41#include <flow/flow_brine_saltprecipitation.hpp>
42#include <flow/flow_gaswater_saltprec_vapwat.hpp>
43#include <flow/flow_gaswater_saltprec_energy.hpp>
44#include <flow/flow_brine_precsalt_vapwat.hpp>
45#include <flow/flow_onephase.hpp>
46#include <flow/flow_onephase_energy.hpp>
47#include <flow/flow_oilwater_brine.hpp>
48#include <flow/flow_gaswater_brine.hpp>
49#include <flow/flow_gaswater_energy.hpp>
50#include <flow/flow_gaswater_dissolution.hpp>
51#include <flow/flow_gaswater_dissolution_diffuse.hpp>
52#include <flow/flow_energy.hpp>
53#include <flow/flow_oilwater_polymer.hpp>
54#include <flow/flow_oilwater_polymer_injectivity.hpp>
55#include <flow/flow_micp.hpp>
56
57#include <opm/input/eclipse/EclipseState/EclipseState.hpp>
58
61
64
65#if HAVE_DUNE_FEM
66#include <dune/fem/misc/mpimanager.hh>
67#else
68#include <dune/common/parallel/mpihelper.hh>
69#endif
70
71#if HAVE_MPI
73#endif
74
75#if HAVE_DAMARIS
77#endif
78
79#include <cassert>
80#include <charconv>
81#include <cstdlib>
82#include <filesystem>
83#include <iostream>
84#include <memory>
85#include <stdexcept>
86#include <string>
87#include <string_view>
88#include <type_traits>
89#include <utility>
90
91namespace Opm::Properties {
92
93// this is a dummy type tag that is used to setup the parameters before the actual
94// simulator.
95namespace TTag {
97 using InheritsFrom = std::tuple<FlowProblem>;
98};
99}
100
101} // namespace Opm::Properties
102
103namespace Opm {
104
105namespace Action { class State; }
106class UDQState;
107class WellTestState;
108
109// ----------------- Main program -----------------
110template <class TypeTag>
111int flowMain(int argc, char** argv, bool outputCout, bool outputFiles)
112{
113 // we always want to use the default locale, and thus spare us the trouble
114 // with incorrect locale settings.
115 resetLocale();
116
117 FlowMain<TypeTag> mainfunc(argc, argv, outputCout, outputFiles);
118 return mainfunc.execute();
119}
120
121// ----------------- Main class -----------------
122// For now, we will either be instantiated from main() in flow.cpp,
123// or from a Python pybind11 module..
124// NOTE (March 2020): When used from a pybind11 module, we do not neccessarily
125// want to run the whole simulation by calling run(), it is also
126// useful to just run one report step at a time. According to these different
127// usage scenarios, we refactored the original run() in flow.cpp into this class.
128class Main
129{
130public:
131 Main(int argc, char** argv, bool ownMPI = true);
132
133 // This constructor can be called from Python
134 Main(const std::string& filename, bool mpi_init = true, bool mpi_finalize = true);
135
136 // This constructor can be called from Python when Python has
137 // already parsed a deck
138 Main(const std::string& filename,
139 std::shared_ptr<EclipseState> eclipseState,
140 std::shared_ptr<Schedule> schedule,
141 std::shared_ptr<SummaryConfig> summaryConfig,
142 bool mpi_init = true,
143 bool mpi_finalize = true);
144
146
147 void setArgvArgc_(const std::string& filename);
148
149 void initMPI();
150
152 {
153 int exitCode = EXIT_SUCCESS;
154 if (initialize_<Properties::TTag::FlowEarlyBird>(exitCode)) {
156 if (isSimulationRank_) {
157 return this->dispatchDynamic_();
158 }
159 }
160
161 return exitCode;
162 }
163
164 template <class TypeTag>
166 {
167 int exitCode = EXIT_SUCCESS;
168 if (initialize_<TypeTag>(exitCode)) {
169 if (isSimulationRank_) {
170 return this->dispatchStatic_<TypeTag>();
171 }
172 }
173
174 return exitCode;
175 }
176
179 {
180 int exitCode = EXIT_SUCCESS;
181 initialize_<Properties::TTag::FlowEarlyBird>(exitCode);
182 return exitCode;
183 }
184
185private:
186 int dispatchDynamic_()
187 {
188 const auto& rspec = this->eclipseState_->runspec();
189 const auto& phases = rspec.phases();
190
191 this->setupVanguard();
192
193 // run the actual simulator
194 //
195 // TODO: make sure that no illegal combinations like thermal and
196 // twophase are requested.
197 const bool thermal = eclipseState_->getSimulationConfig().isThermal();
198
199 // Single-phase case
200 if (rspec.micp()) {
201 return this->runMICP(phases);
202 }
203
204 // water-only case
205 else if (phases.size() == 1 && phases.active(Phase::WATER) && !thermal) {
206 return this->runWaterOnly(phases);
207 }
208
209 // water-only case with energy
210 else if (phases.size() == 2 && phases.active(Phase::WATER) && thermal) {
211 return this->runWaterOnlyEnergy(phases);
212 }
213
214 // Twophase cases
215 else if (phases.size() == 2 && !thermal) {
216 return this->runTwoPhase(phases);
217 }
218
219 // Polymer case
220 else if (phases.active(Phase::POLYMER)) {
221 return this->runPolymer(phases);
222 }
223
224 // Foam case
225 else if (phases.active(Phase::FOAM) && !phases.active(Phase::SOLVENT)) {
226 return this->runFoam();
227 }
228
229 // Solvent case
230 else if (phases.active(Phase::SOLVENT)) {
231 return this->runSolvent(phases);
232 }
233
234 // Brine case
235 else if (phases.active(Phase::BRINE) && !thermal) {
236 return this->runBrine(phases);
237 }
238
239 // Extended BO case
240 else if (phases.active(Phase::ZFRACTION)) {
241 return this->runExtendedBlackOil();
242 }
243
244 // Energy case
245 else if (thermal) {
246 return this->runThermal(phases);
247 }
248
249 // Blackoil case
250 else if (phases.size() == 3) {
251 return this->runBlackOil();
252 }
253
254 else {
255 if (outputCout_) {
256 std::cerr << "No suitable configuration found, valid are "
257 << "Twophase, polymer, foam, brine, solvent, "
258 << "energy, and blackoil.\n";
259 }
260
261 return EXIT_FAILURE;
262 }
263 }
264
265 template <class TypeTag>
266 int dispatchStatic_()
267 {
268 this->setupVanguard();
269 return flowMain<TypeTag>(argc_, argv_, outputCout_, outputFiles_);
270 }
271
272protected:
279 template <class TypeTagEarlyBird>
280 bool initialize_(int& exitCode)
281 {
282 Dune::Timer externalSetupTimer;
283 externalSetupTimer.start();
284
285 handleVersionCmdLine_(argc_, argv_, Opm::moduleVersionName());
286
287 // we always want to use the default locale, and thus spare us the trouble
288 // with incorrect locale settings.
289 resetLocale();
290
291 // this is a work-around for a catch 22: we do not know what code path to use without
292 // parsing the deck, but we don't know the deck without having access to the
293 // parameters and this requires to know the type tag to be used. To solve this, we
294 // use a type tag just for parsing the parameters before we instantiate the actual
295 // simulator object. (Which parses the parameters again, but since this is done in an
296 // identical manner it does not matter.)
297 typedef TypeTagEarlyBird PreTypeTag;
299
300 PreProblem::setBriefDescription("Flow, an advanced reservoir simulator for ECL-decks provided by the Open Porous Media project.");
301 int status = FlowMain<PreTypeTag>::setupParameters_(argc_, argv_, FlowGenericVanguard::comm());
302 if (status != 0) {
303 // if setupParameters_ returns a value smaller than 0, there was no error, but
304 // the program should abort. This is the case e.g. for the --help and the
305 // --print-properties parameters.
306#if HAVE_MPI
307 if (status >= 0)
308 MPI_Abort(MPI_COMM_WORLD, status);
309#endif
310 exitCode = (status > 0) ? status : EXIT_SUCCESS;
311 return false; // Whether to run the simulator
312 }
313
314 std::string deckFilename;
315 std::string outputDir;
316 if ( eclipseState_ ) {
317 deckFilename = eclipseState_->getIOConfig().fullBasePath();
318 outputDir = eclipseState_->getIOConfig().getOutputDir();
319 }
320 else {
321 deckFilename = Parameters::Get<Parameters::EclDeckFileName>();
322 outputDir = Parameters::Get<Parameters::OutputDir>();
323 }
324
325#if HAVE_DAMARIS
326 enableDamarisOutput_ = Parameters::Get<Parameters::EnableDamarisOutput>();
327
328 // Reset to false as we cannot use Damaris if there is only one rank.
329 if ((enableDamarisOutput_ == true) && (FlowGenericVanguard::comm().size() == 1)) {
330 std::string msg ;
331 msg = "\nUse of Damaris (command line argument --enable-damaris-output=true) has been disabled for run with only one rank.\n" ;
332 OpmLog::warning(msg);
333 enableDamarisOutput_ = false ;
334 }
335
336 if (enableDamarisOutput_) {
337 // Deal with empty (defaulted) output dir, should be deck dir
338 auto damarisOutputDir = outputDir;
339 if (outputDir.empty()) {
340 auto odir = std::filesystem::path{deckFilename}.parent_path();
341 if (odir.empty()) {
342 damarisOutputDir = ".";
343 } else {
344 damarisOutputDir = odir.generic_string();
345 }
346 }
347 // Damaris server ranks will block here until damaris_stop() is called by client ranks
348 this->setupDamaris(damarisOutputDir);
349 }
350#endif // HAVE_DAMARIS
351
352 // Guard for when the Damaris core(s) return from damaris_start()
353 // which happens when damaris_stop() is called in main simulation
354 if (!isSimulationRank_) {
355 exitCode = EXIT_SUCCESS;
356 return true;
357 }
358
359 int mpiRank = FlowGenericVanguard::comm().rank();
360 outputCout_ = false;
361 if (mpiRank == 0)
362 outputCout_ = Parameters::Get<Parameters::EnableTerminalOutput>();
363
364 if (deckFilename.empty()) {
365 if (mpiRank == 0) {
366 std::cerr << "No input case given. Try '--help' for a usage description.\n";
367 }
368 exitCode = EXIT_FAILURE;
369 return false;
370 }
371
373 try {
374 deckFilename = PreVanguard::canonicalDeckPath(deckFilename);
375 }
376 catch (const std::exception& e) {
377 if ( mpiRank == 0 ) {
378 std::cerr << "Exception received: " << e.what() << ". Try '--help' for a usage description.\n";
379 }
380#if HAVE_MPI
381 MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE);
382#endif
383 exitCode = EXIT_FAILURE;
384 return false;
385 }
386
387 std::string cmdline_params;
388 if (outputCout_) {
390 getNumThreads(),
392 std::ostringstream str;
394 cmdline_params = str.str();
395 }
396
397 // Create Deck and EclipseState.
398 try {
399 this->readDeck(deckFilename,
400 outputDir,
401 Parameters::Get<Parameters::OutputMode>(),
402 !Parameters::Get<Parameters::SchedRestart>(),
403 Parameters::Get<Parameters::EnableLoggingFalloutWarning>(),
404 Parameters::Get<Parameters::ParsingStrictness>(),
405 Parameters::Get<Parameters::ActionParsingStrictness>(),
406 Parameters::Get<Parameters::InputSkipMode>(),
407 getNumThreads(),
408 Parameters::Get<Parameters::EclOutputInterval>(),
409 cmdline_params,
412 setupTime_ = externalSetupTimer.elapsed();
413 }
414 catch (const std::invalid_argument& e)
415 {
416 if (outputCout_) {
417 std::cerr << "Failed to create valid EclipseState object." << std::endl;
418 std::cerr << "Exception caught: " << e.what() << std::endl;
419 }
420#if HAVE_MPI
421 MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE);
422#endif
423 exitCode = EXIT_FAILURE;
424 return false;
425 }
426
427 exitCode = EXIT_SUCCESS;
428 return true;
429 }
430
432
433private:
434 // This function is an extreme special case, if the program has been invoked
435 // *exactly* as:
436 //
437 // flow --version
438 //
439 // the call is intercepted by this function which will print "flow $version"
440 // on stdout and exit(0).
441 void handleVersionCmdLine_(int argc, char** argv,
442 std::string_view moduleVersionName);
443
444 // This function is a special case, if the program has been invoked
445 // with the argument "--test-split-communicator=true" as the FIRST
446 // argument, it will be removed from the argument list and we set the
447 // test_split_comm_ flag to true.
448 // Note: initializing the parameter system before MPI could make this
449 // use the parameter system instead.
450 void handleTestSplitCommunicatorCmdLine_();
451
452 int runMICP(const Phases& phases)
453 {
454 if (!phases.active(Phase::WATER) || (phases.size() > 2)) {
455 if (outputCout_) {
456 std::cerr << "No valid configuration is found for MICP simulation, "
457 << "the only valid option is water + MICP\n";
458 }
459
460 return EXIT_FAILURE;
461 }
462
463 return flowMICPMain(this->argc_,
464 this->argv_,
465 this->outputCout_,
466 this->outputFiles_);
467 }
468
469 int runTwoPhase(const Phases& phases)
470 {
471 const bool diffusive = eclipseState_->getSimulationConfig().isDiffusive();
472 const bool disgasw = eclipseState_->getSimulationConfig().hasDISGASW();
473 const bool vapwat = eclipseState_->getSimulationConfig().hasVAPWAT();
474
475 // oil-gas
476 if (phases.active( Phase::OIL ) && phases.active( Phase::GAS )) {
477 if (diffusive) {
478 return flowGasOilDiffuseMain(argc_, argv_, outputCout_, outputFiles_);
479 } else {
480 return flowGasOilMain(argc_, argv_, outputCout_, outputFiles_);
481 }
482 }
483
484 // oil-water
485 else if ( phases.active( Phase::OIL ) && phases.active( Phase::WATER ) ) {
486 if (diffusive) {
487 if (outputCout_) {
488 std::cerr << "The DIFFUSE option is not available for the two-phase water/oil model." << std::endl;
489 }
490 return EXIT_FAILURE;
491 }
492 return flowOilWaterMain(argc_, argv_, outputCout_, outputFiles_);
493 }
494
495 // gas-water
496 else if ( phases.active( Phase::GAS ) && phases.active( Phase::WATER ) ) {
497 if (disgasw || vapwat) {
498 if (diffusive) {
499 return flowGasWaterDissolutionDiffuseMain(argc_, argv_, outputCout_, outputFiles_);
500 }
501 return flowGasWaterDissolutionMain(argc_, argv_, outputCout_, outputFiles_);
502 }
503 if (diffusive) {
504 if (outputCout_) {
505 std::cerr << "The DIFFUSE option is not available for the two-phase gas/water model without disgasw or vapwat." << std::endl;
506 }
507 return EXIT_FAILURE;
508 }
509
510 return flowGasWaterMain(argc_, argv_, outputCout_, outputFiles_);
511 }
512 else {
513 if (outputCout_) {
514 std::cerr << "No suitable configuration found, valid are Twophase (oilwater, oilgas and gaswater), polymer, solvent, or blackoil" << std::endl;
515 }
516
517 return EXIT_FAILURE;
518 }
519 }
520
521 int runPolymer(const Phases& phases)
522 {
523 if (! phases.active(Phase::WATER)) {
524 if (outputCout_)
525 std::cerr << "No valid configuration is found for polymer simulation, valid options include "
526 << "oilwater + polymer and blackoil + polymer" << std::endl;
527
528 return EXIT_FAILURE;
529 }
530
531 // Need to track the polymer molecular weight
532 // for the injectivity study
533 if (phases.active(Phase::POLYMW)) {
534 // only oil water two phase for now
535 assert (phases.size() == 4);
536 return flowOilWaterPolymerInjectivityMain(argc_, argv_, outputCout_, outputFiles_);
537 }
538
539 if (phases.size() == 3) { // oil water polymer case
540 return flowOilWaterPolymerMain(argc_, argv_, outputCout_, outputFiles_);
541 }
542 else {
543 return flowPolymerMain(argc_, argv_, outputCout_, outputFiles_);
544 }
545 }
546
547 int runFoam()
548 {
549 return flowFoamMain(argc_, argv_, outputCout_, outputFiles_);
550 }
551
552 int runWaterOnly(const Phases& phases)
553 {
554 if (!phases.active(Phase::WATER) || phases.size() != 1) {
555 if (outputCout_)
556 std::cerr << "No valid configuration is found for water-only simulation, valid options include "
557 << "water, water + thermal" << std::endl;
558
559 return EXIT_FAILURE;
560 }
561
562 return flowWaterOnlyMain(argc_, argv_, outputCout_, outputFiles_);
563 }
564
565 int runWaterOnlyEnergy(const Phases& phases)
566 {
567 if (!phases.active(Phase::WATER) || phases.size() != 2) {
568 if (outputCout_)
569 std::cerr << "No valid configuration is found for water-only simulation, valid options include "
570 << "water, water + thermal" << std::endl;
571
572 return EXIT_FAILURE;
573 }
574
575 return flowWaterOnlyEnergyMain(argc_, argv_, outputCout_, outputFiles_);
576 }
577
578 int runBrine(const Phases& phases)
579 {
580 if (! phases.active(Phase::WATER) || phases.size() == 2) {
581 if (outputCout_)
582 std::cerr << "No valid configuration is found for brine simulation, valid options include "
583 << "oilwater + brine, gaswater + brine and blackoil + brine" << std::endl;
584
585 return EXIT_FAILURE;
586 }
587
588 if (phases.size() == 3) {
589
590 if (phases.active(Phase::OIL)){ // oil water brine case
591 return flowOilWaterBrineMain(argc_, argv_, outputCout_, outputFiles_);
592 }
593 if (phases.active(Phase::GAS)){ // gas water brine case
594 if (eclipseState_->getSimulationConfig().hasPRECSALT() &&
595 eclipseState_->getSimulationConfig().hasVAPWAT()) {
596 //case with water vaporization into gas phase and salt precipitation
597 return flowGasWaterSaltprecVapwatMain(argc_, argv_, outputCout_, outputFiles_);
598 }
599 else {
600 return flowGasWaterBrineMain(argc_, argv_, outputCout_, outputFiles_);
601 }
602 }
603 }
604 else if (eclipseState_->getSimulationConfig().hasPRECSALT()) {
605 if (eclipseState_->getSimulationConfig().hasVAPWAT()) {
606 //case with water vaporization into gas phase and salt precipitation
607 return flowBrinePrecsaltVapwatMain(argc_, argv_, outputCout_, outputFiles_);
608 }
609 else {
610 return flowBrineSaltPrecipitationMain(argc_, argv_, outputCout_, outputFiles_);
611 }
612 }
613 else {
614 return flowBrineMain(argc_, argv_, outputCout_, outputFiles_);
615 }
616
617 return EXIT_FAILURE;
618 }
619
620 int runSolvent(const Phases& phases)
621 {
622 if (phases.active(Phase::FOAM)) {
623 return flowSolventFoamMain(argc_, argv_, outputCout_, outputFiles_);
624 }
625 // solvent + gas + water
626 if (!phases.active( Phase::OIL ) && phases.active( Phase::WATER ) && phases.active( Phase::GAS )) {
627 return flowGasWaterSolventMain(argc_, argv_, outputCout_, outputFiles_);
628 }
629
630 // solvent + gas + water + oil
631 if (phases.active( Phase::OIL ) && phases.active( Phase::WATER ) && phases.active( Phase::GAS )) {
632 return flowSolventMain(argc_, argv_, outputCout_, outputFiles_);
633 }
634
635 if (outputCout_)
636 std::cerr << "No valid configuration is found for solvent simulation, valid options include "
637 << "gas + water + solvent and gas + oil + water + solvent" << std::endl;
638
639 return EXIT_FAILURE;
640 }
641
642 int runExtendedBlackOil()
643 {
644 return flowExtboMain(argc_, argv_, outputCout_, outputFiles_);
645 }
646
647 int runThermal(const Phases& phases)
648 {
649 // oil-gas-thermal
650 if (!phases.active( Phase::WATER ) && phases.active( Phase::OIL ) && phases.active( Phase::GAS )) {
651 return flowGasOilEnergyMain(argc_, argv_, outputCout_, outputFiles_);
652 }
653
654 // water-gas-thermal
655 if (!phases.active( Phase::OIL ) && phases.active( Phase::WATER ) && phases.active( Phase::GAS )) {
656
657 if (phases.active(Phase::BRINE)){
658 return flowGasWaterSaltprecEnergyMain(argc_, argv_, outputCout_, outputFiles_);
659 }
660 return flowGasWaterEnergyMain(argc_, argv_, outputCout_, outputFiles_);
661 }
662
663 return flowEnergyMain(argc_, argv_, outputCout_, outputFiles_);
664 }
665
666 int runBlackOil()
667 {
668 const bool diffusive = eclipseState_->getSimulationConfig().isDiffusive();
669 if (diffusive) {
670 // Use the traditional linearizer, as the TpfaLinearizer does not
671 // support the diffusion module yet.
672 return flowBlackoilMain(argc_, argv_, outputCout_, outputFiles_);
673 } else {
674 return flowBlackoilTpfaMain(argc_, argv_, outputCout_, outputFiles_);
675 }
676 }
677
678 void readDeck(const std::string& deckFilename,
679 const std::string& outputDir,
680 const std::string& outputMode,
681 const bool init_from_restart_file,
682 const bool allRanksDbgPrtLog,
683 const std::string& parsingStrictness,
684 const std::string& actionParsingStrictness,
685 const std::string& inputSkipMode,
686 const std::size_t numThreads,
687 const int output_param,
688 const std::string& parameters,
689 std::string_view moduleVersion,
690 std::string_view compileTimestamp);
691
692 static int getNumThreads()
693 {
694
695 int threads;
696
697#ifdef _OPENMP
698 // This function is called before the parallel OpenMP stuff gets initialized.
699 // That initialization happens after the deck is read and we want this message.
700 // Hence we duplicate the code of setupParallelism to get the number of threads.
701 static bool first_time = true;
702 constexpr int default_threads = 2;
703 const int requested_threads = Parameters::Get<Parameters::ThreadsPerProcess>();
704 threads = requested_threads > 0 ? requested_threads : default_threads;
705
706 const char* env_var = getenv("OMP_NUM_THREADS");
707 if (env_var) {
708 int omp_num_threads = -1;
709 auto result = std::from_chars(env_var, env_var + std::strlen(env_var), omp_num_threads);
710 const bool can_output = first_time && FlowGenericVanguard::comm().rank() == 0;
711 if (result.ec == std::errc() && omp_num_threads > 0) {
712 // Set threads to omp_num_threads if it was successfully parsed and is positive
713 threads = omp_num_threads;
714 if (can_output && requested_threads > 0) {
715 std::cout << "Warning: Environment variable OMP_NUM_THREADS takes precedence over the --threads-per-process cmdline argument."
716 << std::endl;
717 }
718 } else {
719 if (can_output) {
720 std::cout << ("Warning: Invalid value for OMP_NUM_THREADS environment variable.") << std::endl;
721 }
722 }
723 }
724
725 first_time = false;
726#else
727 threads = 1;
728#endif
729 return threads;
730 }
731
732#if HAVE_DAMARIS
733 void setupDamaris(const std::string& outputDir);
734#endif
735
736protected:
737 int argc_{0};
738 char** argv_{nullptr};
739 bool outputCout_{false};
740 bool outputFiles_{false};
741
742private:
743 bool ownMPI_{true};
744 double setupTime_{0.0};
745 std::string deckFilename_{};
746 std::string flowProgName_{};
747 char *saveArgs_[3]{nullptr};
748 std::unique_ptr<UDQState> udqState_{};
749 std::unique_ptr<Action::State> actionState_{};
750 std::unique_ptr<WellTestState> wtestState_{};
751
752 // These variables may be owned by both Python and the simulator
753 std::shared_ptr<EclipseState> eclipseState_{};
754 std::shared_ptr<Schedule> schedule_{};
755 std::shared_ptr<SummaryConfig> summaryConfig_{};
756 bool mpi_init_{true};
757 bool mpi_finalize_{true};
758
759 // To demonstrate run with non_world_comm
760 bool test_split_comm_ = false;
761 bool isSimulationRank_ = true;
762#if HAVE_DAMARIS
763 bool enableDamarisOutput_ = false;
764#endif
765};
766
767} // namespace Opm
768
769#endif // OPM_MAIN_HEADER_INCLUDED
static Parallel::Communication & comm()
Obtain global communicator.
Definition: FlowGenericVanguard.hpp:306
Definition: Main.hpp:129
int argc_
Definition: Main.hpp:737
int justInitialize()
Used for test_outputdir.
Definition: Main.hpp:178
bool outputFiles_
Definition: Main.hpp:740
int runDynamic()
Definition: Main.hpp:151
Main(int argc, char **argv, bool ownMPI=true)
bool initialize_(int &exitCode)
Initialize.
Definition: Main.hpp:280
char ** argv_
Definition: Main.hpp:738
Main(const std::string &filename, bool mpi_init=true, bool mpi_finalize=true)
int runStatic()
Definition: Main.hpp:165
void setupVanguard()
void setArgvArgc_(const std::string &filename)
bool outputCout_
Definition: Main.hpp:739
void initMPI()
Main(const std::string &filename, std::shared_ptr< EclipseState > eclipseState, std::shared_ptr< Schedule > schedule, std::shared_ptr< SummaryConfig > summaryConfig, bool mpi_init=true, bool mpi_finalize=true)
void printValues(std::ostream &os)
Print values of the run-time parameters.
void reset()
Reset parameter system.
Definition: blackoilmodel.hh:72
Definition: blackoilboundaryratevector.hh:37
std::string moduleVersionName()
int flowMain(int argc, char **argv, bool outputCout, bool outputFiles)
Definition: Main.hpp:111
std::string compileTimestamp()
void printFlowBanner(int nprocs, int threads, std::string_view moduleVersionName)
std::string moduleVersion()
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type::type GetPropType
get the type alias defined in the property (equivalent to old macro GET_PROP_TYPE(....
Definition: propertysystem.hh:235
This file provides the infrastructure to retrieve run-time parameters.
The Opm property system, traits with inheritance.
std::tuple< FlowProblem > InheritsFrom
Definition: Main.hpp:97