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>
66#include <dune/fem/misc/mpimanager.hh>
68#include <dune/common/parallel/mpihelper.hh>
105namespace Action {
class State; }
110template <
class TypeTag>
111int flowMain(
int argc,
char** argv,
bool outputCout,
bool outputFiles)
117 FlowMain<TypeTag> mainfunc(argc, argv, outputCout, outputFiles);
118 return mainfunc.execute();
131 Main(
int argc,
char** argv,
bool ownMPI =
true);
134 Main(
const std::string& filename,
bool mpi_init =
true,
bool mpi_finalize =
true);
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);
153 int exitCode = EXIT_SUCCESS;
154 if (initialize_<Properties::TTag::FlowEarlyBird>(exitCode)) {
156 if (isSimulationRank_) {
157 return this->dispatchDynamic_();
164 template <
class TypeTag>
167 int exitCode = EXIT_SUCCESS;
168 if (initialize_<TypeTag>(exitCode)) {
169 if (isSimulationRank_) {
170 return this->dispatchStatic_<TypeTag>();
180 int exitCode = EXIT_SUCCESS;
181 initialize_<Properties::TTag::FlowEarlyBird>(exitCode);
186 int dispatchDynamic_()
188 const auto& rspec = this->eclipseState_->runspec();
189 const auto& phases = rspec.phases();
197 const bool thermal = eclipseState_->getSimulationConfig().isThermal();
201 return this->runMICP(phases);
205 else if (phases.size() == 1 && phases.active(Phase::WATER) && !thermal) {
206 return this->runWaterOnly(phases);
210 else if (phases.size() == 2 && phases.active(Phase::WATER) && thermal) {
211 return this->runWaterOnlyEnergy(phases);
215 else if (phases.size() == 2 && !thermal) {
216 return this->runTwoPhase(phases);
220 else if (phases.active(Phase::POLYMER)) {
221 return this->runPolymer(phases);
225 else if (phases.active(Phase::FOAM) && !phases.active(Phase::SOLVENT)) {
226 return this->runFoam();
230 else if (phases.active(Phase::SOLVENT)) {
231 return this->runSolvent(phases);
235 else if (phases.active(Phase::BRINE) && !thermal) {
236 return this->runBrine(phases);
240 else if (phases.active(Phase::ZFRACTION)) {
241 return this->runExtendedBlackOil();
246 return this->runThermal(phases);
250 else if (phases.size() == 3) {
251 return this->runBlackOil();
256 std::cerr <<
"No suitable configuration found, valid are "
257 <<
"Twophase, polymer, foam, brine, solvent, "
258 <<
"energy, and blackoil.\n";
265 template <
class TypeTag>
266 int dispatchStatic_()
279 template <
class TypeTagEarlyBird>
282 Dune::Timer externalSetupTimer;
283 externalSetupTimer.start();
297 typedef TypeTagEarlyBird PreTypeTag;
300 PreProblem::setBriefDescription(
"Flow, an advanced reservoir simulator for ECL-decks provided by the Open Porous Media project.");
308 MPI_Abort(MPI_COMM_WORLD, status);
310 exitCode = (status > 0) ? status : EXIT_SUCCESS;
314 std::string deckFilename;
315 std::string outputDir;
316 if ( eclipseState_ ) {
317 deckFilename = eclipseState_->getIOConfig().fullBasePath();
318 outputDir = eclipseState_->getIOConfig().getOutputDir();
321 deckFilename = Parameters::Get<Parameters::EclDeckFileName>();
322 outputDir = Parameters::Get<Parameters::OutputDir>();
326 enableDamarisOutput_ = Parameters::Get<Parameters::EnableDamarisOutput>();
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 ;
336 if (enableDamarisOutput_) {
338 auto damarisOutputDir = outputDir;
339 if (outputDir.empty()) {
340 auto odir = std::filesystem::path{deckFilename}.parent_path();
342 damarisOutputDir =
".";
344 damarisOutputDir = odir.generic_string();
348 this->setupDamaris(damarisOutputDir);
354 if (!isSimulationRank_) {
355 exitCode = EXIT_SUCCESS;
362 outputCout_ = Parameters::Get<Parameters::EnableTerminalOutput>();
364 if (deckFilename.empty()) {
366 std::cerr <<
"No input case given. Try '--help' for a usage description.\n";
368 exitCode = EXIT_FAILURE;
374 deckFilename = PreVanguard::canonicalDeckPath(deckFilename);
376 catch (
const std::exception& e) {
377 if ( mpiRank == 0 ) {
378 std::cerr <<
"Exception received: " << e.what() <<
". Try '--help' for a usage description.\n";
381 MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE);
383 exitCode = EXIT_FAILURE;
387 std::string cmdline_params;
392 std::ostringstream str;
394 cmdline_params = str.str();
399 this->readDeck(deckFilename,
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>(),
408 Parameters::Get<Parameters::EclOutputInterval>(),
412 setupTime_ = externalSetupTimer.elapsed();
414 catch (
const std::invalid_argument& e)
417 std::cerr <<
"Failed to create valid EclipseState object." << std::endl;
418 std::cerr <<
"Exception caught: " << e.what() << std::endl;
421 MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE);
423 exitCode = EXIT_FAILURE;
427 exitCode = EXIT_SUCCESS;
441 void handleVersionCmdLine_(
int argc,
char** argv,
450 void handleTestSplitCommunicatorCmdLine_();
452 int runMICP(
const Phases& phases)
454 if (!phases.active(Phase::WATER) || (phases.size() > 2)) {
456 std::cerr <<
"No valid configuration is found for MICP simulation, "
457 <<
"the only valid option is water + MICP\n";
463 return flowMICPMain(this->
argc_,
469 int runTwoPhase(
const Phases& phases)
471 const bool diffusive = eclipseState_->getSimulationConfig().isDiffusive();
472 const bool disgasw = eclipseState_->getSimulationConfig().hasDISGASW();
473 const bool vapwat = eclipseState_->getSimulationConfig().hasVAPWAT();
476 if (phases.active( Phase::OIL ) && phases.active( Phase::GAS )) {
485 else if ( phases.active( Phase::OIL ) && phases.active( Phase::WATER ) ) {
488 std::cerr <<
"The DIFFUSE option is not available for the two-phase water/oil model." << std::endl;
496 else if ( phases.active( Phase::GAS ) && phases.active( Phase::WATER ) ) {
497 if (disgasw || vapwat) {
505 std::cerr <<
"The DIFFUSE option is not available for the two-phase gas/water model without disgasw or vapwat." << std::endl;
514 std::cerr <<
"No suitable configuration found, valid are Twophase (oilwater, oilgas and gaswater), polymer, solvent, or blackoil" << std::endl;
521 int runPolymer(
const Phases& phases)
523 if (! phases.active(Phase::WATER)) {
525 std::cerr <<
"No valid configuration is found for polymer simulation, valid options include "
526 <<
"oilwater + polymer and blackoil + polymer" << std::endl;
533 if (phases.active(Phase::POLYMW)) {
535 assert (phases.size() == 4);
539 if (phases.size() == 3) {
552 int runWaterOnly(
const Phases& phases)
554 if (!phases.active(Phase::WATER) || phases.size() != 1) {
556 std::cerr <<
"No valid configuration is found for water-only simulation, valid options include "
557 <<
"water, water + thermal" << std::endl;
565 int runWaterOnlyEnergy(
const Phases& phases)
567 if (!phases.active(Phase::WATER) || phases.size() != 2) {
569 std::cerr <<
"No valid configuration is found for water-only simulation, valid options include "
570 <<
"water, water + thermal" << std::endl;
578 int runBrine(
const Phases& phases)
580 if (! phases.active(Phase::WATER) || phases.size() == 2) {
582 std::cerr <<
"No valid configuration is found for brine simulation, valid options include "
583 <<
"oilwater + brine, gaswater + brine and blackoil + brine" << std::endl;
588 if (phases.size() == 3) {
590 if (phases.active(Phase::OIL)){
593 if (phases.active(Phase::GAS)){
594 if (eclipseState_->getSimulationConfig().hasPRECSALT() &&
595 eclipseState_->getSimulationConfig().hasVAPWAT()) {
604 else if (eclipseState_->getSimulationConfig().hasPRECSALT()) {
605 if (eclipseState_->getSimulationConfig().hasVAPWAT()) {
620 int runSolvent(
const Phases& phases)
622 if (phases.active(Phase::FOAM)) {
626 if (!phases.active( Phase::OIL ) && phases.active( Phase::WATER ) && phases.active( Phase::GAS )) {
631 if (phases.active( Phase::OIL ) && phases.active( Phase::WATER ) && phases.active( Phase::GAS )) {
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;
642 int runExtendedBlackOil()
647 int runThermal(
const Phases& phases)
650 if (!phases.active( Phase::WATER ) && phases.active( Phase::OIL ) && phases.active( Phase::GAS )) {
655 if (!phases.active( Phase::OIL ) && phases.active( Phase::WATER ) && phases.active( Phase::GAS )) {
657 if (phases.active(Phase::BRINE)){
668 const bool diffusive = eclipseState_->getSimulationConfig().isDiffusive();
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,
692 static int getNumThreads()
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;
706 const char* env_var = getenv(
"OMP_NUM_THREADS");
708 int omp_num_threads = -1;
709 auto result = std::from_chars(env_var, env_var + std::strlen(env_var), omp_num_threads);
711 if (result.ec == std::errc() && omp_num_threads > 0) {
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."
720 std::cout << (
"Warning: Invalid value for OMP_NUM_THREADS environment variable.") << std::endl;
733 void setupDamaris(
const std::string& outputDir);
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_{};
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};
760 bool test_split_comm_ =
false;
761 bool isSimulationRank_ =
true;
763 bool enableDamarisOutput_ =
false;
static Parallel::Communication & comm()
Obtain global communicator.
Definition: FlowGenericVanguard.hpp:306
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 setArgvArgc_(const std::string &filename)
bool outputCout_
Definition: Main.hpp:739
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