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