130 Main(
int argc,
char** argv,
bool ownMPI =
true);
133 Main(
const std::string& filename);
137 Main(
const std::string& filename,
138 std::shared_ptr<EclipseState> eclipseState,
139 std::shared_ptr<Schedule> schedule,
140 std::shared_ptr<SummaryConfig> summaryConfig);
144 void setArgvArgc_(
const std::string& filename);
150 int exitCode = EXIT_SUCCESS;
151 if (initialize_<Properties::TTag::FlowEarlyBird>(exitCode)) {
152 if (isSimulationRank_) {
153 return this->dispatchDynamic_();
160 template <
class TypeTag>
163 int exitCode = EXIT_SUCCESS;
164 if (initialize_<TypeTag>(exitCode)) {
165 if (isSimulationRank_) {
166 return this->dispatchStatic_<TypeTag>();
178 std::unique_ptr<FlowMainType> initFlowBlackoil(
int& exitCode)
180 exitCode = EXIT_SUCCESS;
181 if (initialize_<Properties::TTag::FlowEarlyBird>(exitCode)) {
184 this->setupVanguard();
185 return flowBlackoilTpfaMainInit(
186 argc_, argv_, outputCout_, outputFiles_);
189 return std::unique_ptr<FlowMainType>();
196 int exitCode = EXIT_SUCCESS;
197 initialize_<Properties::TTag::FlowEarlyBird>(exitCode);
202 int dispatchDynamic_()
204 const auto& rspec = this->eclipseState_->runspec();
205 const auto& phases = rspec.phases();
207 this->setupVanguard();
213 const bool thermal = eclipseState_->getSimulationConfig().isThermal();
217 return this->runMICP(phases);
221 else if (phases.size() == 1 && phases.active(Phase::WATER) && !thermal) {
222 return this->runWaterOnly(phases);
226 else if (phases.size() == 2 && phases.active(Phase::WATER) && thermal) {
227 return this->runWaterOnlyEnergy(phases);
231 else if (phases.size() == 2 && !thermal) {
232 return this->runTwoPhase(phases);
236 else if (phases.active(Phase::POLYMER)) {
237 return this->runPolymer(phases);
241 else if (phases.active(Phase::FOAM) && !phases.active(Phase::SOLVENT)) {
242 return this->runFoam();
246 else if (phases.active(Phase::SOLVENT)) {
247 return this->runSolvent(phases);
251 else if (phases.active(Phase::BRINE) && !thermal) {
252 return this->runBrine(phases);
256 else if (phases.active(Phase::ZFRACTION)) {
257 return this->runExtendedBlackOil();
262 return this->runThermal(phases);
266 else if (phases.size() == 3) {
267 return this->runBlackOil();
272 std::cerr <<
"No suitable configuration found, valid are "
273 <<
"Twophase, polymer, foam, brine, solvent, "
274 <<
"energy, and blackoil.\n";
281 template <
class TypeTag>
282 int dispatchStatic_()
284 this->setupVanguard();
285 return flowMain<TypeTag>(argc_, argv_, outputCout_, outputFiles_);
294 template <
class TypeTagEarlyBird>
295 bool initialize_(
int& exitCode)
297 Dune::Timer externalSetupTimer;
298 externalSetupTimer.start();
312 typedef TypeTagEarlyBird PreTypeTag;
313 using PreProblem = GetPropType<PreTypeTag, Properties::Problem>;
315 PreProblem::setBriefDescription(
"Flow, an advanced reservoir simulator for ECL-decks provided by the Open Porous Media project.");
323 MPI_Abort(MPI_COMM_WORLD, status);
325 exitCode = (status > 0) ? status : EXIT_SUCCESS;
329 std::string deckFilename;
330 std::string outputDir;
331 if ( eclipseState_ ) {
332 deckFilename = eclipseState_->getIOConfig().fullBasePath();
333 outputDir = eclipseState_->getIOConfig().getOutputDir();
336 deckFilename = Parameters::get<PreTypeTag, Properties::EclDeckFileName>();
337 outputDir = Parameters::get<PreTypeTag, Properties::OutputDir>();
341 enableDamarisOutput_ = Parameters::get<PreTypeTag, Properties::EnableDamarisOutput>();
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 ;
351 if (enableDamarisOutput_) {
353 auto damarisOutputDir = outputDir;
354 if (outputDir.empty()) {
355 auto odir = std::filesystem::path{deckFilename}.parent_path();
357 damarisOutputDir =
".";
359 damarisOutputDir = odir.generic_string();
363 this->setupDamaris(damarisOutputDir);
369 if (!isSimulationRank_) {
370 exitCode = EXIT_SUCCESS;
377 outputCout_ = Parameters::get<PreTypeTag, Properties::EnableTerminalOutput>();
379 if (deckFilename.empty()) {
381 std::cerr <<
"No input case given. Try '--help' for a usage description.\n";
383 exitCode = EXIT_FAILURE;
387 using PreVanguard = GetPropType<PreTypeTag, Properties::Vanguard>;
389 deckFilename = PreVanguard::canonicalDeckPath(deckFilename);
391 catch (
const std::exception& e) {
392 if ( mpiRank == 0 ) {
393 std::cerr <<
"Exception received: " << e.what() <<
". Try '--help' for a usage description.\n";
396 MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE);
398 exitCode = EXIT_FAILURE;
402 std::string cmdline_params;
405 getNumThreads<PreTypeTag>(),
407 std::ostringstream str;
408 Parameters::printValues<PreTypeTag>(str);
409 cmdline_params = str.str();
414 this->readDeck(deckFilename,
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>(),
425 setupTime_ = externalSetupTimer.elapsed();
427 catch (
const std::invalid_argument& e)
430 std::cerr <<
"Failed to create valid EclipseState object." << std::endl;
431 std::cerr <<
"Exception caught: " << e.what() << std::endl;
434 MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE);
436 exitCode = EXIT_FAILURE;
440 exitCode = EXIT_SUCCESS;
451 void handleVersionCmdLine_(
int argc,
char** argv,
460 void handleTestSplitCommunicatorCmdLine_();
462 int runMICP(
const Phases& phases)
464 if (!phases.active(Phase::WATER) || (phases.size() > 2)) {
466 std::cerr <<
"No valid configuration is found for MICP simulation, "
467 <<
"the only valid option is water + MICP\n";
473 return flowMICPMain(this->argc_,
479 int runTwoPhase(
const Phases& phases)
481 const bool diffusive = eclipseState_->getSimulationConfig().isDiffusive();
482 const bool disgasw = eclipseState_->getSimulationConfig().hasDISGASW();
483 const bool vapwat = eclipseState_->getSimulationConfig().hasVAPWAT();
486 if (phases.active( Phase::OIL ) && phases.active( Phase::GAS )) {
488 return flowGasOilDiffuseMain(argc_, argv_, outputCout_, outputFiles_);
490 return flowGasOilMain(argc_, argv_, outputCout_, outputFiles_);
495 else if ( phases.active( Phase::OIL ) && phases.active( Phase::WATER ) ) {
498 std::cerr <<
"The DIFFUSE option is not available for the two-phase water/oil model." << std::endl;
502 return flowOilWaterMain(argc_, argv_, outputCout_, outputFiles_);
506 else if ( phases.active( Phase::GAS ) && phases.active( Phase::WATER ) ) {
507 if (disgasw || vapwat) {
509 return flowGasWaterDissolutionDiffuseMain(argc_, argv_, outputCout_, outputFiles_);
511 return flowGasWaterDissolutionMain(argc_, argv_, outputCout_, outputFiles_);
515 std::cerr <<
"The DIFFUSE option is not available for the two-phase gas/water model without disgasw or vapwat." << std::endl;
520 return flowGasWaterMain(argc_, argv_, outputCout_, outputFiles_);
524 std::cerr <<
"No suitable configuration found, valid are Twophase (oilwater, oilgas and gaswater), polymer, solvent, or blackoil" << std::endl;
531 int runPolymer(
const Phases& phases)
533 if (! phases.active(Phase::WATER)) {
535 std::cerr <<
"No valid configuration is found for polymer simulation, valid options include "
536 <<
"oilwater + polymer and blackoil + polymer" << std::endl;
543 if (phases.active(Phase::POLYMW)) {
545 assert (phases.size() == 4);
546 return flowOilWaterPolymerInjectivityMain(argc_, argv_, outputCout_, outputFiles_);
549 if (phases.size() == 3) {
550 return flowOilWaterPolymerMain(argc_, argv_, outputCout_, outputFiles_);
553 return flowPolymerMain(argc_, argv_, outputCout_, outputFiles_);
559 return flowFoamMain(argc_, argv_, outputCout_, outputFiles_);
562 int runWaterOnly(
const Phases& phases)
564 if (!phases.active(Phase::WATER) || phases.size() != 1) {
566 std::cerr <<
"No valid configuration is found for water-only simulation, valid options include "
567 <<
"water, water + thermal" << std::endl;
572 return flowWaterOnlyMain(argc_, argv_, outputCout_, outputFiles_);
575 int runWaterOnlyEnergy(
const Phases& phases)
577 if (!phases.active(Phase::WATER) || phases.size() != 2) {
579 std::cerr <<
"No valid configuration is found for water-only simulation, valid options include "
580 <<
"water, water + thermal" << std::endl;
585 return flowWaterOnlyEnergyMain(argc_, argv_, outputCout_, outputFiles_);
588 int runBrine(
const Phases& phases)
590 if (! phases.active(Phase::WATER) || phases.size() == 2) {
592 std::cerr <<
"No valid configuration is found for brine simulation, valid options include "
593 <<
"oilwater + brine, gaswater + brine and blackoil + brine" << std::endl;
598 if (phases.size() == 3) {
600 if (phases.active(Phase::OIL)){
601 return flowOilWaterBrineMain(argc_, argv_, outputCout_, outputFiles_);
603 if (phases.active(Phase::GAS)){
604 if (eclipseState_->getSimulationConfig().hasPRECSALT() &&
605 eclipseState_->getSimulationConfig().hasVAPWAT()) {
607 return flowGasWaterSaltprecVapwatMain(argc_, argv_, outputCout_, outputFiles_);
610 return flowGasWaterBrineMain(argc_, argv_, outputCout_, outputFiles_);
614 else if (eclipseState_->getSimulationConfig().hasPRECSALT()) {
615 if (eclipseState_->getSimulationConfig().hasVAPWAT()) {
617 return flowBrinePrecsaltVapwatMain(argc_, argv_, outputCout_, outputFiles_);
620 return flowBrineSaltPrecipitationMain(argc_, argv_, outputCout_, outputFiles_);
624 return flowBrineMain(argc_, argv_, outputCout_, outputFiles_);
630 int runSolvent(
const Phases& phases)
632 if (phases.active(Phase::FOAM)) {
633 return flowSolventFoamMain(argc_, argv_, outputCout_, outputFiles_);
636 if (!phases.active( Phase::OIL ) && phases.active( Phase::WATER ) && phases.active( Phase::GAS )) {
637 return flowGasWaterSolventMain(argc_, argv_, outputCout_, outputFiles_);
641 if (phases.active( Phase::OIL ) && phases.active( Phase::WATER ) && phases.active( Phase::GAS )) {
642 return flowSolventMain(argc_, argv_, outputCout_, outputFiles_);
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;
652 int runExtendedBlackOil()
654 return flowExtboMain(argc_, argv_, outputCout_, outputFiles_);
657 int runThermal(
const Phases& phases)
660 if (!phases.active( Phase::WATER ) && phases.active( Phase::OIL ) && phases.active( Phase::GAS )) {
661 return flowGasOilEnergyMain(argc_, argv_, outputCout_, outputFiles_);
665 if (!phases.active( Phase::OIL ) && phases.active( Phase::WATER ) && phases.active( Phase::GAS )) {
667 if (phases.active(Phase::BRINE)){
668 return flowGasWaterSaltprecEnergyMain(argc_, argv_, outputCout_, outputFiles_);
670 return flowGasWaterEnergyMain(argc_, argv_, outputCout_, outputFiles_);
673 return flowEnergyMain(argc_, argv_, outputCout_, outputFiles_);
678 const bool diffusive = eclipseState_->getSimulationConfig().isDiffusive();
682 return flowBlackoilMain(argc_, argv_, outputCout_, outputFiles_);
684 return flowBlackoilTpfaMain(argc_, argv_, outputCout_, outputFiles_);
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,
700 void setupVanguard();
702 template<
class TypeTag>
703 static int getNumThreads()
712 if (std::getenv(
"OMP_NUM_THREADS")) {
713 threads = omp_get_max_threads();
718 const int input_threads = Parameters::get<TypeTag, Properties::ThreadsPerProcess>();
720 if (input_threads > 0)
721 threads = input_threads;
731 void setupDamaris(
const std::string& outputDir);
735 char** argv_{
nullptr};
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_{};
748 std::shared_ptr<EclipseState> eclipseState_{};
749 std::shared_ptr<Schedule> schedule_{};
750 std::shared_ptr<SummaryConfig> summaryConfig_{};
753 bool test_split_comm_ =
false;
754 bool isSimulationRank_ =
true;
756 bool enableDamarisOutput_ =
false;