Merge pull request #3590 from daavid00/micp-2021-10

micp
This commit is contained in:
Tor Harald Sandve 2021-10-14 22:28:28 +02:00 committed by GitHub
commit 70c9d2e237
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
47 changed files with 749 additions and 126 deletions

View File

@ -345,7 +345,7 @@ set_property(TARGET moduleVersion PROPERTY POSITION_INDEPENDENT_CODE ON)
add_dependencies(moduleVersion opmsimulators) add_dependencies(moduleVersion opmsimulators)
set(COMMON_MODELS brine energy extbo foam gasoil gaswater oilwater oilwater_polymer polymer solvent) set(COMMON_MODELS brine energy extbo foam gasoil gaswater oilwater oilwater_polymer polymer solvent)
set(FLOW_MODELS blackoil oilwater_brine oilwater_polymer_injectivity) set(FLOW_MODELS blackoil oilwater_brine oilwater_polymer_injectivity micp)
set(FLOW_TGTS) set(FLOW_TGTS)
foreach(OBJ ${COMMON_MODELS} ${FLOW_MODELS}) foreach(OBJ ${COMMON_MODELS} ${FLOW_MODELS})

View File

@ -44,6 +44,8 @@ list (APPEND MAIN_SOURCE_FILES
opm/simulators/linalg/FlexibleSolver2.cpp opm/simulators/linalg/FlexibleSolver2.cpp
opm/simulators/linalg/FlexibleSolver3.cpp opm/simulators/linalg/FlexibleSolver3.cpp
opm/simulators/linalg/FlexibleSolver4.cpp opm/simulators/linalg/FlexibleSolver4.cpp
opm/simulators/linalg/FlexibleSolver5.cpp
opm/simulators/linalg/FlexibleSolver6.cpp
opm/simulators/linalg/PropertyTree.cpp opm/simulators/linalg/PropertyTree.cpp
opm/simulators/linalg/setupPropertyTree.cpp opm/simulators/linalg/setupPropertyTree.cpp
opm/simulators/utils/PartiallySupportedFlowKeywords.cpp opm/simulators/utils/PartiallySupportedFlowKeywords.cpp

View File

@ -57,7 +57,8 @@ public:
getPropValue<TypeTag, Properties::EnableFoam>(), getPropValue<TypeTag, Properties::EnableFoam>(),
getPropValue<TypeTag, Properties::EnableBrine>(), getPropValue<TypeTag, Properties::EnableBrine>(),
/*PVOffset=*/0, /*PVOffset=*/0,
/*disabledCompIdx=*/FluidSystem::waterCompIdx> type; /*disabledCompIdx=*/FluidSystem::waterCompIdx,
getPropValue<TypeTag, Properties::EnableMICP>()> type;
}; };
} // namespace Opm::Properties } // namespace Opm::Properties

View File

@ -60,7 +60,8 @@ public:
getPropValue<TypeTag, Properties::EnableFoam>(), getPropValue<TypeTag, Properties::EnableFoam>(),
getPropValue<TypeTag, Properties::EnableBrine>(), getPropValue<TypeTag, Properties::EnableBrine>(),
/*PVOffset=*/0, /*PVOffset=*/0,
/*disabledCompIdx=*/FluidSystem::oilCompIdx> type; /*disabledCompIdx=*/FluidSystem::oilCompIdx,
getPropValue<TypeTag, Properties::EnableMICP>()> type;
}; };
} // namespace Opm::Properties } // namespace Opm::Properties

View File

@ -56,7 +56,8 @@ public:
getPropValue<TypeTag, Properties::EnableFoam>(), getPropValue<TypeTag, Properties::EnableFoam>(),
getPropValue<TypeTag, Properties::EnableBrine>(), getPropValue<TypeTag, Properties::EnableBrine>(),
/*PVOffset=*/0, /*PVOffset=*/0,
/*disabledCompIdx=*/FluidSystem::gasCompIdx> type; /*disabledCompIdx=*/FluidSystem::gasCompIdx,
getPropValue<TypeTag, Properties::EnableMICP>()> type;
}; };
} // namespace Opm::Properties } // namespace Opm::Properties

View File

@ -61,7 +61,8 @@ public:
getPropValue<TypeTag, Properties::EnableFoam>(), getPropValue<TypeTag, Properties::EnableFoam>(),
getPropValue<TypeTag, Properties::EnableBrine>(), getPropValue<TypeTag, Properties::EnableBrine>(),
/*PVOffset=*/0, /*PVOffset=*/0,
/*disabledCompIdx=*/FluidSystem::gasCompIdx> type; /*disabledCompIdx=*/FluidSystem::gasCompIdx,
getPropValue<TypeTag, Properties::EnableMICP>()> type;
}; };
} // namespace Opm::Properties } // namespace Opm::Properties

View File

