23#ifndef OPM_MAIN_HEADER_INCLUDED
24#define OPM_MAIN_HEADER_INCLUDED
26#include <flow/flow_blackoil.hpp>
27#include <flow/flow_blackoil_legacyassembly.hpp>
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>
57#include <opm/input/eclipse/EclipseState/EclipseState.hpp>
59#include <opm/models/utils/propertysystem.hh>
60#include <opm/models/utils/parametersystem.hh>
66#include <dune/fem/misc/mpimanager.hh>
68#include <dune/common/parallel/mpihelper.hh>
104namespace Action {
class State; }
109template <
class TypeTag>
110int flowMain(
int argc,
char** argv,
bool outputCout,
bool outputFiles)
130 Main(
int argc,
char** argv,
bool ownMPI =
true);
133 Main(
const std::string& filename,
bool mpi_init =
true,
bool mpi_finalize =
true);
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);
152 int exitCode = EXIT_SUCCESS;
153 if (initialize_<Properties::TTag::FlowEarlyBird>(exitCode)) {
154 if (isSimulationRank_) {
155 return this->dispatchDynamic_();
162 template <
class TypeTag>
165 int exitCode = EXIT_SUCCESS;
166 if (initialize_<TypeTag>(exitCode)) {
167 if (isSimulationRank_) {
168 return this->dispatchStatic_<TypeTag>();
182 exitCode = EXIT_SUCCESS;
183 if (initialize_<Properties::TTag::FlowEarlyBird>(exitCode)) {
186 this->setupVanguard();
187 return flowBlackoilTpfaMainInit(
188 argc_, argv_, outputCout_, outputFiles_);
191 return std::unique_ptr<FlowMainType>();
198 int exitCode = EXIT_SUCCESS;
199 initialize_<Properties::TTag::FlowEarlyBird>(exitCode);
204 int dispatchDynamic_()
206 const auto& rspec = this->eclipseState_->runspec();
207 const auto& phases = rspec.phases();
209 this->setupVanguard();
215 const bool thermal = eclipseState_->getSimulationConfig().isThermal();
219 return this->runMICP(phases);
223 else if (phases.size() == 1 && phases.active(Phase::WATER) && !thermal) {
224 return this->runWaterOnly(phases);
228 else if (phases.size() == 2 && phases.active(Phase::WATER) && thermal) {
229 return this->runWaterOnlyEnergy(phases);
233 else if (phases.size() == 2 && !thermal) {
234 return this->runTwoPhase(phases);
238 else if (phases.active(Phase::POLYMER)) {
239 return this->runPolymer(phases);
243 else if (phases.active(Phase::FOAM) && !phases.active(Phase::SOLVENT)) {
244 return this->runFoam();
248 else if (phases.active(Phase::SOLVENT)) {
249 return this->runSolvent(phases);
253 else if (phases.active(Phase::BRINE) && !thermal) {
254 return this->runBrine(phases);
258 else if (phases.active(Phase::ZFRACTION)) {
259 return this->runExtendedBlackOil();
264 return this->runThermal(phases);
268 else if (phases.size() == 3) {
269 return this->runBlackOil();
274 std::cerr <<
"No suitable configuration found, valid are "
275 <<
"Twophase, polymer, foam, brine, solvent, "
276 <<
"energy, and blackoil.\n";
283 template <
class TypeTag>
284 int dispatchStatic_()
286 this->setupVanguard();
287 return flowMain<TypeTag>(argc_, argv_, outputCout_, outputFiles_);
296 template <
class TypeTagEarlyBird>
297 bool initialize_(
int& exitCode)
299 Dune::Timer externalSetupTimer;
300 externalSetupTimer.start();
314 typedef TypeTagEarlyBird PreTypeTag;
315 using PreProblem = GetPropType<PreTypeTag, Properties::Problem>;
317 PreProblem::setBriefDescription(
"Flow, an advanced reservoir simulator for ECL-decks provided by the Open Porous Media project.");
325 MPI_Abort(MPI_COMM_WORLD, status);
327 exitCode = (status > 0) ? status : EXIT_SUCCESS;
331 std::string deckFilename;
332 std::string outputDir;
333 if ( eclipseState_ ) {
334 deckFilename = eclipseState_->getIOConfig().fullBasePath();
335 outputDir = eclipseState_->getIOConfig().getOutputDir();
338 deckFilename = Parameters::get<PreTypeTag, Properties::EclDeckFileName>();
339 outputDir = Parameters::get<PreTypeTag, Properties::OutputDir>();
343 enableDamarisOutput_ = Parameters::get<PreTypeTag, Properties::EnableDamarisOutput>();
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 ;
353 if (enableDamarisOutput_) {
355 auto damarisOutputDir = outputDir;
356 if (outputDir.empty()) {
357 auto odir = std::filesystem::path{deckFilename}.parent_path();
359 damarisOutputDir =
".";
361 damarisOutputDir = odir.generic_string();
365 this->setupDamaris(damarisOutputDir);
371 if (!isSimulationRank_) {
372 exitCode = EXIT_SUCCESS;
379 outputCout_ = Parameters::get<PreTypeTag, Properties::EnableTerminalOutput>();
381 if (deckFilename.empty()) {
383 std::cerr <<
"No input case given. Try '--help' for a usage description.\n";
385 exitCode = EXIT_FAILURE;
389 using PreVanguard = GetPropType<PreTypeTag, Properties::Vanguard>;
391 deckFilename = PreVanguard::canonicalDeckPath(deckFilename);
393 catch (
const std::exception& e) {
394 if ( mpiRank == 0 ) {
395 std::cerr <<
"Exception received: " << e.what() <<
". Try '--help' for a usage description.\n";
398 MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE);
400 exitCode = EXIT_FAILURE;
404 std::string cmdline_params;
407 getNumThreads<PreTypeTag>(),
409 std::ostringstream str;
410 Parameters::printValues<PreTypeTag>(str);
411 cmdline_params = str.str();
416 this->readDeck(deckFilename,
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>(),
427 setupTime_ = externalSetupTimer.elapsed();
429 catch (
const std::invalid_argument& e)
432 std::cerr <<
"Failed to create valid EclipseState object." << std::endl;
433 std::cerr <<
"Exception caught: " << e.what() << std::endl;
436 MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE);
438 exitCode = EXIT_FAILURE;
442 exitCode = EXIT_SUCCESS;
453 void handleVersionCmdLine_(
int argc,
char** argv,
462 void handleTestSplitCommunicatorCmdLine_();
464 int runMICP(
const Phases& phases)
466 if (!phases.active(Phase::WATER) || (phases.size() > 2)) {
468 std::cerr <<
"No valid configuration is found for MICP simulation, "
469 <<
"the only valid option is water + MICP\n";
475 return flowMICPMain(this->argc_,
481 int runTwoPhase(
const Phases& phases)
483 const bool diffusive = eclipseState_->getSimulationConfig().isDiffusive();
484 const bool disgasw = eclipseState_->getSimulationConfig().hasDISGASW();
485 const bool vapwat = eclipseState_->getSimulationConfig().hasVAPWAT();
488 if (phases.active( Phase::OIL ) && phases.active( Phase::GAS )) {
490 return flowGasOilDiffuseMain(argc_, argv_, outputCout_, outputFiles_);
492 return flowGasOilMain(argc_, argv_, outputCout_, outputFiles_);
497 else if ( phases.active( Phase::OIL ) && phases.active( Phase::WATER ) ) {
500 std::cerr <<
"The DIFFUSE option is not available for the two-phase water/oil model." << std::endl;
504 return flowOilWaterMain(argc_, argv_, outputCout_, outputFiles_);
508 else if ( phases.active( Phase::GAS ) && phases.active( Phase::WATER ) ) {
509 if (disgasw || vapwat) {
511 return flowGasWaterDissolutionDiffuseMain(argc_, argv_, outputCout_, outputFiles_);
513 return flowGasWaterDissolutionMain(argc_, argv_, outputCout_, outputFiles_);
517 std::cerr <<
"The DIFFUSE option is not available for the two-phase gas/water model without disgasw or vapwat." << std::endl;
522 return flowGasWaterMain(argc_, argv_, outputCout_, outputFiles_);
526 std::cerr <<
"No suitable configuration found, valid are Twophase (oilwater, oilgas and gaswater), polymer, solvent, or blackoil" << std::endl;
533 int runPolymer(
const Phases& phases)
535 if (! phases.active(Phase::WATER)) {
537 std::cerr <<
"No valid configuration is found for polymer simulation, valid options include "
538 <<
"oilwater + polymer and blackoil + polymer" << std::endl;
545 if (phases.active(Phase::POLYMW)) {
547 assert (phases.size() == 4);
548 return flowOilWaterPolymerInjectivityMain(argc_, argv_, outputCout_, outputFiles_);
551 if (phases.size() == 3) {
552 return flowOilWaterPolymerMain(argc_, argv_, outputCout_, outputFiles_);
555 return flowPolymerMain(argc_, argv_, outputCout_, outputFiles_);
561 return flowFoamMain(argc_, argv_, outputCout_, outputFiles_);
564 int runWaterOnly(
const Phases& phases)
566 if (!phases.active(Phase::WATER) || phases.size() != 1) {
568 std::cerr <<
"No valid configuration is found for water-only simulation, valid options include "
569 <<
"water, water + thermal" << std::endl;
574 return flowWaterOnlyMain(argc_, argv_, outputCout_, outputFiles_);
577 int runWaterOnlyEnergy(
const Phases& phases)
579 if (!phases.active(Phase::WATER) || phases.size() != 2) {
581 std::cerr <<
"No valid configuration is found for water-only simulation, valid options include "
582 <<
"water, water + thermal" << std::endl;
587 return flowWaterOnlyEnergyMain(argc_, argv_, outputCout_, outputFiles_);
590 int runBrine(
const Phases& phases)
592 if (! phases.active(Phase::WATER) || phases.size() == 2) {
594 std::cerr <<
"No valid configuration is found for brine simulation, valid options include "
595 <<
"oilwater + brine, gaswater + brine and blackoil + brine" << std::endl;
600 if (phases.size() == 3) {
602 if (phases.active(Phase::OIL)){
603 return flowOilWaterBrineMain(argc_, argv_, outputCout_, outputFiles_);
605 if (phases.active(Phase::GAS)){
606 if (eclipseState_->getSimulationConfig().hasPRECSALT() &&
607 eclipseState_->getSimulationConfig().hasVAPWAT()) {
609 return flowGasWaterSaltprecVapwatMain(argc_, argv_, outputCout_, outputFiles_);
612 return flowGasWaterBrineMain(argc_, argv_, outputCout_, outputFiles_);
616 else if (eclipseState_->getSimulationConfig().hasPRECSALT()) {
617 if (eclipseState_->getSimulationConfig().hasVAPWAT()) {
619 return flowBrinePrecsaltVapwatMain(argc_, argv_, outputCout_, outputFiles_);
622 return flowBrineSaltPrecipitationMain(argc_, argv_, outputCout_, outputFiles_);
626 return flowBrineMain(argc_, argv_, outputCout_, outputFiles_);
632 int runSolvent(
const Phases& phases)
634 if (phases.active(Phase::FOAM)) {
635 return flowSolventFoamMain(argc_, argv_, outputCout_, outputFiles_);
638 if (!phases.active( Phase::OIL ) && phases.active( Phase::WATER ) && phases.active( Phase::GAS )) {
639 return flowGasWaterSolventMain(argc_, argv_, outputCout_, outputFiles_);
643 if (phases.active( Phase::OIL ) && phases.active( Phase::WATER ) && phases.active( Phase::GAS )) {
644 return flowSolventMain(argc_, argv_, outputCout_, outputFiles_);
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;
654 int runExtendedBlackOil()
656 return flowExtboMain(argc_, argv_, outputCout_, outputFiles_);
659 int runThermal(
const Phases& phases)
662 if (!phases.active( Phase::WATER ) && phases.active( Phase::OIL ) && phases.active( Phase::GAS )) {
663 return flowGasOilEnergyMain(argc_, argv_, outputCout_, outputFiles_);
667 if (!phases.active( Phase::OIL ) && phases.active( Phase::WATER ) && phases.active( Phase::GAS )) {
669 if (phases.active(Phase::BRINE)){
670 return flowGasWaterSaltprecEnergyMain(argc_, argv_, outputCout_, outputFiles_);
672 return flowGasWaterEnergyMain(argc_, argv_, outputCout_, outputFiles_);
675 return flowEnergyMain(argc_, argv_, outputCout_, outputFiles_);
680 const bool diffusive = eclipseState_->getSimulationConfig().isDiffusive();
684 return flowBlackoilMain(argc_, argv_, outputCout_, outputFiles_);
686 return flowBlackoilTpfaMain(argc_, argv_, outputCout_, outputFiles_);
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,
702 void setupVanguard();
704 template<
class TypeTag>
705 static int getNumThreads()
714 if (std::getenv(
"OMP_NUM_THREADS")) {
715 threads = omp_get_max_threads();
720 const int input_threads = Parameters::get<TypeTag, Properties::ThreadsPerProcess>();
722 if (input_threads > 0)
723 threads = input_threads;
733 void setupDamaris(
const std::string& outputDir);
737 char** argv_{
nullptr};
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_{};
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};
757 bool test_split_comm_ =
false;
758 bool isSimulationRank_ =
true;
760 bool enableDamarisOutput_ =
false;
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
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)
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