diff --git a/CMakeLists.txt b/CMakeLists.txt index 391579832..b9885bb4e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -422,8 +422,10 @@ add_dependencies(moduleVersion opmsimulators) set(FLOW_MODELS blackoil brine energy extbo foam gasoil gaswater oilwater oilwater_brine gaswater_brine oilwater_polymer oilwater_polymer_injectivity micp polymer solvent - gasoil_energy brine_saltprecipitation gaswater_saltprec_vapwat brine_precsalt_vapwat) -set(FLOW_VARIANT_MODELS brine_energy onephase onephase_energy blackoil_tpfa) + gasoil_energy brine_saltprecipitation + gaswater_saltprec_vapwat brine_precsalt_vapwat + blackoil_tpfa gasoildiffuse) +set(FLOW_VARIANT_MODELS brine_energy onephase onephase_energy) set(FLOW_TGTS) foreach(OBJ ${COMMON_MODELS} ${FLOW_MODELS} ${FLOW_VARIANT_MODELS}) diff --git a/ebos/eclequilinitializer.hh b/ebos/eclequilinitializer.hh index d3a7156f9..f7fb08ab3 100644 --- a/ebos/eclequilinitializer.hh +++ b/ebos/eclequilinitializer.hh @@ -73,6 +73,7 @@ class EclEquilInitializer enum { dimWorld = GridView::dimensionworld }; enum { enableTemperature = getPropValue() }; enum { enableEnergy = getPropValue() }; + enum { enableDissolution = Indices::compositionSwitchIdx >= 0 }; enum { enableBrine = getPropValue() }; enum { enableEvaporation = getPropValue() }; enum { enableSaltPrecipitation = getPropValue() }; @@ -84,7 +85,7 @@ public: FluidSystem, enableTemperature, enableEnergy, - Indices::gasEnabled, + enableDissolution, enableEvaporation, enableBrine, enableSaltPrecipitation, diff --git a/flow/flow_ebos_gasoil.cpp b/flow/flow_ebos_gasoil.cpp index 618ad3ec8..793f5d2cb 100644 --- a/flow/flow_ebos_gasoil.cpp +++ b/flow/flow_ebos_gasoil.cpp @@ -25,6 +25,9 @@ #include #include +#include +#include + namespace Opm { namespace Properties { namespace TTag { @@ -33,6 +36,15 @@ struct EclFlowGasOilProblem { }; } +template +struct Linearizer { using type = TpfaLinearizer; }; + +template +struct LocalResidual { using type = BlackOilLocalResidualTPFA; }; + +template +struct EnableDiffusion { static constexpr bool value = false; }; + //! The indices required by the model template struct Indices diff --git a/flow/flow_ebos_gasoildiffuse.cpp b/flow/flow_ebos_gasoildiffuse.cpp new file mode 100644 index 000000000..5c7a2255f --- /dev/null +++ b/flow/flow_ebos_gasoildiffuse.cpp @@ -0,0 +1,85 @@ +/* + This file is part of the Open Porous Media project (OPM). + + OPM is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OPM is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OPM. If not, see . +*/ +#include "config.h" + +#include + +#include +#include + +#include +#include +#include + +namespace Opm { +namespace Properties { +namespace TTag { +struct EclFlowGasOilDiffuseProblem { + using InheritsFrom = std::tuple; +}; +} + + +template +struct EnableDiffusion { static constexpr bool value = true; }; + +//! The indices required by the model +template +struct Indices +{ +private: + // it is unfortunately not possible to simply use 'TypeTag' here because this leads + // to cyclic definitions of some properties. if this happens the compiler error + // messages unfortunately are *really* confusing and not really helpful. + using BaseTypeTag = TTag::EclFlowProblem; + using FluidSystem = GetPropType; + +public: + typedef BlackOilTwoPhaseIndices(), + getPropValue(), + getPropValue(), + getPropValue(), + getPropValue(), + getPropValue(), + /*PVOffset=*/0, + /*disabledCompIdx=*/FluidSystem::waterCompIdx, + getPropValue()> type; +}; +}} + +namespace Opm { + +// ----------------- Main program ----------------- +int flowEbosGasOilDiffuseMain(int argc, char** argv, bool outputCout, bool outputFiles) +{ + // we always want to use the default locale, and thus spare us the trouble + // with incorrect locale settings. + resetLocale(); + + FlowMainEbos + mainfunc {argc, argv, outputCout, outputFiles} ; + return mainfunc.execute(); +} + +int flowEbosGasOilDiffuseMainStandalone(int argc, char** argv) +{ + using TypeTag = Properties::TTag::EclFlowGasOilDiffuseProblem; + auto mainObject = Opm::Main(argc, argv); + return mainObject.runStatic(); +} + +} diff --git a/flow/flow_ebos_gasoildiffuse.hpp b/flow/flow_ebos_gasoildiffuse.hpp new file mode 100644 index 000000000..c770eec20 --- /dev/null +++ b/flow/flow_ebos_gasoildiffuse.hpp @@ -0,0 +1,30 @@ +/* + This file is part of the Open Porous Media project (OPM). + + OPM is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OPM is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OPM. If not, see . +*/ +#ifndef FLOW_EBOS_GASOILDIFFUSE_HPP +#define FLOW_EBOS_GASOILDIFFUSE_HPP + +namespace Opm { + +//! \brief Main function used in flow binary. +int flowEbosGasOilDiffuseMain(int argc, char** argv, bool outputCout, bool outputFiles); + +//! \brief Main function used in flow_gasoil binary. +int flowEbosGasOilDiffuseMainStandalone(int argc, char** argv); + +} + +#endif // FLOW_EBOS_GASOILDIFFUSE_HPP diff --git a/flow/flow_ebos_gaswater.cpp b/flow/flow_ebos_gaswater.cpp index f5491c805..66dd2e07e 100644 --- a/flow/flow_ebos_gaswater.cpp +++ b/flow/flow_ebos_gaswater.cpp @@ -28,6 +28,9 @@ #include #include +#include +#include + namespace Opm { namespace Properties { namespace TTag { @@ -36,6 +39,15 @@ struct EclFlowGasWaterProblem { }; } +template +struct Linearizer { using type = TpfaLinearizer; }; + +template +struct LocalResidual { using type = BlackOilLocalResidualTPFA; }; + +template +struct EnableDiffusion { static constexpr bool value = false; }; + //! The indices required by the model template struct Indices diff --git a/flow/flow_ebos_oilwater.cpp b/flow/flow_ebos_oilwater.cpp index 4d8605a68..9b5d5f083 100644 --- a/flow/flow_ebos_oilwater.cpp +++ b/flow/flow_ebos_oilwater.cpp @@ -25,6 +25,9 @@ #include #include +#include +#include + namespace Opm { namespace Properties { namespace TTag { @@ -33,6 +36,18 @@ struct EclFlowOilWaterProblem { }; } + + +template +struct Linearizer { using type = TpfaLinearizer; }; + +template +struct LocalResidual { using type = BlackOilLocalResidualTPFA; }; + +template +struct EnableDiffusion { static constexpr bool value = false; }; + + //! The indices required by the model template struct Indices diff --git a/flow/flow_ebos_onephase.cpp b/flow/flow_ebos_onephase.cpp index 3419793b5..4243a6502 100644 --- a/flow/flow_ebos_onephase.cpp +++ b/flow/flow_ebos_onephase.cpp @@ -22,6 +22,8 @@ #include #include +#include +#include namespace Opm { namespace Properties { @@ -31,6 +33,16 @@ struct EclFlowProblemWaterOnly { using InheritsFrom = std::tuple; }; } + +template +struct Linearizer { using type = TpfaLinearizer; }; + +template +struct LocalResidual { using type = BlackOilLocalResidualTPFA; }; + +template +struct EnableDiffusion { static constexpr bool value = false; }; + //! The indices required by the model template struct Indices diff --git a/flow/flow_gasoildiffuse.cpp b/flow/flow_gasoildiffuse.cpp new file mode 100644 index 000000000..5e819958f --- /dev/null +++ b/flow/flow_gasoildiffuse.cpp @@ -0,0 +1,24 @@ +/* + This file is part of the Open Porous Media project (OPM). + + OPM is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OPM is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OPM. If not, see . +*/ +#include "config.h" +#include + + +int main(int argc, char** argv) +{ + return Opm::flowEbosGasOilDiffuseMainStandalone(argc, argv); +} diff --git a/opm/simulators/flow/Main.hpp b/opm/simulators/flow/Main.hpp index 43c51f9c4..bc93127ee 100644 --- a/opm/simulators/flow/Main.hpp +++ b/opm/simulators/flow/Main.hpp @@ -23,8 +23,10 @@ #define OPM_MAIN_HEADER_INCLUDED #include +#include #include +#include #include #include #include @@ -117,9 +119,6 @@ int flowEbosMain(int argc, char** argv, bool outputCout, bool outputFiles) // usage scenarios, we refactored the original run() in flow.cpp into this class. class Main { -private: - using FlowMainEbosType = FlowMainEbos; - public: Main(int argc, char** argv) : argc_(argc), argv_(argv) { initMPI(); } @@ -236,6 +235,7 @@ public: return exitCode; } + using FlowMainEbosType = FlowMainEbos; // To be called from the Python interface code. Only do the // initialization and then return a pointer to the FlowEbosMain // object that can later be accessed directly from the Python interface @@ -282,6 +282,7 @@ private: // // TODO: make sure that no illegal combinations like thermal and // twophase are requested. + const bool thermal = eclipseState_->getSimulationConfig().isThermal(); // Single-phase case if (rspec.micp()) { @@ -289,17 +290,17 @@ private: } // water-only case - else if(phases.size() == 1 && phases.active(Phase::WATER) && !eclipseState_->getSimulationConfig().isThermal()) { + else if(phases.size() == 1 && phases.active(Phase::WATER) && !thermal) { return this->runWaterOnly(phases); } // water-only case with energy - else if(phases.size() == 2 && phases.active(Phase::WATER) && eclipseState_->getSimulationConfig().isThermal()) { + else if(phases.size() == 2 && phases.active(Phase::WATER) && thermal) { return this->runWaterOnlyEnergy(phases); } // Twophase cases - else if (phases.size() == 2 && !eclipseState_->getSimulationConfig().isThermal()) { + else if (phases.size() == 2 && !thermal) { return this->runTwoPhase(phases); } @@ -329,7 +330,7 @@ private: } // Energy case - else if (eclipseState_->getSimulationConfig().isThermal()) { + else if (thermal) { return this->runThermal(phases); } @@ -593,18 +594,36 @@ private: int runTwoPhase(const Phases& phases) { + const bool diffusive = eclipseState_->getSimulationConfig().isDiffusive(); + // oil-gas if (phases.active( Phase::OIL ) && phases.active( Phase::GAS )) { - return flowEbosGasOilMain(argc_, argv_, outputCout_, outputFiles_); + if (diffusive) { + return flowEbosGasOilDiffuseMain(argc_, argv_, outputCout_, outputFiles_); + } else { + return flowEbosGasOilMain(argc_, argv_, outputCout_, outputFiles_); + } } // oil-water else if ( phases.active( Phase::OIL ) && phases.active( Phase::WATER ) ) { + if (diffusive) { + if (outputCout_) { + std::cerr << "The DIFFUSE option is not available for the two-phase water/oil model." << std::endl; + } + return EXIT_FAILURE; + } return flowEbosOilWaterMain(argc_, argv_, outputCout_, outputFiles_); } // gas-water else if ( phases.active( Phase::GAS ) && phases.active( Phase::WATER ) ) { + if (diffusive) { + if (outputCout_) { + std::cerr << "The DIFFUSE option is not available for the two-phase gas/water model." << std::endl; + } + return EXIT_FAILURE; + } return flowEbosGasWaterMain(argc_, argv_, outputCout_, outputFiles_); } else { @@ -737,7 +756,14 @@ private: int runBlackOil() { - return flowEbosBlackoilMain(argc_, argv_, outputCout_, outputFiles_); + const bool diffusive = eclipseState_->getSimulationConfig().isDiffusive(); + if (diffusive) { + // Use the traditional linearizer, as the TpfaLinearizer does not + // support the diffusion module yet. + return flowEbosBlackoilMain(argc_, argv_, outputCout_, outputFiles_); + } else { + return flowEbosBlackoilTpfaMain(argc_, argv_, outputCout_, outputFiles_); + } } int argc_{0};