@ -2,20 +2,16 @@
// vi: set et ts=4 sw=4 sts=4: // vi: set et ts=4 sw=4 sts=4:
/* /*
This file is part of the Open Porous Media project (OPM). This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or the Free Software Foundation, either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
OPM is distributed in the hope that it will be useful, OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>. along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of module for the precise wording of the license and the list of
copyright holders. copyright holders.
@ -79,7 +75,8 @@ EclGenericOutputBlackoilModule(const EclipseState& eclState,
bool enablePolymer, bool enablePolymer,
bool enableFoam, bool enableFoam,
bool enableBrine, bool enableBrine,
bool enableExtbo) bool enableExtbo,
bool enableMICP)
: eclState_(eclState) : eclState_(eclState)
, schedule_(schedule) , schedule_(schedule)
, summaryConfig_(summaryConfig) , summaryConfig_(summaryConfig)
@ -91,6 +88,7 @@ EclGenericOutputBlackoilModule(const EclipseState& eclState,
, enableFoam_(enableFoam) , enableFoam_(enableFoam)
, enableBrine_(enableBrine) , enableBrine_(enableBrine)
, enableExtbo_(enableExtbo) , enableExtbo_(enableExtbo)
, enableMICP_(enableMICP)
{ {
const auto& fp = eclState_.fieldProps(); const auto& fp = eclState_.fieldProps();
@ -592,15 +590,19 @@ assignToSolution(data::Solution& sol)
{"1OVERBG", UnitSystem::measure::gas_inverse_formation_volume_factor, data::TargetType::RESTART_AUXILIARY, invB_[gasPhaseIdx]}, {"1OVERBG", UnitSystem::measure::gas_inverse_formation_volume_factor, data::TargetType::RESTART_AUXILIARY, invB_[gasPhaseIdx]},
{"1OVERBO", UnitSystem::measure::oil_inverse_formation_volume_factor, data::TargetType::RESTART_AUXILIARY, invB_[oilPhaseIdx]}, {"1OVERBO", UnitSystem::measure::oil_inverse_formation_volume_factor, data::TargetType::RESTART_AUXILIARY, invB_[oilPhaseIdx]},
{"1OVERBW", UnitSystem::measure::water_inverse_formation_volume_factor, data::TargetType::RESTART_AUXILIARY, invB_[waterPhaseIdx]}, {"1OVERBW", UnitSystem::measure::water_inverse_formation_volume_factor, data::TargetType::RESTART_AUXILIARY, invB_[waterPhaseIdx]},
{"BIOFILM", UnitSystem::measure::identity, data::TargetType::RESTART_SOLUTION, cBiofilm_},
{"CALCITE", UnitSystem::measure::identity, data::TargetType::RESTART_SOLUTION, cCalcite_},
{"FOAM", UnitSystem::measure::identity, data::TargetType::RESTART_SOLUTION, cFoam_}, {"FOAM", UnitSystem::measure::identity, data::TargetType::RESTART_SOLUTION, cFoam_},
{"GASKR", UnitSystem::measure::identity, data::TargetType::RESTART_AUXILIARY, relativePermeability_[gasPhaseIdx]}, {"GASKR", UnitSystem::measure::identity, data::TargetType::RESTART_AUXILIARY, relativePermeability_[gasPhaseIdx]},
{"GAS_DEN", UnitSystem::measure::density, data::TargetType::RESTART_AUXILIARY, density_[gasPhaseIdx]}, {"GAS_DEN", UnitSystem::measure::density, data::TargetType::RESTART_AUXILIARY, density_[gasPhaseIdx]},
{"GAS_VISC", UnitSystem::measure::viscosity, data::TargetType::RESTART_AUXILIARY, viscosity_[gasPhaseIdx]}, {"GAS_VISC", UnitSystem::measure::viscosity, data::TargetType::RESTART_AUXILIARY, viscosity_[gasPhaseIdx]},
{"KRNSW_GO", UnitSystem::measure::identity, data::TargetType::RESTART_AUXILIARY, krnSwMdcGo_}, {"KRNSW_GO", UnitSystem::measure::identity, data::TargetType::RESTART_AUXILIARY, krnSwMdcGo_},
{"KRNSW_OW", UnitSystem::measure::identity, data::TargetType::RESTART_AUXILIARY, krnSwMdcOw_}, {"KRNSW_OW", UnitSystem::measure::identity, data::TargetType::RESTART_AUXILIARY, krnSwMdcOw_},
{"MICROBES", UnitSystem::measure::density, data::TargetType::RESTART_SOLUTION, cMicrobes_},
{"OILKR", UnitSystem::measure::identity, data::TargetType::RESTART_AUXILIARY, relativePermeability_[oilPhaseIdx]}, {"OILKR", UnitSystem::measure::identity, data::TargetType::RESTART_AUXILIARY, relativePermeability_[oilPhaseIdx]},
{"OIL_DEN", UnitSystem::measure::density, data::TargetType::RESTART_AUXILIARY, density_[oilPhaseIdx]}, {"OIL_DEN", UnitSystem::measure::density, data::TargetType::RESTART_AUXILIARY, density_[oilPhaseIdx]},
{"OIL_VISC", UnitSystem::measure::viscosity, data::TargetType::RESTART_AUXILIARY, viscosity_[oilPhaseIdx]}, {"OIL_VISC", UnitSystem::measure::viscosity, data::TargetType::RESTART_AUXILIARY, viscosity_[oilPhaseIdx]},
{"OXYGEN", UnitSystem::measure::density, data::TargetType::RESTART_SOLUTION, cOxygen_},
{"PBUB", UnitSystem::measure::identity, data::TargetType::RESTART_AUXILIARY, bubblePointPressure_}, {"PBUB", UnitSystem::measure::identity, data::TargetType::RESTART_AUXILIARY, bubblePointPressure_},
{"PCSWM_GO", UnitSystem::measure::identity, data::TargetType::RESTART_AUXILIARY, pcSwMdcGo_}, {"PCSWM_GO", UnitSystem::measure::identity, data::TargetType::RESTART_AUXILIARY, pcSwMdcGo_},
{"PCSWM_OW", UnitSystem::measure::identity, data::TargetType::RESTART_AUXILIARY, pcSwMdcOw_}, {"PCSWM_OW", UnitSystem::measure::identity, data::TargetType::RESTART_AUXILIARY, pcSwMdcOw_},
@ -625,6 +627,7 @@ assignToSolution(data::Solution& sol)
{"STD_GAS", UnitSystem::measure::identity, data::TargetType::RESTART_SOLUTION, mFracGas_}, {"STD_GAS", UnitSystem::measure::identity, data::TargetType::RESTART_SOLUTION, mFracGas_},
{"STD_OIL", UnitSystem::measure::identity, data::TargetType::RESTART_SOLUTION, mFracOil_}, {"STD_OIL", UnitSystem::measure::identity, data::TargetType::RESTART_SOLUTION, mFracOil_},
{"SWMAX", UnitSystem::measure::identity, data::TargetType::RESTART_SOLUTION, swMax_}, {"SWMAX", UnitSystem::measure::identity, data::TargetType::RESTART_SOLUTION, swMax_},
{"UREA", UnitSystem::measure::density, data::TargetType::RESTART_SOLUTION, cUrea_},
{"TMULT_RC", UnitSystem::measure::identity, data::TargetType::RESTART_SOLUTION, rockCompTransMultiplier_}, {"TMULT_RC", UnitSystem::measure::identity, data::TargetType::RESTART_SOLUTION, rockCompTransMultiplier_},
{"WATKR", UnitSystem::measure::identity, data::TargetType::RESTART_AUXILIARY, relativePermeability_[waterPhaseIdx]}, {"WATKR", UnitSystem::measure::identity, data::TargetType::RESTART_AUXILIARY, relativePermeability_[waterPhaseIdx]},
{"WAT_DEN", UnitSystem::measure::density, data::TargetType::RESTART_AUXILIARY, density_[waterPhaseIdx]}, {"WAT_DEN", UnitSystem::measure::density, data::TargetType::RESTART_AUXILIARY, density_[waterPhaseIdx]},
@ -734,6 +737,16 @@ setRestart(const data::Solution& sol,
krnSwMdcGo_[elemIdx] = sol.data("KRNSW_GO")[globalDofIndex]; krnSwMdcGo_[elemIdx] = sol.data("KRNSW_GO")[globalDofIndex];
if (!ppcw_.empty() && sol.has("PPCW")) if (!ppcw_.empty() && sol.has("PPCW"))
ppcw_[elemIdx] = sol.data("PPCW")[globalDofIndex]; ppcw_[elemIdx] = sol.data("PPCW")[globalDofIndex];
if (!cMicrobes_.empty() && sol.has("MICROBES"))
cMicrobes_[elemIdx] = sol.data("MICROBES")[globalDofIndex];
if (!cOxygen_.empty() && sol.has("OXYGEN"))
cOxygen_[elemIdx] = sol.data("OXYGEN")[globalDofIndex];
if (!cUrea_.empty() && sol.has("UREA"))
cUrea_[elemIdx] = sol.data("UREA")[globalDofIndex];
if (!cBiofilm_.empty() && sol.has("BIOFILM"))
cBiofilm_[elemIdx] = sol.data("BIOFILM")[globalDofIndex];
if (!cCalcite_.empty() && sol.has("CALCITE"))
cCalcite_[elemIdx] = sol.data("CALCITE")[globalDofIndex];
} }
template<class FluidSystem,class Scalar> template<class FluidSystem,class Scalar>
@ -913,6 +926,13 @@ doAllocBuffers(unsigned bufferSize,
mFracGas_.resize(bufferSize, 0.0); mFracGas_.resize(bufferSize, 0.0);
mFracCo2_.resize(bufferSize, 0.0); mFracCo2_.resize(bufferSize, 0.0);
} }
if (enableMICP_){
cMicrobes_.resize(bufferSize, 0.0);
cOxygen_.resize(bufferSize, 0.0);
cUrea_.resize(bufferSize, 0.0);
cBiofilm_.resize(bufferSize, 0.0);
cCalcite_.resize(bufferSize, 0.0);
}
if (vapparsActive) if (vapparsActive)
soMax_.resize(bufferSize, 0.0); soMax_.resize(bufferSize, 0.0);

View File

@ -2,20 +2,16 @@
// vi: set et ts=4 sw=4 sts=4: // vi: set et ts=4 sw=4 sts=4:
/* /*
This file is part of the Open Porous Media project (OPM). This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or the Free Software Foundation, either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
OPM is distributed in the hope that it will be useful, OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>. along with OPM. If not, see <http://www.gnu.org/licenses/>.
Consult the COPYING file in the top-level source directory of this Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of module for the precise wording of the license and the list of
copyright holders. copyright holders.
@ -132,6 +128,46 @@ public:
return 0; return 0;
} }
Scalar getMicrobialConcentration(unsigned elemIdx) const
{
if (cMicrobes_.size() > elemIdx)
return cMicrobes_[elemIdx];
return 0;
}
Scalar getOxygenConcentration(unsigned elemIdx) const
{
if (cOxygen_.size() > elemIdx)
return cOxygen_[elemIdx];
return 0;
}
Scalar getUreaConcentration(unsigned elemIdx) const
{
if (cUrea_.size() > elemIdx)
return cUrea_[elemIdx];
return 0;
}
Scalar getBiofilmConcentration(unsigned elemIdx) const
{
if (cBiofilm_.size() > elemIdx)
return cBiofilm_[elemIdx];
return 0;
}
Scalar getCalciteConcentration(unsigned elemIdx) const
{
if (cCalcite_.size() > elemIdx)
return cCalcite_[elemIdx];
return 0;
}
const std::map<std::size_t, double>& getWBPData() const const std::map<std::size_t, double>& getWBPData() const
{ {
return this->wbpData_; return this->wbpData_;
@ -168,7 +204,8 @@ protected:
bool enablePolymer, bool enablePolymer,
bool enableFoam, bool enableFoam,
bool enableBrine, bool enableBrine,
bool enableExtbo); bool enableExtbo,
bool enableMICP);
struct WellProdDataType struct WellProdDataType
{ {
@ -324,6 +361,7 @@ protected:
bool enableFoam_; bool enableFoam_;
bool enableBrine_; bool enableBrine_;
bool enableExtbo_; bool enableExtbo_;
bool enableMICP_;
bool forceDisableFipOutput_; bool forceDisableFipOutput_;
bool forceDisableFipresvOutput_; bool forceDisableFipresvOutput_;
@ -376,6 +414,11 @@ protected:
ScalarBuffer minimumOilPressure_; ScalarBuffer minimumOilPressure_;
ScalarBuffer saturatedOilFormationVolumeFactor_; ScalarBuffer saturatedOilFormationVolumeFactor_;
ScalarBuffer rockCompTransMultiplier_; ScalarBuffer rockCompTransMultiplier_;
ScalarBuffer cMicrobes_;
ScalarBuffer cOxygen_;
ScalarBuffer cUrea_;
ScalarBuffer cBiofilm_;
ScalarBuffer cCalcite_;
std::array<ScalarBuffer, numPhases> saturation_; std::array<ScalarBuffer, numPhases> saturation_;
std::array<ScalarBuffer, numPhases> invB_; std::array<ScalarBuffer, numPhases> invB_;

View File

@ -407,7 +407,8 @@ checkDeckCompatibility_(const Deck& deck,
int numPhases, int numPhases,
bool indicesGasEnabled, bool indicesGasEnabled,
bool indicesOilEnabled, bool indicesOilEnabled,
bool indicesWaterEnabled) const bool indicesWaterEnabled,
bool enableMICP) const
{ {
if (enableApiTracking) if (enableApiTracking)
throw std::logic_error("API tracking is not yet implemented but requested at compile time."); throw std::logic_error("API tracking is not yet implemented but requested at compile time.");
@ -424,6 +425,11 @@ checkDeckCompatibility_(const Deck& deck,
else if (!enablePolymer && deck.hasKeyword("POLYMER")) else if (!enablePolymer && deck.hasKeyword("POLYMER"))
throw std::runtime_error("The deck enables the polymer option, but the simulator is compiled without it."); throw std::runtime_error("The deck enables the polymer option, but the simulator is compiled without it.");
if (enableMICP && !deck.hasKeyword("MICP"))
throw std::runtime_error("The simulator requires the MICP option to be enabled, but the deck does not.");
else if (!enableMICP && deck.hasKeyword("MICP"))
throw std::runtime_error("The deck enables the MICP option, but the simulator is compiled without it.");
if (enableExtbo && !deck.hasKeyword("PVTSOL")) if (enableExtbo && !deck.hasKeyword("PVTSOL"))
throw std::runtime_error("The simulator requires the extendedBO option to be enabled, but the deck does not."); throw std::runtime_error("The simulator requires the extendedBO option to be enabled, but the deck does not.");
else if (!enableExtbo && deck.hasKeyword("PVTSOL")) else if (!enableExtbo && deck.hasKeyword("PVTSOL"))
@ -476,7 +482,8 @@ void EclGenericProblem<GridView,FluidSystem,Scalar>::
readBlackoilExtentionsInitialConditions_(size_t numDof, readBlackoilExtentionsInitialConditions_(size_t numDof,
bool enableSolvent, bool enableSolvent,
bool enablePolymer, bool enablePolymer,
bool enablePolymerMolarWeight) bool enablePolymerMolarWeight,
bool enableMICP)
{ {
if (enableSolvent) { if (enableSolvent) {
if (eclState_.fieldProps().has_double("SSOL")) if (eclState_.fieldProps().has_double("SSOL"))
@ -498,6 +505,29 @@ readBlackoilExtentionsInitialConditions_(size_t numDof,
else else
polymerMoleWeight_.resize(numDof, 0.0); polymerMoleWeight_.resize(numDof, 0.0);
} }
if (enableMICP) {
if (eclState_.fieldProps().has_double("SMICR"))
microbialConcentration_ = eclState_.fieldProps().get_double("SMICR");
else
microbialConcentration_.resize(numDof, 0.0);
if (eclState_.fieldProps().has_double("SOXYG"))
oxygenConcentration_ = eclState_.fieldProps().get_double("SOXYG");
else
oxygenConcentration_.resize(numDof, 0.0);
if (eclState_.fieldProps().has_double("SUREA"))
ureaConcentration_ = eclState_.fieldProps().get_double("SUREA");
else
ureaConcentration_.resize(numDof, 0.0);
if (eclState_.fieldProps().has_double("SBIOF"))
biofilmConcentration_ = eclState_.fieldProps().get_double("SBIOF");
else
biofilmConcentration_.resize(numDof, 0.0);
if (eclState_.fieldProps().has_double("SCALC"))
calciteConcentration_ = eclState_.fieldProps().get_double("SCALC");
else
calciteConcentration_.resize(numDof, 0.0);
}
} }
@ -561,6 +591,56 @@ polymerMolecularWeight(const unsigned elemIdx) const
return polymerMoleWeight_[elemIdx]; return polymerMoleWeight_[elemIdx];
} }
template<class GridView, class FluidSystem, class Scalar>
Scalar EclGenericProblem<GridView,FluidSystem,Scalar>::
microbialConcentration(unsigned elemIdx) const
{
if (microbialConcentration_.empty())
return 0;
return microbialConcentration_[elemIdx];
}
template<class GridView, class FluidSystem, class Scalar>
Scalar EclGenericProblem<GridView,FluidSystem,Scalar>::
oxygenConcentration(unsigned elemIdx) const
{
if (oxygenConcentration_.empty())
return 0;
return oxygenConcentration_[elemIdx];
}
template<class GridView, class FluidSystem, class Scalar>
Scalar EclGenericProblem<GridView,FluidSystem,Scalar>::
ureaConcentration(unsigned elemIdx) const
{
if (ureaConcentration_.empty())
return 0;
return ureaConcentration_[elemIdx];
}
template<class GridView, class FluidSystem, class Scalar>
Scalar EclGenericProblem<GridView,FluidSystem,Scalar>::
biofilmConcentration(unsigned elemIdx) const
{
if (biofilmConcentration_.empty())
return 0;
return biofilmConcentration_[elemIdx];
}
template<class GridView, class FluidSystem, class Scalar>
Scalar EclGenericProblem<GridView,FluidSystem,Scalar>::
calciteConcentration(unsigned elemIdx) const
{
if (calciteConcentration_.empty())
return 0;
return calciteConcentration_[elemIdx];
}
template<class GridView, class FluidSystem, class Scalar> template<class GridView, class FluidSystem, class Scalar>
unsigned EclGenericProblem<GridView,FluidSystem,Scalar>:: unsigned EclGenericProblem<GridView,FluidSystem,Scalar>::
pvtRegionIndex(unsigned elemIdx) const pvtRegionIndex(unsigned elemIdx) const

View File

@ -145,6 +145,31 @@ public:
// TODO: remove this function if not called // TODO: remove this function if not called
Scalar polymerMolecularWeight(const unsigned elemIdx) const; Scalar polymerMolecularWeight(const unsigned elemIdx) const;
/*!
* \brief Returns the initial microbial concentration for a given a cell index
*/
Scalar microbialConcentration(unsigned elemIdx) const;
/*!
* \brief Returns the initial oxygen concentration for a given a cell index
*/
Scalar oxygenConcentration(unsigned elemIdx) const;
/*!
* \brief Returns the initial urea concentration for a given a cell index
*/
Scalar ureaConcentration(unsigned elemIdx) const;
/*!
* \brief Returns the initial biofilm concentration for a given a cell index
*/
Scalar biofilmConcentration(unsigned elemIdx) const;
/*!
* \brief Returns the initial calcite concentration for a given a cell index
*/
Scalar calciteConcentration(unsigned elemIdx) const;
/*! /*!
* \brief Returns the index the relevant PVT region given a cell index * \brief Returns the index the relevant PVT region given a cell index
*/ */
@ -231,7 +256,8 @@ protected:
int numPhases, int numPhases,
bool indicesGasEnabled, bool indicesGasEnabled,
bool indicesOilEnabled, bool indicesOilEnabled,
bool indicesWaterEnabled) const; bool indicesWaterEnabled,
bool enableMICP) const;
void readRockParameters_(const std::vector<Scalar>& cellCenterDepths); void readRockParameters_(const std::vector<Scalar>& cellCenterDepths);
@ -240,7 +266,8 @@ protected:
void readBlackoilExtentionsInitialConditions_(size_t numDof, void readBlackoilExtentionsInitialConditions_(size_t numDof,
bool enableSolvent, bool enableSolvent,
bool enablePolymer, bool enablePolymer,
bool enablePolymerMolarWeight); bool enablePolymerMolarWeight,
bool enableMICP);
void updatePvtnum_(); void updatePvtnum_();
void updateSatnum_(); void updateSatnum_();
@ -274,6 +301,11 @@ protected:
std::vector<Scalar> polymerConcentration_; std::vector<Scalar> polymerConcentration_;
std::vector<Scalar> polymerMoleWeight_; // polymer molecular weight std::vector<Scalar> polymerMoleWeight_; // polymer molecular weight
std::vector<Scalar> solventSaturation_; std::vector<Scalar> solventSaturation_;
std::vector<Scalar> microbialConcentration_;
std::vector<Scalar> oxygenConcentration_;
std::vector<Scalar> ureaConcentration_;
std::vector<Scalar> biofilmConcentration_;
std::vector<Scalar> calciteConcentration_;
std::vector<Scalar> lastRv_; std::vector<Scalar> lastRv_;
std::vector<Scalar> maxDRv_; std::vector<Scalar> maxDRv_;

