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