View File

@ -135,7 +135,8 @@ public:
getPropValue<TypeTag, Properties::EnablePolymer>(), getPropValue<TypeTag, Properties::EnablePolymer>(),
getPropValue<TypeTag, Properties::EnableFoam>(), getPropValue<TypeTag, Properties::EnableFoam>(),
getPropValue<TypeTag, Properties::EnableBrine>(), getPropValue<TypeTag, Properties::EnableBrine>(),
getPropValue<TypeTag, Properties::EnableExtbo>()) getPropValue<TypeTag, Properties::EnableExtbo>(),
getPropValue<TypeTag, Properties::EnableMICP>())
, simulator_(simulator) , simulator_(simulator)
{ {
const SummaryConfig summaryConfig = simulator_.vanguard().summaryConfig(); const SummaryConfig summaryConfig = simulator_.vanguard().summaryConfig();
@ -359,6 +360,26 @@ public:
this->mFracCo2_[globalDofIdx] = stdVolCo2*rhoCO2/stdMassTotal; this->mFracCo2_[globalDofIdx] = stdVolCo2*rhoCO2/stdMassTotal;
} }
if (!this->cMicrobes_.empty()) {
this->cMicrobes_[globalDofIdx] = intQuants.microbialConcentration().value();
}
if (!this->cOxygen_.empty()) {
this->cOxygen_[globalDofIdx] = intQuants.oxygenConcentration().value();
}
if (!this->cUrea_.empty()) {
this->cUrea_[globalDofIdx] = 10 * intQuants.ureaConcentration().value(); //Reescaling back the urea concentration (see WellInterface_impl.hpp)
}
if (!this->cBiofilm_.empty()) {
this->cBiofilm_[globalDofIdx] = intQuants.biofilmConcentration().value();
}
if (!this->cCalcite_.empty()) {
this->cCalcite_[globalDofIdx] = intQuants.calciteConcentration().value();
}
if (!this->bubblePointPressure_.empty()) { if (!this->bubblePointPressure_.empty()) {
try { try {
this->bubblePointPressure_[globalDofIdx] = getValue(FluidSystem::bubblePointPressure(fs, intQuants.pvtRegionIndex())); this->bubblePointPressure_[globalDofIdx] = getValue(FluidSystem::bubblePointPressure(fs, intQuants.pvtRegionIndex()));

View File

@ -539,6 +539,10 @@ template<class TypeTag>
struct EnableExtbo<TypeTag, TTag::EclBaseProblem> { struct EnableExtbo<TypeTag, TTag::EclBaseProblem> {
static constexpr bool value = false; static constexpr bool value = false;
}; };
template<class TypeTag>
struct EnableMICP<TypeTag, TTag::EclBaseProblem> {
static constexpr bool value = false;
};
// disable thermal flux boundaries by default // disable thermal flux boundaries by default
template<class TypeTag> template<class TypeTag>
@ -627,6 +631,7 @@ class EclProblem : public GetPropType<TypeTag, Properties::BaseProblem>
enum { enableDiffusion = getPropValue<TypeTag, Properties::EnableDiffusion>() }; enum { enableDiffusion = getPropValue<TypeTag, Properties::EnableDiffusion>() };
enum { enableThermalFluxBoundaries = getPropValue<TypeTag, Properties::EnableThermalFluxBoundaries>() }; enum { enableThermalFluxBoundaries = getPropValue<TypeTag, Properties::EnableThermalFluxBoundaries>() };
enum { enableApiTracking = getPropValue<TypeTag, Properties::EnableApiTracking>() }; enum { enableApiTracking = getPropValue<TypeTag, Properties::EnableApiTracking>() };
enum { enableMICP = getPropValue<TypeTag, Properties::EnableMICP>() };
enum { gasPhaseIdx = FluidSystem::gasPhaseIdx }; enum { gasPhaseIdx = FluidSystem::gasPhaseIdx };
enum { oilPhaseIdx = FluidSystem::oilPhaseIdx }; enum { oilPhaseIdx = FluidSystem::oilPhaseIdx };
enum { waterPhaseIdx = FluidSystem::waterPhaseIdx }; enum { waterPhaseIdx = FluidSystem::waterPhaseIdx };
@ -658,6 +663,7 @@ class EclProblem : public GetPropType<TypeTag, Properties::BaseProblem>
using FoamModule = BlackOilFoamModule<TypeTag>; using FoamModule = BlackOilFoamModule<TypeTag>;
using BrineModule = BlackOilBrineModule<TypeTag>; using BrineModule = BlackOilBrineModule<TypeTag>;
using ExtboModule = BlackOilExtboModule<TypeTag>; using ExtboModule = BlackOilExtboModule<TypeTag>;
using MICPModule= BlackOilMICPModule<TypeTag>;
using InitialFluidState = typename EclEquilInitializer<TypeTag>::ScalarFluidState; using InitialFluidState = typename EclEquilInitializer<TypeTag>::ScalarFluidState;
@ -789,6 +795,7 @@ public:
FoamModule::initFromState(vanguard.eclState()); FoamModule::initFromState(vanguard.eclState());
BrineModule::initFromState(vanguard.eclState()); BrineModule::initFromState(vanguard.eclState());
ExtboModule::initFromState(vanguard.eclState()); ExtboModule::initFromState(vanguard.eclState());
MICPModule::initFromState(vanguard.eclState());
// create the ECL writer // create the ECL writer
eclWriter_.reset(new EclWriterType(simulator)); eclWriter_.reset(new EclWriterType(simulator));
@ -908,7 +915,8 @@ public:
Indices::numPhases, Indices::numPhases,
Indices::gasEnabled, Indices::gasEnabled,
Indices::oilEnabled, Indices::oilEnabled,
Indices::waterEnabled); Indices::waterEnabled,
enableMICP);
} }
catch(const std::exception& e) catch(const std::exception& e)
{ {
@ -1161,6 +1169,16 @@ public:
schedule, schedule,
simulator.vanguard().actionState(), simulator.vanguard().actionState(),
simulator.vanguard().summaryState()); simulator.vanguard().summaryState());
// deal with "clogging" for the MICP model
if constexpr (enableMICP){
auto& model = this->model();
const auto& residual = this->model().linearizer().residual();
for (unsigned globalDofIdx = 0; globalDofIdx < residual.size(); globalDofIdx ++) {
auto& phi = this->referencePorosity_[/*timeIdx=*/1][globalDofIdx];
MICPModule::checkCloggingMICP(model, phi, globalDofIdx);
}
}
} }
/*! /*!
@ -1805,6 +1823,14 @@ public:
if constexpr (enableBrine) if constexpr (enableBrine)
values[Indices::saltConcentrationIdx] = initialFluidStates_[globalDofIdx].saltConcentration(); values[Indices::saltConcentrationIdx] = initialFluidStates_[globalDofIdx].saltConcentration();
if constexpr (enableMICP){
values[Indices::microbialConcentrationIdx]= this->microbialConcentration_[globalDofIdx];
values[Indices::oxygenConcentrationIdx]= this->oxygenConcentration_[globalDofIdx];
values[Indices::ureaConcentrationIdx]= this->ureaConcentration_[globalDofIdx];
values[Indices::calciteConcentrationIdx]= this->calciteConcentration_[globalDofIdx];
values[Indices::biofilmConcentrationIdx]= this->biofilmConcentration_[globalDofIdx];
}
values.checkDefined(); values.checkDefined();
} }
@ -2297,11 +2323,12 @@ private:
else else
readExplicitInitialCondition_(); readExplicitInitialCondition_();
if constexpr (enableSolvent || enablePolymer || enablePolymerMolarWeight) if constexpr (enableSolvent || enablePolymer || enablePolymerMolarWeight || enableMICP)
this->readBlackoilExtentionsInitialConditions_(this->model().numGridDof(), this->readBlackoilExtentionsInitialConditions_(this->model().numGridDof(),
enableSolvent, enableSolvent,
enablePolymer, enablePolymer,
enablePolymerMolarWeight); enablePolymerMolarWeight,
enableMICP);
//initialize min/max values //initialize min/max values
size_t numElems = this->model().numGridDof(); size_t numElems = this->model().numGridDof();
@ -2372,6 +2399,14 @@ private:
this->polymerMoleWeight_.resize(numElems, 0.0); this->polymerMoleWeight_.resize(numElems, 0.0);
} }
if constexpr (enableMICP){
this->microbialConcentration_.resize(numElems, 0.0);
this->oxygenConcentration_.resize(numElems, 0.0);
this->ureaConcentration_.resize(numElems, 0.0);
this->biofilmConcentration_.resize(numElems, 0.0);
this->calciteConcentration_.resize(numElems, 0.0);
}
for (size_t elemIdx = 0; elemIdx < numElems; ++elemIdx) { for (size_t elemIdx = 0; elemIdx < numElems; ++elemIdx) {
auto& elemFluidState = initialFluidStates_[elemIdx]; auto& elemFluidState = initialFluidStates_[elemIdx];
elemFluidState.setPvtRegionIndex(pvtRegionIndex(elemIdx)); elemFluidState.setPvtRegionIndex(pvtRegionIndex(elemIdx));
@ -2405,6 +2440,13 @@ private:
if constexpr (enablePolymer) if constexpr (enablePolymer)
this->polymerConcentration_[elemIdx] = eclWriter_->eclOutputModule().getPolymerConcentration(elemIdx); this->polymerConcentration_[elemIdx] = eclWriter_->eclOutputModule().getPolymerConcentration(elemIdx);
if constexpr (enableMICP){
this->microbialConcentration_[elemIdx] = eclWriter_->eclOutputModule().getMicrobialConcentration(elemIdx);
this->oxygenConcentration_[elemIdx] = eclWriter_->eclOutputModule().getOxygenConcentration(elemIdx);
this->ureaConcentration_[elemIdx] = eclWriter_->eclOutputModule().getUreaConcentration(elemIdx);
this->biofilmConcentration_[elemIdx] = eclWriter_->eclOutputModule().getBiofilmConcentration(elemIdx);
this->calciteConcentration_[elemIdx] = eclWriter_->eclOutputModule().getCalciteConcentration(elemIdx);
}
// if we need to restart for polymer molecular weight simulation, we need to add related here // if we need to restart for polymer molecular weight simulation, we need to add related here
} }

View File

@ -58,7 +58,8 @@ public:
getPropValue<TypeTag, Properties::EnableFoam>(), getPropValue<TypeTag, Properties::EnableFoam>(),
getPropValue<TypeTag, Properties::EnableBrine>(), getPropValue<TypeTag, Properties::EnableBrine>(),
/*PVOffset=*/0, /*PVOffset=*/0,
/*disabledCompIdx=*/FluidSystem::waterCompIdx> type; /*disabledCompIdx=*/FluidSystem::waterCompIdx,
getPropValue<TypeTag, Properties::EnableMICP>()> type;
}; };
}} }}

View File

@ -61,7 +61,8 @@ public:
getPropValue<TypeTag, Properties::EnableFoam>(), getPropValue<TypeTag, Properties::EnableFoam>(),
getPropValue<TypeTag, Properties::EnableBrine>(), getPropValue<TypeTag, Properties::EnableBrine>(),
/*PVOffset=*/0, /*PVOffset=*/0,
/*disabledCompIdx=*/FluidSystem::oilCompIdx> type; /*disabledCompIdx=*/FluidSystem::oilCompIdx,
getPropValue<TypeTag, Properties::EnableMICP>()> type;
}; };
}} }}

103
flow/flow_ebos_micp.cpp Normal file
View File

@ -0,0 +1,103 @@
/*
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 <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <flow/flow_ebos_micp.hpp>
#include <opm/material/common/ResetLocale.hpp>
#include <opm/models/blackoil/blackoilonephaseindices.hh>
#include <opm/grid/CpGrid.hpp>
#include <opm/simulators/flow/SimulatorFullyImplicitBlackoilEbos.hpp>
#include <opm/simulators/flow/FlowMainEbos.hpp>
#if HAVE_DUNE_FEM
#include <dune/fem/misc/mpimanager.hh>
#else
#include <dune/common/parallel/mpihelper.hh>
#endif
namespace Opm {
namespace Properties {
namespace TTag {
struct EclFlowMICPProblem {
using InheritsFrom = std::tuple<EclFlowProblem>;
};
}
template<class TypeTag>
struct EnableMICP<TypeTag, TTag::EclFlowMICPProblem> {
static constexpr bool value = true;
};
//! The indices required by the model
template<class TypeTag>
struct Indices<TypeTag, TTag::EclFlowMICPProblem>
{
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<BaseTypeTag, Properties::FluidSystem>;
public:
typedef BlackOilOnePhaseIndices<getPropValue<TypeTag, Properties::EnableSolvent>(),
getPropValue<TypeTag, Properties::EnableExtbo>(),
getPropValue<TypeTag, Properties::EnablePolymer>(),
getPropValue<TypeTag, Properties::EnableEnergy>(),
getPropValue<TypeTag, Properties::EnableFoam>(),
getPropValue<TypeTag, Properties::EnableBrine>(),
/*PVOffset=*/0,
/*enabledCompIdx=*/FluidSystem::waterCompIdx,
5> type; //Five MICP components
};
}}
namespace Opm {
void flowEbosMICPSetDeck(double setupTime, std::shared_ptr<Deck> deck,
std::shared_ptr<EclipseState> eclState,
std::shared_ptr<Schedule> schedule,
std::shared_ptr<SummaryConfig> summaryConfig)
{
using TypeTag = Properties::TTag::EclFlowMICPProblem;
using Vanguard = GetPropType<TypeTag, Properties::Vanguard>;
Vanguard::setExternalSetupTime(setupTime);
Vanguard::setExternalDeck(std::move(deck));
Vanguard::setExternalEclState(std::move(eclState));
Vanguard::setExternalSchedule(std::move(schedule));
Vanguard::setExternalSummaryConfig(std::move(summaryConfig));
}
// ----------------- Main program -----------------
int flowEbosMICPMain(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();
#if HAVE_DUNE_FEM
Dune::Fem::MPIManager::initialize(argc, argv);
#else
Dune::MPIHelper::instance(argc, argv);
#endif
FlowMainEbos<Properties::TTag::EclFlowMICPProblem>
mainfunc {argc, argv, outputCout, outputFiles};
return mainfunc.execute();
}
}

37
flow/flow_ebos_micp.hpp Normal file
View File

@ -0,0 +1,37 @@
/*
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 <http://www.gnu.org/licenses/>.
*/
#ifndef FLOW_EBOS_MICP_HPP
#define FLOW_EBOS_MICP_HPP
#include <memory>
namespace Opm {
class Deck;
class EclipseState;
class Schedule;
class SummaryConfig;
void flowEbosMICPSetDeck(double setupTime, std::shared_ptr<Deck> deck,
std::shared_ptr<EclipseState> eclState,
std::shared_ptr<Schedule> schedule,
std::shared_ptr<SummaryConfig> summaryConfig);
int flowEbosMICPMain(int argc, char** argv, bool outputCout, bool outputFiles);
}
#endif // FLOW_EBOS_MICP_HPP

View File

@ -58,7 +58,8 @@ public:
getPropValue<TypeTag, Properties::EnableFoam>(), getPropValue<TypeTag, Properties::EnableFoam>(),
getPropValue<TypeTag, Properties::EnableBrine>(), getPropValue<TypeTag, Properties::EnableBrine>(),
/*PVOffset=*/0, /*PVOffset=*/0,
/*disabledCompIdx=*/FluidSystem::gasCompIdx> type; /*disabledCompIdx=*/FluidSystem::gasCompIdx,
getPropValue<TypeTag, Properties::EnableMICP>()> type;
}; };
}} }}

View File

@ -61,7 +61,8 @@ public:
getPropValue<TypeTag, Properties::EnableFoam>(), getPropValue<TypeTag, Properties::EnableFoam>(),
getPropValue<TypeTag, Properties::EnableBrine>(), getPropValue<TypeTag, Properties::EnableBrine>(),
/*PVOffset=*/0, /*PVOffset=*/0,
/*disabledCompIdx=*/FluidSystem::gasCompIdx> type; /*disabledCompIdx=*/FluidSystem::gasCompIdx,
getPropValue<TypeTag, Properties::EnableMICP>()> type;
}; };
}} }}

View File

@ -61,7 +61,8 @@ public:
getPropValue<TypeTag, Properties::EnableFoam>(), getPropValue<TypeTag, Properties::EnableFoam>(),
getPropValue<TypeTag, Properties::EnableBrine>(), getPropValue<TypeTag, Properties::EnableBrine>(),
/*PVOffset=*/0, /*PVOffset=*/0,
/*disabledCompIdx=*/FluidSystem::gasCompIdx> type; /*disabledCompIdx=*/FluidSystem::gasCompIdx,
getPropValue<TypeTag, Properties::EnableMICP>()> type;
}; };
}} }}

View File

@ -67,7 +67,8 @@ public:
getPropValue<TypeTag, Properties::EnableFoam>(), getPropValue<TypeTag, Properties::EnableFoam>(),
getPropValue<TypeTag, Properties::EnableBrine>(), getPropValue<TypeTag, Properties::EnableBrine>(),
/*PVOffset=*/0, /*PVOffset=*/0,
/*disabledCompIdx=*/FluidSystem::gasCompIdx> type; /*disabledCompIdx=*/FluidSystem::gasCompIdx,
getPropValue<TypeTag, Properties::EnableMICP>()> type;
}; };
}} }}

View File

@ -42,6 +42,7 @@ private:
using BaseTypeTag = TTag::EclFlowProblem; using BaseTypeTag = TTag::EclFlowProblem;
using FluidSystem = GetPropType<BaseTypeTag, Properties::FluidSystem>; using FluidSystem = GetPropType<BaseTypeTag, Properties::FluidSystem>;
public:
public: public:
using type = BlackOilOnePhaseIndices<getPropValue<TypeTag, Properties::EnableSolvent>(), using type = BlackOilOnePhaseIndices<getPropValue<TypeTag, Properties::EnableSolvent>(),
getPropValue<TypeTag, Properties::EnableExtbo>(), getPropValue<TypeTag, Properties::EnableExtbo>(),
@ -50,7 +51,8 @@ public:
getPropValue<TypeTag, Properties::EnableFoam>(), getPropValue<TypeTag, Properties::EnableFoam>(),
getPropValue<TypeTag, Properties::EnableBrine>(), getPropValue<TypeTag, Properties::EnableBrine>(),
/*PVOffset=*/0, /*PVOffset=*/0,
/*enabledCompIdx=*/FluidSystem::waterCompIdx>; /*enabledCompIdx=*/FluidSystem::waterCompIdx,
getPropValue<TypeTag, Properties::EnableMICP>()>;
}; };
} // namespace Opm::Properties } // namespace Opm::Properties

View File

@ -53,7 +53,8 @@ public:
getPropValue<TypeTag, Properties::EnableFoam>(), getPropValue<TypeTag, Properties::EnableFoam>(),
getPropValue<TypeTag, Properties::EnableBrine>(), getPropValue<TypeTag, Properties::EnableBrine>(),
/*PVOffset=*/0, /*PVOffset=*/0,
/*enebledCompIdx=*/FluidSystem::waterCompIdx> /*enebledCompIdx=*/FluidSystem::waterCompIdx,
getPropValue<TypeTag, Properties::EnableMICP>()>
type; type;
}; };

View File

@ -126,6 +126,10 @@ template<class TypeTag>
struct EnableBrine<TypeTag, TTag::EclFlowProblem> { struct EnableBrine<TypeTag, TTag::EclFlowProblem> {
static constexpr bool value = false; static constexpr bool value = false;
}; };
template<class TypeTag>
struct EnableMICP<TypeTag, TTag::EclFlowProblem> {
static constexpr bool value = false;
};
template<class TypeTag> template<class TypeTag>
struct EclWellModel<TypeTag, TTag::EclFlowProblem> { struct EclWellModel<TypeTag, TTag::EclFlowProblem> {
@ -172,6 +176,11 @@ namespace Opm {
static const int contiPolymerMWEqIdx = Indices::contiPolymerMWEqIdx; static const int contiPolymerMWEqIdx = Indices::contiPolymerMWEqIdx;
static const int contiFoamEqIdx = Indices::contiFoamEqIdx; static const int contiFoamEqIdx = Indices::contiFoamEqIdx;
static const int contiBrineEqIdx = Indices::contiBrineEqIdx; static const int contiBrineEqIdx = Indices::contiBrineEqIdx;
static const int contiMicrobialEqIdx = Indices::contiMicrobialEqIdx;
static const int contiOxygenEqIdx = Indices::contiOxygenEqIdx;
static const int contiUreaEqIdx = Indices::contiUreaEqIdx;
static const int contiBiofilmEqIdx = Indices::contiBiofilmEqIdx;
static const int contiCalciteEqIdx = Indices::contiCalciteEqIdx;
static const int solventSaturationIdx = Indices::solventSaturationIdx; static const int solventSaturationIdx = Indices::solventSaturationIdx;
static const int zFractionIdx = Indices::zFractionIdx; static const int zFractionIdx = Indices::zFractionIdx;
static const int polymerConcentrationIdx = Indices::polymerConcentrationIdx; static const int polymerConcentrationIdx = Indices::polymerConcentrationIdx;
@ -179,6 +188,11 @@ namespace Opm {
static const int temperatureIdx = Indices::temperatureIdx; static const int temperatureIdx = Indices::temperatureIdx;
static const int foamConcentrationIdx = Indices::foamConcentrationIdx; static const int foamConcentrationIdx = Indices::foamConcentrationIdx;
static const int saltConcentrationIdx = Indices::saltConcentrationIdx; static const int saltConcentrationIdx = Indices::saltConcentrationIdx;
static const int microbialConcentrationIdx = Indices::microbialConcentrationIdx;
static const int oxygenConcentrationIdx = Indices::oxygenConcentrationIdx;
static const int ureaConcentrationIdx = Indices::ureaConcentrationIdx;
static const int biofilmConcentrationIdx = Indices::biofilmConcentrationIdx;
static const int calciteConcentrationIdx = Indices::calciteConcentrationIdx;
typedef Dune::FieldVector<Scalar, numEq > VectorBlockType; typedef Dune::FieldVector<Scalar, numEq > VectorBlockType;
typedef typename SparseMatrixAdapter::MatrixBlock MatrixBlockType; typedef typename SparseMatrixAdapter::MatrixBlock MatrixBlockType;
@ -452,7 +466,7 @@ namespace Opm {
Scalar saturationsNew[FluidSystem::numPhases] = { 0.0 }; Scalar saturationsNew[FluidSystem::numPhases] = { 0.0 };
Scalar oilSaturationNew = 1.0; Scalar oilSaturationNew = 1.0;
if (FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx)) { if (FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx) && FluidSystem::numActivePhases() > 1) {
saturationsNew[FluidSystem::waterPhaseIdx] = priVarsNew[Indices::waterSaturationIdx]; saturationsNew[FluidSystem::waterPhaseIdx] = priVarsNew[Indices::waterSaturationIdx];
oilSaturationNew -= saturationsNew[FluidSystem::waterPhaseIdx]; oilSaturationNew -= saturationsNew[FluidSystem::waterPhaseIdx];
} }
@ -726,6 +740,28 @@ namespace Opm {
maxCoeff[ contiEnergyEqIdx ] = std::max( maxCoeff[ contiEnergyEqIdx ], std::abs( R2 ) / pvValue ); maxCoeff[ contiEnergyEqIdx ] = std::max( maxCoeff[ contiEnergyEqIdx ], std::abs( R2 ) / pvValue );
} }
if constexpr (has_micp_) {
B_avg[ contiMicrobialEqIdx ] += 1.0 / fs.invB(FluidSystem::waterPhaseIdx).value();
const auto R1 = ebosResid[cell_idx][contiMicrobialEqIdx];
R_sum[ contiMicrobialEqIdx ] += R1;
maxCoeff[ contiMicrobialEqIdx ] = std::max( maxCoeff[ contiMicrobialEqIdx ], std::abs( R1 ) / pvValue );
B_avg[ contiOxygenEqIdx ] += 1.0 / fs.invB(FluidSystem::waterPhaseIdx).value();
const auto R2 = ebosResid[cell_idx][contiOxygenEqIdx];
R_sum[ contiOxygenEqIdx ] += R2;
maxCoeff[ contiOxygenEqIdx ] = std::max( maxCoeff[ contiOxygenEqIdx ], std::abs( R2 ) / pvValue );
B_avg[ contiUreaEqIdx ] += 1.0 / fs.invB(FluidSystem::waterPhaseIdx).value();
const auto R3 = ebosResid[cell_idx][contiUreaEqIdx];
R_sum[ contiUreaEqIdx ] += R3;
maxCoeff[ contiUreaEqIdx ] = std::max( maxCoeff[ contiUreaEqIdx ], std::abs( R3 ) / pvValue );
B_avg[ contiBiofilmEqIdx ] += 1.0 / fs.invB(FluidSystem::waterPhaseIdx).value();
const auto R4 = ebosResid[cell_idx][contiBiofilmEqIdx];
R_sum[ contiBiofilmEqIdx ] += R4;
maxCoeff[ contiBiofilmEqIdx ] = std::max( maxCoeff[ contiBiofilmEqIdx ], std::abs( R4 ) / pvValue );
B_avg[ contiCalciteEqIdx ] += 1.0 / fs.invB(FluidSystem::waterPhaseIdx).value();
const auto R5 = ebosResid[cell_idx][contiCalciteEqIdx];
R_sum[ contiCalciteEqIdx ] += R5;
maxCoeff[ contiCalciteEqIdx ] = std::max( maxCoeff[ contiCalciteEqIdx ], std::abs( R5 ) / pvValue );
}
} }
OPM_END_PARALLEL_TRY_CATCH("BlackoilModelEbos::localConvergenceData() failed: ", grid_.comm()); OPM_END_PARALLEL_TRY_CATCH("BlackoilModelEbos::localConvergenceData() failed: ", grid_.comm());
@ -849,6 +885,13 @@ namespace Opm {
if constexpr (has_brine_) { if constexpr (has_brine_) {
compNames[saltConcentrationIdx] = "Brine"; compNames[saltConcentrationIdx] = "Brine";
} }
if constexpr (has_micp_) {
compNames[microbialConcentrationIdx] = "Microbes";
compNames[oxygenConcentrationIdx] = "Oxygen";
compNames[ureaConcentrationIdx] = "Urea";
compNames[biofilmConcentrationIdx] = "Biofilm";
compNames[calciteConcentrationIdx] = "Calcite";
}
} }
// Create convergence report. // Create convergence report.
@ -994,6 +1037,7 @@ namespace Opm {
static constexpr bool has_energy_ = getPropValue<TypeTag, Properties::EnableEnergy>(); static constexpr bool has_energy_ = getPropValue<TypeTag, Properties::EnableEnergy>();
static constexpr bool has_foam_ = getPropValue<TypeTag, Properties::EnableFoam>(); static constexpr bool has_foam_ = getPropValue<TypeTag, Properties::EnableFoam>();
static constexpr bool has_brine_ = getPropValue<TypeTag, Properties::EnableBrine>(); static constexpr bool has_brine_ = getPropValue<TypeTag, Properties::EnableBrine>();
static constexpr bool has_micp_ = getPropValue<TypeTag, Properties::EnableMICP>();
ModelParameters param_; ModelParameters param_;
SimulatorReportSingle failureReport_; SimulatorReportSingle failureReport_;

View File

@ -37,6 +37,7 @@
# include <flow/flow_ebos_energy.hpp> # include <flow/flow_ebos_energy.hpp>
# include <flow/flow_ebos_oilwater_polymer.hpp> # include <flow/flow_ebos_oilwater_polymer.hpp>
# include <flow/flow_ebos_oilwater_polymer_injectivity.hpp> # include <flow/flow_ebos_oilwater_polymer_injectivity.hpp>
# include <flow/flow_ebos_micp.hpp>
# endif # endif
#include <opm/parser/eclipse/Deck/Deck.hpp> #include <opm/parser/eclipse/Deck/Deck.hpp>
@ -288,6 +289,19 @@ namespace Opm
if (false) {} if (false) {}
#ifndef FLOW_BLACKOIL_ONLY #ifndef FLOW_BLACKOIL_ONLY
// Single-phase case
else if( eclipseState_->runspec().micp() ) {
// micp
if ( !phases.active( Phase::WATER) || phases.size() > 2) {
if (outputCout_)
std::cerr << "No valid configuration is found for MICP simulation, the only valid option is "
<< "water + MICP" << std::endl;
return EXIT_FAILURE;
}
flowEbosMICPSetDeck(
setupTime_, deck_, eclipseState_, schedule_, summaryConfig_);
return flowEbosMICPMain(argc_, argv_, outputCout_, outputFiles_);
}
// Twophase cases // Twophase cases
else if (phases.size() == 2) { else if (phases.size() == 2) {
return this->runTwoPhase(phases); return this->runTwoPhase(phases);

View File

@ -83,6 +83,7 @@ public:
typedef AdaptiveTimeSteppingEbos<TypeTag> TimeStepper; typedef AdaptiveTimeSteppingEbos<TypeTag> TimeStepper;
typedef BlackOilPolymerModule<TypeTag> PolymerModule; typedef BlackOilPolymerModule<TypeTag> PolymerModule;
typedef BlackOilMICPModule<TypeTag> MICPModule;
typedef BlackoilModelEbos<TypeTag> Model; typedef BlackoilModelEbos<TypeTag> Model;
typedef NonlinearSolverEbos<TypeTag, Model> Solver; typedef NonlinearSolverEbos<TypeTag, Model> Solver;

View File

@ -0,0 +1,24 @@
/*
Copyright 2019, 2020 SINTEF Digital, Mathematics and Cybernetics.
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 <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <opm/simulators/linalg/FlexibleSolver_impl.hpp>
INSTANTIATE_FLEXIBLESOLVER(5);

View File

@ -0,0 +1,24 @@
/*
Copyright 2019, 2020 SINTEF Digital, Mathematics and Cybernetics.
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 <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <opm/simulators/linalg/FlexibleSolver_impl.hpp>
INSTANTIATE_FLEXIBLESOLVER(6);

View File

@ -687,9 +687,9 @@ INSTANTIATE_BDA_FUNCTIONS(1);
INSTANTIATE_BDA_FUNCTIONS(2); INSTANTIATE_BDA_FUNCTIONS(2);
INSTANTIATE_BDA_FUNCTIONS(3); INSTANTIATE_BDA_FUNCTIONS(3);
INSTANTIATE_BDA_FUNCTIONS(4); INSTANTIATE_BDA_FUNCTIONS(4);
INSTANTIATE_BDA_FUNCTIONS(5);
INSTANTIATE_BDA_FUNCTIONS(6);
#undef INSTANTIATE_BDA_FUNCTIONS #undef INSTANTIATE_BDA_FUNCTIONS
} // end namespace bda } // end namespace bda

View File

@ -292,9 +292,9 @@ INSTANTIATE_BDA_FUNCTIONS(1);
INSTANTIATE_BDA_FUNCTIONS(2); INSTANTIATE_BDA_FUNCTIONS(2);
INSTANTIATE_BDA_FUNCTIONS(3); INSTANTIATE_BDA_FUNCTIONS(3);
INSTANTIATE_BDA_FUNCTIONS(4); INSTANTIATE_BDA_FUNCTIONS(4);
INSTANTIATE_BDA_FUNCTIONS(5);
INSTANTIATE_BDA_FUNCTIONS(6);
#undef INSTANTIATE_BDA_FUNCTIONS #undef INSTANTIATE_BDA_FUNCTIONS
} // namespace Opm } // namespace Opm

View File

@ -478,6 +478,8 @@ INSTANTIATE_BDA_FUNCTIONS(1);
INSTANTIATE_BDA_FUNCTIONS(2); INSTANTIATE_BDA_FUNCTIONS(2);
INSTANTIATE_BDA_FUNCTIONS(3); INSTANTIATE_BDA_FUNCTIONS(3);
INSTANTIATE_BDA_FUNCTIONS(4); INSTANTIATE_BDA_FUNCTIONS(4);
INSTANTIATE_BDA_FUNCTIONS(5);
INSTANTIATE_BDA_FUNCTIONS(6);
#undef INSTANTIATE_BDA_FUNCTIONS #undef INSTANTIATE_BDA_FUNCTIONS

View File

@ -407,6 +407,8 @@ INSTANTIATE_BDA_FUNCTIONS(1);
INSTANTIATE_BDA_FUNCTIONS(2); INSTANTIATE_BDA_FUNCTIONS(2);
INSTANTIATE_BDA_FUNCTIONS(3); INSTANTIATE_BDA_FUNCTIONS(3);
INSTANTIATE_BDA_FUNCTIONS(4); INSTANTIATE_BDA_FUNCTIONS(4);
INSTANTIATE_BDA_FUNCTIONS(5);
INSTANTIATE_BDA_FUNCTIONS(6);
#undef INSTANTIATE_BDA_FUNCTIONS #undef INSTANTIATE_BDA_FUNCTIONS

View File

@ -726,6 +726,8 @@ INSTANTIATE_BDA_FUNCTIONS(1);
INSTANTIATE_BDA_FUNCTIONS(2); INSTANTIATE_BDA_FUNCTIONS(2);
INSTANTIATE_BDA_FUNCTIONS(3); INSTANTIATE_BDA_FUNCTIONS(3);
INSTANTIATE_BDA_FUNCTIONS(4); INSTANTIATE_BDA_FUNCTIONS(4);
INSTANTIATE_BDA_FUNCTIONS(5);
INSTANTIATE_BDA_FUNCTIONS(6);
#undef INSTANTIATE_BDA_FUNCTIONS #undef INSTANTIATE_BDA_FUNCTIONS

View File

@ -376,6 +376,8 @@ INSTANTIATE_BDA_FUNCTIONS(1);
INSTANTIATE_BDA_FUNCTIONS(2); INSTANTIATE_BDA_FUNCTIONS(2);
INSTANTIATE_BDA_FUNCTIONS(3); INSTANTIATE_BDA_FUNCTIONS(3);
INSTANTIATE_BDA_FUNCTIONS(4); INSTANTIATE_BDA_FUNCTIONS(4);
INSTANTIATE_BDA_FUNCTIONS(5);
INSTANTIATE_BDA_FUNCTIONS(6);
#undef INSTANTIATE_BDA_FUNCTIONS #undef INSTANTIATE_BDA_FUNCTIONS

View File

@ -376,8 +376,9 @@ INSTANTIATE_BDA_FUNCTIONS(1);
INSTANTIATE_BDA_FUNCTIONS(2); INSTANTIATE_BDA_FUNCTIONS(2);
INSTANTIATE_BDA_FUNCTIONS(3); INSTANTIATE_BDA_FUNCTIONS(3);
INSTANTIATE_BDA_FUNCTIONS(4); INSTANTIATE_BDA_FUNCTIONS(4);
INSTANTIATE_BDA_FUNCTIONS(5);
INSTANTIATE_BDA_FUNCTIONS(6);
#undef INSTANTIATE_BDA_FUNCTIONS #undef INSTANTIATE_BDA_FUNCTIONS
} // namespace bda } // namespace bda

View File

@ -82,6 +82,8 @@ INSTANTIATE_BDA_FUNCTIONS(1);
INSTANTIATE_BDA_FUNCTIONS(2); INSTANTIATE_BDA_FUNCTIONS(2);
INSTANTIATE_BDA_FUNCTIONS(3); INSTANTIATE_BDA_FUNCTIONS(3);
INSTANTIATE_BDA_FUNCTIONS(4); INSTANTIATE_BDA_FUNCTIONS(4);
INSTANTIATE_BDA_FUNCTIONS(5);
INSTANTIATE_BDA_FUNCTIONS(6);
#undef INSTANTIATE_BDA_FUNCTIONS #undef INSTANTIATE_BDA_FUNCTIONS

View File

@ -506,6 +506,8 @@ INSTANTIATE_BDA_FUNCTIONS(1);
INSTANTIATE_BDA_FUNCTIONS(2); INSTANTIATE_BDA_FUNCTIONS(2);
INSTANTIATE_BDA_FUNCTIONS(3); INSTANTIATE_BDA_FUNCTIONS(3);
INSTANTIATE_BDA_FUNCTIONS(4); INSTANTIATE_BDA_FUNCTIONS(4);
INSTANTIATE_BDA_FUNCTIONS(5);
INSTANTIATE_BDA_FUNCTIONS(6);
#undef INSTANTIATE_BDA_FUNCTIONS #undef INSTANTIATE_BDA_FUNCTIONS

View File

@ -815,8 +815,9 @@ INSTANTIATE_BDA_FUNCTIONS(1);
INSTANTIATE_BDA_FUNCTIONS(2); INSTANTIATE_BDA_FUNCTIONS(2);
INSTANTIATE_BDA_FUNCTIONS(3); INSTANTIATE_BDA_FUNCTIONS(3);
INSTANTIATE_BDA_FUNCTIONS(4); INSTANTIATE_BDA_FUNCTIONS(4);
INSTANTIATE_BDA_FUNCTIONS(5);
INSTANTIATE_BDA_FUNCTIONS(6);
#undef INSTANTIATE_BDA_FUNCTIONS #undef INSTANTIATE_BDA_FUNCTIONS
} // namespace bda } // namespace bda

View File

@ -119,6 +119,7 @@ namespace Opm {
static constexpr bool has_solvent_ = getPropValue<TypeTag, Properties::EnableSolvent>(); static constexpr bool has_solvent_ = getPropValue<TypeTag, Properties::EnableSolvent>();
static constexpr bool has_polymer_ = getPropValue<TypeTag, Properties::EnablePolymer>(); static constexpr bool has_polymer_ = getPropValue<TypeTag, Properties::EnablePolymer>();
static constexpr bool has_energy_ = getPropValue<TypeTag, Properties::EnableEnergy>(); static constexpr bool has_energy_ = getPropValue<TypeTag, Properties::EnableEnergy>();
static constexpr bool has_micp_ = getPropValue<TypeTag, Properties::EnableMICP>();
// TODO: where we should put these types, WellInterface or Well Model? // TODO: where we should put these types, WellInterface or Well Model?
// or there is some other strategy, like TypeTag // or there is some other strategy, like TypeTag
@ -128,6 +129,7 @@ namespace Opm {
typedef Dune::FieldMatrix<Scalar, numEq, numEq > MatrixBlockType; typedef Dune::FieldMatrix<Scalar, numEq, numEq > MatrixBlockType;
typedef BlackOilPolymerModule<TypeTag> PolymerModule; typedef BlackOilPolymerModule<TypeTag> PolymerModule;
typedef BlackOilMICPModule<TypeTag> MICPModule;
// For the conversion between the surface volume rate and resrevoir voidage rate // For the conversion between the surface volume rate and resrevoir voidage rate
using RateConverterType = RateConverter:: using RateConverterType = RateConverter::

View File

@ -1852,26 +1852,27 @@ addWellContribution(WellContributions& wellContribs) const
template class MultisegmentWellEval<BlackOilFluidSystem<double,A>,__VA_ARGS__,double>; template class MultisegmentWellEval<BlackOilFluidSystem<double,A>,__VA_ARGS__,double>;
// One phase // One phase
INSTANCE(BlackOilDefaultIndexTraits,BlackOilOnePhaseIndices<0u,0u,0u,0u,false,false,0u,1u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilOnePhaseIndices<0u,0u,0u,0u,false,false,0u,1u,0u>)
INSTANCE(BlackOilDefaultIndexTraits,BlackOilOnePhaseIndices<0u,0u,0u,1u,false,false,0u,1u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilOnePhaseIndices<0u,0u,0u,1u,false,false,0u,1u,0u>)
INSTANCE(BlackOilDefaultIndexTraits,BlackOilOnePhaseIndices<0u,0u,0u,0u,false,false,0u,1u,5u>)
// Two phase // Two phase
INSTANCE(BlackOilDefaultIndexTraits,BlackOilTwoPhaseIndices<0u,0u,0u,0u,false,false,0u,0u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilTwoPhaseIndices<0u,0u,0u,0u,false,false,0u,0u,0u>)
INSTANCE(BlackOilDefaultIndexTraits,BlackOilTwoPhaseIndices<0u,0u,0u,0u,false,false,0u,1u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilTwoPhaseIndices<0u,0u,0u,0u,false,false,0u,1u,0u>)
INSTANCE(BlackOilDefaultIndexTraits,BlackOilTwoPhaseIndices<0u,0u,0u,0u,false,false,0u,2u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilTwoPhaseIndices<0u,0u,0u,0u,false,false,0u,2u,0u>)
INSTANCE(BlackOilDefaultIndexTraits,BlackOilTwoPhaseIndices<0u,0u,0u,0u,false,true,0u,2u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilTwoPhaseIndices<0u,0u,0u,0u,false,true,0u,2u,0u>)
INSTANCE(BlackOilDefaultIndexTraits,BlackOilTwoPhaseIndices<0u,0u,1u,0u,false,false,0u,2u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilTwoPhaseIndices<0u,0u,1u,0u,false,false,0u,2u,0u>)
INSTANCE(BlackOilDefaultIndexTraits,BlackOilTwoPhaseIndices<0u,0u,2u,0u,false,false,0u,2u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilTwoPhaseIndices<0u,0u,2u,0u,false,false,0u,2u,0u>)
// Blackoil // Blackoil
INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<0u,0u,0u,0u,false,false,0u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<0u,0u,0u,0u,false,false,0u,0u>)
INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<0u,0u,0u,0u,true,false,0u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<0u,0u,0u,0u,true,false,0u,0u>)
INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<0u,0u,0u,0u,false,true,0u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<0u,0u,0u,0u,false,true,0u,0u>)
INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<0u,0u,0u,0u,false,true,2u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<0u,0u,0u,0u,false,true,2u,0u>)
INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<1u,0u,0u,0u,false,false,0u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<1u,0u,0u,0u,false,false,0u,0u>)
INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<0u,1u,0u,0u,false,false,0u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<0u,1u,0u,0u,false,false,0u,0u>)
INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<0u,0u,1u,0u,false,false,0u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<0u,0u,1u,0u,false,false,0u,0u>)
INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<0u,0u,0u,1u,false,false,0u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<0u,0u,0u,1u,false,false,0u,0u>)
INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<0u,0u,0u,0u,false,false,1u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<0u,0u,0u,0u,false,false,1u,0u>)
} // namespace Opm } // namespace Opm

View File

@ -37,6 +37,7 @@ PerfData::PerfData(std::size_t num_perf, bool injector_, std::size_t num_phases)
, connection_transmissibility_factor(num_perf) , connection_transmissibility_factor(num_perf)
, satnum_id(num_perf) , satnum_id(num_perf)
, ecl_index(num_perf) , ecl_index(num_perf)
, micp_rates(num_perf)
{ {
if (injector) { if (injector) {
this->water_throughput.resize(num_perf); this->water_throughput.resize(num_perf);
@ -70,8 +71,8 @@ bool PerfData::try_assign(const PerfData& other) {
this->skin_pressure = other.skin_pressure; this->skin_pressure = other.skin_pressure;
this->water_velocity = other.water_velocity; this->water_velocity = other.water_velocity;
this->prod_index = other.prod_index; this->prod_index = other.prod_index;
this->micp_rates = other.micp_rates;
return true; return true;
} }
} }

View File

@ -45,6 +45,7 @@ public:
std::vector<double> polymer_rates; std::vector<double> polymer_rates;
std::vector<double> brine_rates; std::vector<double> brine_rates;
std::vector<double> prod_index; std::vector<double> prod_index;
std::vector<double> micp_rates;
std::vector<std::size_t> cell_index; std::vector<std::size_t> cell_index;
std::vector<double> connection_transmissibility_factor; std::vector<double> connection_transmissibility_factor;

View File

@ -39,6 +39,7 @@
#include <opm/models/blackoil/blackoilextbomodules.hh> #include <opm/models/blackoil/blackoilextbomodules.hh>
#include <opm/models/blackoil/blackoilfoammodules.hh> #include <opm/models/blackoil/blackoilfoammodules.hh>
#include <opm/models/blackoil/blackoilbrinemodules.hh> #include <opm/models/blackoil/blackoilbrinemodules.hh>
#include <opm/models/blackoil/blackoilmicpmodules.hh>
#include <opm/material/densead/DynamicEvaluation.hpp> #include <opm/material/densead/DynamicEvaluation.hpp>
#include <opm/parser/eclipse/EclipseState/Runspec.hpp> #include <opm/parser/eclipse/EclipseState/Runspec.hpp>
@ -95,6 +96,7 @@ namespace Opm
using Base::has_foam; using Base::has_foam;
using Base::has_brine; using Base::has_brine;
using Base::has_energy; using Base::has_energy;
using Base::has_micp;
using PolymerModule = BlackOilPolymerModule<TypeTag>; using PolymerModule = BlackOilPolymerModule<TypeTag>;
using FoamModule = BlackOilFoamModule<TypeTag>; using FoamModule = BlackOilFoamModule<TypeTag>;

View File

@ -1110,26 +1110,27 @@ addWellContribution(WellContributions& wellContribs) const
template class StandardWellEval<BlackOilFluidSystem<double,A>,__VA_ARGS__,double>; template class StandardWellEval<BlackOilFluidSystem<double,A>,__VA_ARGS__,double>;
// One phase // One phase
INSTANCE(BlackOilDefaultIndexTraits,BlackOilOnePhaseIndices<0u,0u,0u,0u,false,false,0u,1u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilOnePhaseIndices<0u,0u,0u,0u,false,false,0u,1u,0u>)
INSTANCE(BlackOilDefaultIndexTraits,BlackOilOnePhaseIndices<0u,0u,0u,1u,false,false,0u,1u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilOnePhaseIndices<0u,0u,0u,1u,false,false,0u,1u,0u>)
INSTANCE(BlackOilDefaultIndexTraits,BlackOilOnePhaseIndices<0u,0u,0u,0u,false,false,0u,1u,5u>)
// Two phase // Two phase
INSTANCE(BlackOilDefaultIndexTraits,BlackOilTwoPhaseIndices<0u,0u,0u,0u,false,false,0u,0u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilTwoPhaseIndices<0u,0u,0u,0u,false,false,0u,0u,0u>)
INSTANCE(BlackOilDefaultIndexTraits,BlackOilTwoPhaseIndices<0u,0u,0u,0u,false,false,0u,1u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilTwoPhaseIndices<0u,0u,0u,0u,false,false,0u,1u,0u>)
INSTANCE(BlackOilDefaultIndexTraits,BlackOilTwoPhaseIndices<0u,0u,0u,0u,false,false,0u,2u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilTwoPhaseIndices<0u,0u,0u,0u,false,false,0u,2u,0u>)
INSTANCE(BlackOilDefaultIndexTraits,BlackOilTwoPhaseIndices<0u,0u,0u,0u,false,true,0u,2u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilTwoPhaseIndices<0u,0u,0u,0u,false,true,0u,2u,0u>)
INSTANCE(BlackOilDefaultIndexTraits,BlackOilTwoPhaseIndices<0u,0u,1u,0u,false,false,0u,2u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilTwoPhaseIndices<0u,0u,1u,0u,false,false,0u,2u,0u>)
INSTANCE(BlackOilDefaultIndexTraits,BlackOilTwoPhaseIndices<0u,0u,1u,0u,false,true,0u,2u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilTwoPhaseIndices<0u,0u,1u,0u,false,true,0u,2u,0u>)
INSTANCE(BlackOilDefaultIndexTraits,BlackOilTwoPhaseIndices<0u,0u,2u,0u,false,false,0u,2u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilTwoPhaseIndices<0u,0u,2u,0u,false,false,0u,2u,0u>)
// Blackoil // Blackoil
INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<0u,0u,0u,0u,false,false,0u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<0u,0u,0u,0u,false,false,0u,0u>)
INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<0u,0u,0u,0u,true,false,0u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<0u,0u,0u,0u,true,false,0u,0u>)
INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<0u,0u,0u,0u,false,true,0u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<0u,0u,0u,0u,false,true,0u,0u>)
INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<1u,0u,0u,0u,false,false,0u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<1u,0u,0u,0u,false,false,0u,0u>)
INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<0u,1u,0u,0u,false,false,0u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<0u,1u,0u,0u,false,false,0u,0u>)
INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<0u,0u,1u,0u,false,false,0u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<0u,0u,1u,0u,false,false,0u,0u>)
INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<0u,0u,0u,1u,false,false,0u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<0u,0u,0u,1u,false,false,0u,0u>)
INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<0u,0u,0u,1u,false,false,1u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<0u,0u,0u,1u,false,false,1u,0u>)
} }

View File

@ -694,6 +694,31 @@ namespace Opm
connectionRates[perf][Indices::contiBrineEqIdx] = Base::restrictEval(cq_s_sm); connectionRates[perf][Indices::contiBrineEqIdx] = Base::restrictEval(cq_s_sm);
} }
if constexpr (has_micp) {
const unsigned waterCompIdx = Indices::canonicalToActiveComponentIndex(FluidSystem::waterCompIdx);
EvalWell cq_s_microbe = cq_s[waterCompIdx];
if (this->isInjector()) {
cq_s_microbe *= this->wmicrobes();
} else {
cq_s_microbe *= this->extendEval(intQuants.microbialConcentration());
}
connectionRates[perf][Indices::contiMicrobialEqIdx] = Base::restrictEval(cq_s_microbe);
EvalWell cq_s_oxygen = cq_s[waterCompIdx];
if (this->isInjector()) {
cq_s_oxygen *= this->woxygen();
} else {
cq_s_oxygen *= this->extendEval(intQuants.oxygenConcentration());
}
connectionRates[perf][Indices::contiOxygenEqIdx] = Base::restrictEval(cq_s_oxygen);
EvalWell cq_s_urea = cq_s[waterCompIdx];
if (this->isInjector()) {
cq_s_urea *= this->wurea();
} else {
cq_s_urea *= this->extendEval(intQuants.ureaConcentration());
}
connectionRates[perf][Indices::contiUreaEqIdx] = Base::restrictEval(cq_s_urea);
}
// Store the perforation pressure for later usage. // Store the perforation pressure for later usage.
perf_data.pressure[perf] = ws.bhp + this->perf_pressure_diffs_[perf]; perf_data.pressure[perf] = ws.bhp + this->perf_pressure_diffs_[perf];
} }
@ -1323,7 +1348,7 @@ namespace Opm
{ {
// the following implementation assume that the polymer is always after the w-o-g phases // the following implementation assume that the polymer is always after the w-o-g phases
// For the polymer, energy and foam cases, there is one more mass balance equations of reservoir than wells // For the polymer, energy and foam cases, there is one more mass balance equations of reservoir than wells
assert((int(B_avg.size()) == this->num_components_) || has_polymer || has_energy || has_foam || has_brine || has_zFraction); assert((int(B_avg.size()) == this->num_components_) || has_polymer || has_energy || has_foam || has_brine || has_zFraction || has_micp);
std::vector<double> res; std::vector<double> res;
ConvergenceReport report = this->StdWellEval::getWellConvergence(well_state, ConvergenceReport report = this->StdWellEval::getWellConvergence(well_state,

View File

@ -112,6 +112,7 @@ public:
static constexpr bool has_polymermw = getPropValue<TypeTag, Properties::EnablePolymerMW>(); static constexpr bool has_polymermw = getPropValue<TypeTag, Properties::EnablePolymerMW>();
static constexpr bool has_foam = getPropValue<TypeTag, Properties::EnableFoam>(); static constexpr bool has_foam = getPropValue<TypeTag, Properties::EnableFoam>();
static constexpr bool has_brine = getPropValue<TypeTag, Properties::EnableBrine>(); static constexpr bool has_brine = getPropValue<TypeTag, Properties::EnableBrine>();
static constexpr bool has_micp = getPropValue<TypeTag, Properties::EnableMICP>();
// For the conversion between the surface volume rate and reservoir voidage rate // For the conversion between the surface volume rate and reservoir voidage rate
using FluidState = BlackOilFluidState<Eval, using FluidState = BlackOilFluidState<Eval,
@ -284,6 +285,12 @@ protected:
double wsalt() const; double wsalt() const;
double wmicrobes() const;
double woxygen() const;
double wurea() const;
virtual double getRefDensity() const = 0; virtual double getRefDensity() const = 0;
// Component fractions for each phase for the well // Component fractions for each phase for the well

View File

@ -117,28 +117,29 @@ template class WellInterfaceIndices<BlackOilFluidSystem<double, A>, \
double>; double>;
// One phase // One phase
INSTANCE(BlackOilDefaultIndexTraits,BlackOilOnePhaseIndices<0u,0u,0u,0u,false,false,0u,1u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilOnePhaseIndices<0u,0u,0u,0u,false,false,0u,1u,0u>)
INSTANCE(BlackOilDefaultIndexTraits,BlackOilOnePhaseIndices<0u,0u,0u,1u,false,false,0u,1u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilOnePhaseIndices<0u,0u,0u,1u,false,false,0u,1u,0u>)
INSTANCE(BlackOilDefaultIndexTraits,BlackOilOnePhaseIndices<0u,0u,0u,0u,false,false,0u,1u,5u>)
// Two phase // Two phase
INSTANCE(BlackOilDefaultIndexTraits,BlackOilTwoPhaseIndices<0u,0u,0u,0u,false,false,0u,0u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilTwoPhaseIndices<0u,0u,0u,0u,false,false,0u,0u,0u>)
INSTANCE(BlackOilDefaultIndexTraits,BlackOilTwoPhaseIndices<0u,0u,0u,0u,false,false,0u,1u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilTwoPhaseIndices<0u,0u,0u,0u,false,false,0u,1u,0u>)
INSTANCE(BlackOilDefaultIndexTraits,BlackOilTwoPhaseIndices<0u,0u,0u,0u,false,false,0u,2u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilTwoPhaseIndices<0u,0u,0u,0u,false,false,0u,2u,0u>)
INSTANCE(BlackOilDefaultIndexTraits,BlackOilTwoPhaseIndices<0u,0u,1u,0u,false,false,0u,2u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilTwoPhaseIndices<0u,0u,1u,0u,false,false,0u,2u,0u>)
INSTANCE(BlackOilDefaultIndexTraits,BlackOilTwoPhaseIndices<0u,0u,2u,0u,false,false,0u,2u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilTwoPhaseIndices<0u,0u,2u,0u,false,false,0u,2u,0u>)
INSTANCE(BlackOilDefaultIndexTraits,BlackOilTwoPhaseIndices<0u,0u,0u,0u,false,true,0u,2u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilTwoPhaseIndices<0u,0u,0u,0u,false,true,0u,2u,0u>)
INSTANCE(BlackOilDefaultIndexTraits,BlackOilTwoPhaseIndices<0u,0u,1u,0u,false,true,0u,2u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilTwoPhaseIndices<0u,0u,1u,0u,false,true,0u,2u,0u>)
// Blackoil // Blackoil
INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<0u,0u,0u,0u,false,false,0u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<0u,0u,0u,0u,false,false,0u,0u>)
INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<0u,0u,0u,0u,true,false,0u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<0u,0u,0u,0u,true,false,0u,0u>)
INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<0u,0u,0u,0u,false,true,0u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<0u,0u,0u,0u,false,true,0u,0u>)
INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<0u,0u,0u,0u,false,true,2u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<0u,0u,0u,0u,false,true,2u,0u>)
INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<1u,0u,0u,0u,false,false,0u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<1u,0u,0u,0u,false,false,0u,0u>)
INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<0u,1u,0u,0u,false,false,0u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<0u,1u,0u,0u,false,false,0u,0u>)
INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<0u,0u,1u,0u,false,false,0u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<0u,0u,1u,0u,false,false,0u,0u>)
INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<0u,0u,0u,1u,false,false,0u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<0u,0u,0u,1u,false,false,0u,0u>)
INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<0u,0u,0u,1u,false,false,1u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<0u,0u,0u,1u,false,false,1u,0u>)
INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<0u,0u,0u,0u,false,false,1u>) INSTANCE(BlackOilDefaultIndexTraits,BlackOilIndices<0u,0u,0u,0u,false,false,1u,0u>)
} // namespace Opm } // namespace Opm

View File

@ -150,6 +150,74 @@ namespace Opm
return 0.0; return 0.0;
} }
template<typename TypeTag>
double
WellInterface<TypeTag>::
wmicrobes() const
{
if constexpr (has_micp) {
auto injectorType = this->well_ecl_.injectorType();
if (injectorType == InjectorType::WATER) {
WellMICPProperties microbes = this->well_ecl_.getMICPProperties();
const double microbial_injection_concentration = microbes.m_microbialConcentration;
return microbial_injection_concentration;
} else {
// Not a water injection well => no microbes.
return 0.0;
}
}
return 0.0;
}
template<typename TypeTag>
double
WellInterface<TypeTag>::
woxygen() const
{
if constexpr (has_micp) {
auto injectorType = this->well_ecl_.injectorType();
if (injectorType == InjectorType::WATER) {
WellMICPProperties oxygen = this->well_ecl_.getMICPProperties();
const double oxygen_injection_concentration = oxygen.m_oxygenConcentration;
return oxygen_injection_concentration;
} else {
// Not a water injection well => no oxygen.
return 0.0;
}
}
return 0.0;
}
// The urea injection concentration is scaled down by a factor of 10, since its value
// can be much bigger than 1 (not doing this slows the simulations). The
// corresponding values are scaled accordingly in blackoilmicpmodules.hh when computing
// the reactions and also when writing the output files (vtk and eclipse format, i.e.,
// vtkblackoilmicpmodule.hh and ecloutputblackoilmodel.hh respectively).
template<typename TypeTag>
double
WellInterface<TypeTag>::
wurea() const
{
if constexpr (has_micp) {
auto injectorType = this->well_ecl_.injectorType();
if (injectorType == InjectorType::WATER) {
WellMICPProperties urea = this->well_ecl_.getMICPProperties();
const double urea_injection_concentration = urea.m_ureaConcentration / 10.; //Dividing by scaling factor 10
return urea_injection_concentration;
} else {
// Not a water injection well => no urea.
return 0.0;
}
}
return 0.0;
}
template<typename TypeTag> template<typename TypeTag>
bool bool