mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
Merge pull request #2851 from osae/extboSimulators
Alternative solvent extension for the black oil model.
This commit is contained in:
commit
0ac2f922d3
@ -228,7 +228,7 @@ add_dependencies(moduleVersion opmsimulators)
|
|||||||
set(FLOW_TGTS)
|
set(FLOW_TGTS)
|
||||||
foreach(OBJ blackoil brine energy foam gasoil oilwater
|
foreach(OBJ blackoil brine energy foam gasoil oilwater
|
||||||
oilwater_brine oilwater_polymer
|
oilwater_brine oilwater_polymer
|
||||||
oilwater_polymer_injectivity polymer solvent)
|
oilwater_polymer_injectivity polymer solvent extbo)
|
||||||
add_library(flow_lib${OBJ} OBJECT flow/flow_ebos_${OBJ}.cpp)
|
add_library(flow_lib${OBJ} OBJECT flow/flow_ebos_${OBJ}.cpp)
|
||||||
list(APPEND FLOW_TGTS $<TARGET_OBJECTS:flow_lib${OBJ}>)
|
list(APPEND FLOW_TGTS $<TARGET_OBJECTS:flow_lib${OBJ}>)
|
||||||
endforeach()
|
endforeach()
|
||||||
@ -342,7 +342,7 @@ endif()
|
|||||||
# the research oriented general-purpose ECL simulator ("ebos" == &ecl
|
# the research oriented general-purpose ECL simulator ("ebos" == &ecl
|
||||||
# &black-&oil &simulator)
|
# &black-&oil &simulator)
|
||||||
set(MEBOS_TARGETS "")
|
set(MEBOS_TARGETS "")
|
||||||
foreach(OBJ blackoil solvent polymer foam brine gasoil oilwater oilwaterpolymer thermal)
|
foreach(OBJ blackoil solvent extbo polymer foam brine gasoil oilwater oilwaterpolymer thermal)
|
||||||
add_library(ebos_lib${OBJ} OBJECT EXCLUDE_FROM_ALL ebos/ebos_${OBJ}.cc)
|
add_library(ebos_lib${OBJ} OBJECT EXCLUDE_FROM_ALL ebos/ebos_${OBJ}.cc)
|
||||||
list(APPEND MEBOS_TARGETS $<TARGET_OBJECTS:ebos_lib${OBJ}>)
|
list(APPEND MEBOS_TARGETS $<TARGET_OBJECTS:ebos_lib${OBJ}>)
|
||||||
endforeach()
|
endforeach()
|
||||||
@ -366,7 +366,7 @@ else()
|
|||||||
set(EBOS_EXTENSIONS_DEFAULT_ENABLE_IF "TRUE")
|
set(EBOS_EXTENSIONS_DEFAULT_ENABLE_IF "TRUE")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
foreach(OBJ solvent polymer foam brine gasoil oilwater oilwaterpolymer thermal)
|
foreach(OBJ solvent extbo polymer foam brine gasoil oilwater oilwaterpolymer thermal)
|
||||||
opm_add_test(ebos_${OBJ}
|
opm_add_test(ebos_${OBJ}
|
||||||
ONLY_COMPILE
|
ONLY_COMPILE
|
||||||
DEFAULT_ENABLE_IF ${EBOS_EXTENSIONS_DEFAULT_ENABLE_IF}
|
DEFAULT_ENABLE_IF ${EBOS_EXTENSIONS_DEFAULT_ENABLE_IF}
|
||||||
@ -406,7 +406,7 @@ opm_add_test(ebos_plain
|
|||||||
LIBRARIES opmsimulators)
|
LIBRARIES opmsimulators)
|
||||||
|
|
||||||
if (BUILD_EBOS_EXTENSIONS)
|
if (BUILD_EBOS_EXTENSIONS)
|
||||||
foreach(TGT ebos_solvent ebos_polymer ebos_foam ebos_brine ebos_gasoil ebos_oilwater ebos_oilwaterpolymer ebos_thermal mebos)
|
foreach(TGT ebos_solvent ebos_extbo ebos_polymer ebos_foam ebos_brine ebos_gasoil ebos_oilwater ebos_oilwaterpolymer ebos_thermal mebos)
|
||||||
install(TARGETS ${TGT} DESTINATION bin)
|
install(TARGETS ${TGT} DESTINATION bin)
|
||||||
opm_add_bash_completion(${TGT})
|
opm_add_bash_completion(${TGT})
|
||||||
endforeach()
|
endforeach()
|
||||||
|
71
ebos/ebos_extbo.cc
Normal file
71
ebos/ebos_extbo.cc
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||||
|
// vi: set et ts=4 sw=4 sts=4:
|
||||||
|
/*
|
||||||
|
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 2 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/>.
|
||||||
|
|
||||||
|
Consult the COPYING file in the top-level source directory of this
|
||||||
|
module for the precise wording of the license and the list of
|
||||||
|
copyright holders.
|
||||||
|
*/
|
||||||
|
/*!
|
||||||
|
* \file
|
||||||
|
*
|
||||||
|
* \brief A general-purpose simulator for ECL decks using the black-oil model.
|
||||||
|
*/
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "ebos.hh"
|
||||||
|
#include "startEbos.hh"
|
||||||
|
|
||||||
|
namespace Opm::Properties {
|
||||||
|
|
||||||
|
namespace TTag {
|
||||||
|
struct EbosExtboTypeTag {
|
||||||
|
using InheritsFrom = std::tuple<EbosTypeTag>;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// enable the polymer extension of the black oil model
|
||||||
|
template<class TypeTag>
|
||||||
|
struct EnableExtbo<TypeTag, TTag::EbosExtboTypeTag> {
|
||||||
|
static constexpr bool value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Opm::Properties
|
||||||
|
|
||||||
|
namespace Opm {
|
||||||
|
|
||||||
|
void ebosExtboSetDeck(std::unique_ptr<Opm::Deck> deck,
|
||||||
|
std::unique_ptr<Opm::ParseContext> parseContext,
|
||||||
|
std::unique_ptr<Opm::ErrorGuard> errorGuard,
|
||||||
|
double externalSetupTime)
|
||||||
|
{
|
||||||
|
using ProblemTypeTag = Properties::TTag::EbosExtboTypeTag;
|
||||||
|
using Vanguard = GetPropType<ProblemTypeTag, Properties::Vanguard>;
|
||||||
|
|
||||||
|
Vanguard::setExternalSetupTime(externalSetupTime);
|
||||||
|
Vanguard::setExternalParseContext(std::move(parseContext));
|
||||||
|
Vanguard::setExternalErrorGuard(std::move(errorGuard));
|
||||||
|
Vanguard::setExternalDeck(std::move(deck));
|
||||||
|
}
|
||||||
|
|
||||||
|
int ebosExtboMain(int argc, char **argv)
|
||||||
|
{
|
||||||
|
using ProblemTypeTag = Properties::TTag::EbosExtboTypeTag;
|
||||||
|
return Opm::startEbos<ProblemTypeTag>(argc, argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
44
ebos/ebos_extbo.hh
Normal file
44
ebos/ebos_extbo.hh
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||||
|
// vi: set et ts=4 sw=4 sts=4:
|
||||||
|
/*
|
||||||
|
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 2 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/>.
|
||||||
|
|
||||||
|
Consult the COPYING file in the top-level source directory of this
|
||||||
|
module for the precise wording of the license and the list of
|
||||||
|
copyright holders.
|
||||||
|
*/
|
||||||
|
/*!
|
||||||
|
* \file
|
||||||
|
*
|
||||||
|
* \brief The function prototypes required to start the solvent variant of ebos
|
||||||
|
*/
|
||||||
|
#ifndef EBOS_EXTBO_HH
|
||||||
|
#define EBOS_EXTBO_HH
|
||||||
|
|
||||||
|
#include <opm/parser/eclipse/Deck/Deck.hpp>
|
||||||
|
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
|
||||||
|
#include <opm/parser/eclipse/Parser/ErrorGuard.hpp>
|
||||||
|
|
||||||
|
namespace Opm {
|
||||||
|
void ebosExtboSetDeck(Opm::Deck* deck,
|
||||||
|
Opm::ParseContext* parseContext,
|
||||||
|
Opm::ErrorGuard* errorGuard,
|
||||||
|
double externalSetupTime);
|
||||||
|
|
||||||
|
int ebosExtboMain(int argc, char** argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
37
ebos/ebos_extbo_main.cc
Normal file
37
ebos/ebos_extbo_main.cc
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||||
|
// vi: set et ts=4 sw=4 sts=4:
|
||||||
|
/*
|
||||||
|
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 2 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/>.
|
||||||
|
|
||||||
|
Consult the COPYING file in the top-level source directory of this
|
||||||
|
module for the precise wording of the license and the list of
|
||||||
|
copyright holders.
|
||||||
|
*/
|
||||||
|
/*!
|
||||||
|
* \file
|
||||||
|
*
|
||||||
|
* \brief The main function for the stand alone solvent variant of ebos.
|
||||||
|
*
|
||||||
|
* This only calls the ebosExtboMain() function.
|
||||||
|
*/
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "ebos_extbo.hh"
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
return Opm::ebosExtboMain(argc, argv);
|
||||||
|
}
|
@ -50,6 +50,7 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
typedef Opm::BlackOilTwoPhaseIndices<getPropValue<TypeTag, Properties::EnableSolvent>(),
|
typedef Opm::BlackOilTwoPhaseIndices<getPropValue<TypeTag, Properties::EnableSolvent>(),
|
||||||
|
getPropValue<TypeTag, Properties::EnableExtbo>(),
|
||||||
getPropValue<TypeTag, Properties::EnablePolymer>(),
|
getPropValue<TypeTag, Properties::EnablePolymer>(),
|
||||||
getPropValue<TypeTag, Properties::EnableEnergy>(),
|
getPropValue<TypeTag, Properties::EnableEnergy>(),
|
||||||
getPropValue<TypeTag, Properties::EnableFoam>(),
|
getPropValue<TypeTag, Properties::EnableFoam>(),
|
||||||
|
@ -50,6 +50,7 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
typedef Opm::BlackOilTwoPhaseIndices<getPropValue<TypeTag, Properties::EnableSolvent>(),
|
typedef Opm::BlackOilTwoPhaseIndices<getPropValue<TypeTag, Properties::EnableSolvent>(),
|
||||||
|
getPropValue<TypeTag, Properties::EnableExtbo>(),
|
||||||
getPropValue<TypeTag, Properties::EnablePolymer>(),
|
getPropValue<TypeTag, Properties::EnablePolymer>(),
|
||||||
getPropValue<TypeTag, Properties::EnableEnergy>(),
|
getPropValue<TypeTag, Properties::EnableEnergy>(),
|
||||||
getPropValue<TypeTag, Properties::EnableFoam>(),
|
getPropValue<TypeTag, Properties::EnableFoam>(),
|
||||||
|
@ -55,6 +55,7 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
typedef Opm::BlackOilTwoPhaseIndices<getPropValue<TypeTag, Properties::EnableSolvent>(),
|
typedef Opm::BlackOilTwoPhaseIndices<getPropValue<TypeTag, Properties::EnableSolvent>(),
|
||||||
|
getPropValue<TypeTag, Properties::EnableExtbo>(),
|
||||||
getPropValue<TypeTag, Properties::EnablePolymer>(),
|
getPropValue<TypeTag, Properties::EnablePolymer>(),
|
||||||
getPropValue<TypeTag, Properties::EnableEnergy>(),
|
getPropValue<TypeTag, Properties::EnableEnergy>(),
|
||||||
getPropValue<TypeTag, Properties::EnableFoam>(),
|
getPropValue<TypeTag, Properties::EnableFoam>(),
|
||||||
|
@ -111,6 +111,7 @@ class EclTransExtensiveQuantities
|
|||||||
enum { gasPhaseIdx = FluidSystem::gasPhaseIdx };
|
enum { gasPhaseIdx = FluidSystem::gasPhaseIdx };
|
||||||
enum { numPhases = FluidSystem::numPhases };
|
enum { numPhases = FluidSystem::numPhases };
|
||||||
enum { enableSolvent = getPropValue<TypeTag, Properties::EnableSolvent>() };
|
enum { enableSolvent = getPropValue<TypeTag, Properties::EnableSolvent>() };
|
||||||
|
enum { enableExtbo = getPropValue<TypeTag, Properties::EnableExtbo>() };
|
||||||
enum { enableEnergy = getPropValue<TypeTag, Properties::EnableEnergy>() };
|
enum { enableEnergy = getPropValue<TypeTag, Properties::EnableEnergy>() };
|
||||||
|
|
||||||
typedef Opm::MathToolbox<Evaluation> Toolbox;
|
typedef Opm::MathToolbox<Evaluation> Toolbox;
|
||||||
@ -271,6 +272,10 @@ protected:
|
|||||||
|
|
||||||
const Evaluation& pressureInterior = intQuantsIn.fluidState().pressure(phaseIdx);
|
const Evaluation& pressureInterior = intQuantsIn.fluidState().pressure(phaseIdx);
|
||||||
Evaluation pressureExterior = Toolbox::value(intQuantsEx.fluidState().pressure(phaseIdx));
|
Evaluation pressureExterior = Toolbox::value(intQuantsEx.fluidState().pressure(phaseIdx));
|
||||||
|
if (enableExtbo) // added stability; particulary useful for solvent migrating in pure water
|
||||||
|
// where the solvent fraction displays a 0/1 behaviour ...
|
||||||
|
pressureExterior += Toolbox::value(rhoAvg)*(distZ*g);
|
||||||
|
else
|
||||||
pressureExterior += rhoAvg*(distZ*g);
|
pressureExterior += rhoAvg*(distZ*g);
|
||||||
|
|
||||||
pressureDifference_[phaseIdx] = pressureExterior - pressureInterior;
|
pressureDifference_[phaseIdx] = pressureExterior - pressureInterior;
|
||||||
|
@ -396,6 +396,14 @@ public:
|
|||||||
cFoam_.resize(bufferSize, 0.0);
|
cFoam_.resize(bufferSize, 0.0);
|
||||||
if (getPropValue<TypeTag, Properties::EnableBrine>())
|
if (getPropValue<TypeTag, Properties::EnableBrine>())
|
||||||
cSalt_.resize(bufferSize, 0.0);
|
cSalt_.resize(bufferSize, 0.0);
|
||||||
|
if (getPropValue<TypeTag, Properties::EnableExtbo>()) {
|
||||||
|
extboX_.resize(bufferSize, 0.0);
|
||||||
|
extboY_.resize(bufferSize, 0.0);
|
||||||
|
extboZ_.resize(bufferSize, 0.0);
|
||||||
|
mFracOil_.resize(bufferSize, 0.0);
|
||||||
|
mFracGas_.resize(bufferSize, 0.0);
|
||||||
|
mFracCo2_.resize(bufferSize, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
if (simulator_.problem().vapparsActive())
|
if (simulator_.problem().vapparsActive())
|
||||||
soMax_.resize(bufferSize, 0.0);
|
soMax_.resize(bufferSize, 0.0);
|
||||||
@ -629,6 +637,11 @@ public:
|
|||||||
if (viscosity_[phaseIdx].size() == 0)
|
if (viscosity_[phaseIdx].size() == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (extboX_.size() > 0 && phaseIdx==oilPhaseIdx)
|
||||||
|
viscosity_[phaseIdx][globalDofIdx] = Opm::getValue(intQuants.oilViscosity());
|
||||||
|
else if (extboX_.size() > 0 && phaseIdx==gasPhaseIdx)
|
||||||
|
viscosity_[phaseIdx][globalDofIdx] = Opm::getValue(intQuants.gasViscosity());
|
||||||
|
else
|
||||||
viscosity_[phaseIdx][globalDofIdx] = Opm::getValue(fs.viscosity(phaseIdx));
|
viscosity_[phaseIdx][globalDofIdx] = Opm::getValue(fs.viscosity(phaseIdx));
|
||||||
Opm::Valgrind::CheckDefined(viscosity_[phaseIdx][globalDofIdx]);
|
Opm::Valgrind::CheckDefined(viscosity_[phaseIdx][globalDofIdx]);
|
||||||
}
|
}
|
||||||
@ -657,6 +670,34 @@ public:
|
|||||||
cSalt_[globalDofIdx] = fs.saltConcentration().value();
|
cSalt_[globalDofIdx] = fs.saltConcentration().value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (extboX_.size() > 0) {
|
||||||
|
extboX_[globalDofIdx] = intQuants.xVolume().value();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (extboY_.size() > 0) {
|
||||||
|
extboY_[globalDofIdx] = intQuants.yVolume().value();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (extboZ_.size() > 0) {
|
||||||
|
extboZ_[globalDofIdx] = intQuants.zFraction().value();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mFracCo2_.size() > 0) {
|
||||||
|
const Scalar stdVolOil = Opm::getValue(fs.saturation(oilPhaseIdx))*Opm::getValue(fs.invB(oilPhaseIdx))
|
||||||
|
+ Opm::getValue(fs.saturation(gasPhaseIdx))*Opm::getValue(fs.invB(gasPhaseIdx))*Opm::getValue(fs.Rv());
|
||||||
|
const Scalar stdVolGas = Opm::getValue(fs.saturation(gasPhaseIdx))*Opm::getValue(fs.invB(gasPhaseIdx))*(1.0-intQuants.yVolume().value())
|
||||||
|
+ Opm::getValue(fs.saturation(oilPhaseIdx))*Opm::getValue(fs.invB(oilPhaseIdx))*Opm::getValue(fs.Rs())*(1.0-intQuants.xVolume().value());
|
||||||
|
const Scalar stdVolCo2 = Opm::getValue(fs.saturation(gasPhaseIdx))*Opm::getValue(fs.invB(gasPhaseIdx))*intQuants.yVolume().value()
|
||||||
|
+ Opm::getValue(fs.saturation(oilPhaseIdx))*Opm::getValue(fs.invB(oilPhaseIdx))*Opm::getValue(fs.Rs())*intQuants.xVolume().value();
|
||||||
|
const Scalar rhoO= FluidSystem::referenceDensity(gasPhaseIdx, pvtRegionIdx);
|
||||||
|
const Scalar rhoG= FluidSystem::referenceDensity(gasPhaseIdx, pvtRegionIdx);
|
||||||
|
const Scalar rhoCO2= intQuants.zRefDensity();
|
||||||
|
const Scalar stdMassTotal= 1.0e-10 + stdVolOil*rhoO + stdVolGas*rhoG + stdVolCo2*rhoCO2;
|
||||||
|
mFracOil_[globalDofIdx] = stdVolOil*rhoO/stdMassTotal;
|
||||||
|
mFracGas_[globalDofIdx] = stdVolGas*rhoG/stdMassTotal;
|
||||||
|
mFracCo2_[globalDofIdx] = stdVolCo2*rhoCO2/stdMassTotal;
|
||||||
|
}
|
||||||
|
|
||||||
if (bubblePointPressure_.size() > 0) {
|
if (bubblePointPressure_.size() > 0) {
|
||||||
try {
|
try {
|
||||||
bubblePointPressure_[globalDofIdx] = Opm::getValue(FluidSystem::bubblePointPressure(fs, intQuants.pvtRegionIndex()));
|
bubblePointPressure_[globalDofIdx] = Opm::getValue(FluidSystem::bubblePointPressure(fs, intQuants.pvtRegionIndex()));
|
||||||
@ -1045,6 +1086,24 @@ public:
|
|||||||
if (sSol_.size() > 0)
|
if (sSol_.size() > 0)
|
||||||
sol.insert ("SSOLVENT", Opm::UnitSystem::measure::identity, std::move(sSol_), Opm::data::TargetType::RESTART_SOLUTION);
|
sol.insert ("SSOLVENT", Opm::UnitSystem::measure::identity, std::move(sSol_), Opm::data::TargetType::RESTART_SOLUTION);
|
||||||
|
|
||||||
|
if (extboX_.size() > 0)
|
||||||
|
sol.insert ("SS_X", Opm::UnitSystem::measure::identity, std::move(extboX_), Opm::data::TargetType::RESTART_SOLUTION);
|
||||||
|
|
||||||
|
if (extboY_.size() > 0)
|
||||||
|
sol.insert ("SS_Y", Opm::UnitSystem::measure::identity, std::move(extboY_), Opm::data::TargetType::RESTART_SOLUTION);
|
||||||
|
|
||||||
|
if (extboZ_.size() > 0)
|
||||||
|
sol.insert ("SS_Z", Opm::UnitSystem::measure::identity, std::move(extboZ_), Opm::data::TargetType::RESTART_SOLUTION);
|
||||||
|
|
||||||
|
if (mFracOil_.size() > 0)
|
||||||
|
sol.insert ("STD_OIL", Opm::UnitSystem::measure::identity, std::move(mFracOil_), Opm::data::TargetType::RESTART_SOLUTION);
|
||||||
|
|
||||||
|
if (mFracGas_.size() > 0)
|
||||||
|
sol.insert ("STD_GAS", Opm::UnitSystem::measure::identity, std::move(mFracGas_), Opm::data::TargetType::RESTART_SOLUTION);
|
||||||
|
|
||||||
|
if (mFracCo2_.size() > 0)
|
||||||
|
sol.insert ("STD_CO2", Opm::UnitSystem::measure::identity, std::move(mFracCo2_), Opm::data::TargetType::RESTART_SOLUTION);
|
||||||
|
|
||||||
if (cPolymer_.size() > 0)
|
if (cPolymer_.size() > 0)
|
||||||
sol.insert ("POLYMER", Opm::UnitSystem::measure::identity, std::move(cPolymer_), Opm::data::TargetType::RESTART_SOLUTION);
|
sol.insert ("POLYMER", Opm::UnitSystem::measure::identity, std::move(cPolymer_), Opm::data::TargetType::RESTART_SOLUTION);
|
||||||
|
|
||||||
@ -2290,6 +2349,12 @@ private:
|
|||||||
ScalarBuffer viscosity_[numPhases];
|
ScalarBuffer viscosity_[numPhases];
|
||||||
ScalarBuffer relativePermeability_[numPhases];
|
ScalarBuffer relativePermeability_[numPhases];
|
||||||
ScalarBuffer sSol_;
|
ScalarBuffer sSol_;
|
||||||
|
ScalarBuffer extboX_;
|
||||||
|
ScalarBuffer extboY_;
|
||||||
|
ScalarBuffer extboZ_;
|
||||||
|
ScalarBuffer mFracOil_;
|
||||||
|
ScalarBuffer mFracGas_;
|
||||||
|
ScalarBuffer mFracCo2_;
|
||||||
ScalarBuffer cPolymer_;
|
ScalarBuffer cPolymer_;
|
||||||
ScalarBuffer cFoam_;
|
ScalarBuffer cFoam_;
|
||||||
ScalarBuffer cSalt_;
|
ScalarBuffer cSalt_;
|
||||||
|
@ -534,6 +534,10 @@ template<class TypeTag>
|
|||||||
struct EnableFoam<TypeTag, TTag::EclBaseProblem> {
|
struct EnableFoam<TypeTag, TTag::EclBaseProblem> {
|
||||||
static constexpr bool value = false;
|
static constexpr bool value = false;
|
||||||
};
|
};
|
||||||
|
template<class TypeTag>
|
||||||
|
struct EnableExtbo<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>
|
||||||
@ -613,6 +617,7 @@ class EclProblem : public GetPropType<TypeTag, Properties::BaseProblem>
|
|||||||
enum { enableBrine = getPropValue<TypeTag, Properties::EnableBrine>() };
|
enum { enableBrine = getPropValue<TypeTag, Properties::EnableBrine>() };
|
||||||
enum { enablePolymerMolarWeight = getPropValue<TypeTag, Properties::EnablePolymerMW>() };
|
enum { enablePolymerMolarWeight = getPropValue<TypeTag, Properties::EnablePolymerMW>() };
|
||||||
enum { enableFoam = getPropValue<TypeTag, Properties::EnableFoam>() };
|
enum { enableFoam = getPropValue<TypeTag, Properties::EnableFoam>() };
|
||||||
|
enum { enableExtbo = getPropValue<TypeTag, Properties::EnableExtbo>() };
|
||||||
enum { enableTemperature = getPropValue<TypeTag, Properties::EnableTemperature>() };
|
enum { enableTemperature = getPropValue<TypeTag, Properties::EnableTemperature>() };
|
||||||
enum { enableEnergy = getPropValue<TypeTag, Properties::EnableEnergy>() };
|
enum { enableEnergy = getPropValue<TypeTag, Properties::EnableEnergy>() };
|
||||||
enum { enableThermalFluxBoundaries = getPropValue<TypeTag, Properties::EnableThermalFluxBoundaries>() };
|
enum { enableThermalFluxBoundaries = getPropValue<TypeTag, Properties::EnableThermalFluxBoundaries>() };
|
||||||
@ -647,6 +652,7 @@ class EclProblem : public GetPropType<TypeTag, Properties::BaseProblem>
|
|||||||
typedef BlackOilPolymerModule<TypeTag> PolymerModule;
|
typedef BlackOilPolymerModule<TypeTag> PolymerModule;
|
||||||
typedef BlackOilFoamModule<TypeTag> FoamModule;
|
typedef BlackOilFoamModule<TypeTag> FoamModule;
|
||||||
typedef BlackOilBrineModule<TypeTag> BrineModule;
|
typedef BlackOilBrineModule<TypeTag> BrineModule;
|
||||||
|
typedef BlackOilExtboModule<TypeTag> ExtboModule;
|
||||||
|
|
||||||
typedef typename EclEquilInitializer<TypeTag>::ScalarFluidState InitialFluidState;
|
typedef typename EclEquilInitializer<TypeTag>::ScalarFluidState InitialFluidState;
|
||||||
|
|
||||||
@ -812,6 +818,7 @@ public:
|
|||||||
PolymerModule::initFromState(vanguard.eclState());
|
PolymerModule::initFromState(vanguard.eclState());
|
||||||
FoamModule::initFromState(vanguard.eclState());
|
FoamModule::initFromState(vanguard.eclState());
|
||||||
BrineModule::initFromState(vanguard.eclState());
|
BrineModule::initFromState(vanguard.eclState());
|
||||||
|
ExtboModule::initFromState(vanguard.eclState());
|
||||||
|
|
||||||
// create the ECL writer
|
// create the ECL writer
|
||||||
eclWriter_.reset(new EclWriterType(simulator));
|
eclWriter_.reset(new EclWriterType(simulator));
|
||||||
@ -2176,6 +2183,11 @@ private:
|
|||||||
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 (enableExtbo && !deck.hasKeyword("PVTSOL"))
|
||||||
|
throw std::runtime_error("The simulator requires the extendedBO option to be enabled, but the deck does not.");
|
||||||
|
else if (!enableExtbo && deck.hasKeyword("PVTSOL"))
|
||||||
|
throw std::runtime_error("The deck enables the extendedBO option, but the simulator is compiled without it.");
|
||||||
|
|
||||||
if (deck.hasKeyword("TEMP") && deck.hasKeyword("THERMAL"))
|
if (deck.hasKeyword("TEMP") && deck.hasKeyword("THERMAL"))
|
||||||
throw std::runtime_error("The deck enables both, the TEMP and the THERMAL options, but they are mutually exclusive.");
|
throw std::runtime_error("The deck enables both, the TEMP and the THERMAL options, but they are mutually exclusive.");
|
||||||
|
|
||||||
|
80
flow/flow_ebos_extbo.cpp
Normal file
80
flow/flow_ebos_extbo.cpp
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
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_extbo.hpp>
|
||||||
|
|
||||||
|
#include <opm/material/common/ResetLocale.hpp>
|
||||||
|
#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 EclFlowExtboProblem {
|
||||||
|
using InheritsFrom = std::tuple<EclFlowProblem>;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
template<class TypeTag>
|
||||||
|
struct EnableExtbo<TypeTag, TTag::EclFlowExtboProblem> {
|
||||||
|
static constexpr bool value = true;
|
||||||
|
};
|
||||||
|
}}
|
||||||
|
|
||||||
|
namespace Opm {
|
||||||
|
void flowEbosExtboSetDeck(double setupTime, std::unique_ptr<Deck> deck,
|
||||||
|
std::unique_ptr<EclipseState> eclState,
|
||||||
|
std::unique_ptr<Schedule> schedule,
|
||||||
|
std::unique_ptr<SummaryConfig> summaryConfig)
|
||||||
|
{
|
||||||
|
using TypeTag = Properties::TTag::EclFlowExtboProblem;
|
||||||
|
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 flowEbosExtboMain(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.
|
||||||
|
Opm::resetLocale();
|
||||||
|
|
||||||
|
// initialize MPI, finalize is done automatically on exit
|
||||||
|
#if HAVE_DUNE_FEM
|
||||||
|
Dune::Fem::MPIManager::initialize(argc, argv);
|
||||||
|
#else
|
||||||
|
Dune::MPIHelper::instance(argc, argv).rank();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Opm::FlowMainEbos<Properties::TTag::EclFlowExtboProblem>
|
||||||
|
mainfunc {argc, argv, outputCout, outputFiles};
|
||||||
|
return mainfunc.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
33
flow/flow_ebos_extbo.hpp
Normal file
33
flow/flow_ebos_extbo.hpp
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
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_EXTBO_HPP
|
||||||
|
#define FLOW_EBOS_EXTBO_HPP
|
||||||
|
|
||||||
|
#include <opm/parser/eclipse/Deck/Deck.hpp>
|
||||||
|
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
|
||||||
|
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
|
||||||
|
#include <opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp>
|
||||||
|
|
||||||
|
namespace Opm {
|
||||||
|
void flowEbosExtboSetDeck(double setupTime, std::unique_ptr<Deck> deck,
|
||||||
|
std::unique_ptr<EclipseState> eclState,
|
||||||
|
std::unique_ptr<Schedule> schedule,
|
||||||
|
std::unique_ptr<SummaryConfig> summaryConfig);
|
||||||
|
int flowEbosExtboMain(int argc, char** argv, bool outputCout, bool outputFiles);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // FLOW_EBOS_EXTBO_HPP
|
@ -52,6 +52,7 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
typedef Opm::BlackOilTwoPhaseIndices<getPropValue<TypeTag, Properties::EnableSolvent>(),
|
typedef Opm::BlackOilTwoPhaseIndices<getPropValue<TypeTag, Properties::EnableSolvent>(),
|
||||||
|
getPropValue<TypeTag, Properties::EnableExtbo>(),
|
||||||
getPropValue<TypeTag, Properties::EnablePolymer>(),
|
getPropValue<TypeTag, Properties::EnablePolymer>(),
|
||||||
getPropValue<TypeTag, Properties::EnableEnergy>(),
|
getPropValue<TypeTag, Properties::EnableEnergy>(),
|
||||||
getPropValue<TypeTag, Properties::EnableFoam>(),
|
getPropValue<TypeTag, Properties::EnableFoam>(),
|
||||||
|
@ -52,6 +52,7 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
typedef Opm::BlackOilTwoPhaseIndices<getPropValue<TypeTag, Properties::EnableSolvent>(),
|
typedef Opm::BlackOilTwoPhaseIndices<getPropValue<TypeTag, Properties::EnableSolvent>(),
|
||||||
|
getPropValue<TypeTag, Properties::EnableExtbo>(),
|
||||||
getPropValue<TypeTag, Properties::EnablePolymer>(),
|
getPropValue<TypeTag, Properties::EnablePolymer>(),
|
||||||
getPropValue<TypeTag, Properties::EnableEnergy>(),
|
getPropValue<TypeTag, Properties::EnableEnergy>(),
|
||||||
getPropValue<TypeTag, Properties::EnableFoam>(),
|
getPropValue<TypeTag, Properties::EnableFoam>(),
|
||||||
|
@ -55,6 +55,7 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
typedef Opm::BlackOilTwoPhaseIndices<getPropValue<TypeTag, Properties::EnableSolvent>(),
|
typedef Opm::BlackOilTwoPhaseIndices<getPropValue<TypeTag, Properties::EnableSolvent>(),
|
||||||
|
getPropValue<TypeTag, Properties::EnableExtbo>(),
|
||||||
getPropValue<TypeTag, Properties::EnablePolymer>(),
|
getPropValue<TypeTag, Properties::EnablePolymer>(),
|
||||||
getPropValue<TypeTag, Properties::EnableEnergy>(),
|
getPropValue<TypeTag, Properties::EnableEnergy>(),
|
||||||
getPropValue<TypeTag, Properties::EnableFoam>(),
|
getPropValue<TypeTag, Properties::EnableFoam>(),
|
||||||
|
@ -55,6 +55,7 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
typedef Opm::BlackOilTwoPhaseIndices<getPropValue<TypeTag, Properties::EnableSolvent>(),
|
typedef Opm::BlackOilTwoPhaseIndices<getPropValue<TypeTag, Properties::EnableSolvent>(),
|
||||||
|
getPropValue<TypeTag, Properties::EnableExtbo>(),
|
||||||
getPropValue<TypeTag, Properties::EnablePolymer>(),
|
getPropValue<TypeTag, Properties::EnablePolymer>(),
|
||||||
getPropValue<TypeTag, Properties::EnableEnergy>(),
|
getPropValue<TypeTag, Properties::EnableEnergy>(),
|
||||||
getPropValue<TypeTag, Properties::EnableFoam>(),
|
getPropValue<TypeTag, Properties::EnableFoam>(),
|
||||||
|
@ -61,6 +61,7 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
typedef Opm::BlackOilTwoPhaseIndices<0,
|
typedef Opm::BlackOilTwoPhaseIndices<0,
|
||||||
|
0,
|
||||||
2,
|
2,
|
||||||
0,
|
0,
|
||||||
getPropValue<TypeTag, Properties::EnableFoam>(),
|
getPropValue<TypeTag, Properties::EnableFoam>(),
|
||||||
|
@ -43,6 +43,7 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
typedef Opm::BlackOilOnePhaseIndices<getPropValue<TypeTag, Properties::EnableSolvent>(),
|
typedef Opm::BlackOilOnePhaseIndices<getPropValue<TypeTag, Properties::EnableSolvent>(),
|
||||||
|
getPropValue<TypeTag, Properties::EnableExtbo>(),
|
||||||
getPropValue<TypeTag, Properties::EnablePolymer>(),
|
getPropValue<TypeTag, Properties::EnablePolymer>(),
|
||||||
getPropValue<TypeTag, Properties::EnableEnergy>(),
|
getPropValue<TypeTag, Properties::EnableEnergy>(),
|
||||||
getPropValue<TypeTag, Properties::EnableFoam>(),
|
getPropValue<TypeTag, Properties::EnableFoam>(),
|
||||||
|
@ -46,6 +46,7 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
typedef Opm::BlackOilOnePhaseIndices<getPropValue<TypeTag, Properties::EnableSolvent>(),
|
typedef Opm::BlackOilOnePhaseIndices<getPropValue<TypeTag, Properties::EnableSolvent>(),
|
||||||
|
getPropValue<TypeTag, Properties::EnableExtbo>(),
|
||||||
getPropValue<TypeTag, Properties::EnablePolymer>(),
|
getPropValue<TypeTag, Properties::EnablePolymer>(),
|
||||||
getPropValue<TypeTag, Properties::EnableEnergy>(),
|
getPropValue<TypeTag, Properties::EnableEnergy>(),
|
||||||
getPropValue<TypeTag, Properties::EnableFoam>(),
|
getPropValue<TypeTag, Properties::EnableFoam>(),
|
||||||
|
@ -34,10 +34,10 @@ namespace Opm
|
|||||||
// to and from active ones. That said, they are not considered by num_phases or
|
// to and from active ones. That said, they are not considered by num_phases or
|
||||||
// MaxNumPhases. The crypto phases which are currently implemented are solvent,
|
// MaxNumPhases. The crypto phases which are currently implemented are solvent,
|
||||||
// polymer, energy, polymer molecular weight, foam and brine.
|
// polymer, energy, polymer molecular weight, foam and brine.
|
||||||
static const int NumCryptoPhases = 6;
|
static const int NumCryptoPhases = 7;
|
||||||
|
|
||||||
// enum ComponentIndex { Water = 0, Oil = 1, Gas = 2 };
|
// enum ComponentIndex { Water = 0, Oil = 1, Gas = 2 };
|
||||||
enum PhaseIndex { Aqua = 0, Liquid = 1, Vapour = 2, Solvent = 3, Polymer = 4, Energy = 5, PolymerMW = 6, Foam = 7, Brine = 8 };
|
enum PhaseIndex { Aqua = 0, Liquid = 1, Vapour = 2, Solvent = 3, Polymer = 4, Energy = 5, PolymerMW = 6, Foam = 7, Brine = 8, ZFraction = 9 };
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PhaseUsage : public BlackoilPhases
|
struct PhaseUsage : public BlackoilPhases
|
||||||
@ -52,6 +52,8 @@ namespace Opm
|
|||||||
bool has_polymermw;
|
bool has_polymermw;
|
||||||
bool has_foam;
|
bool has_foam;
|
||||||
bool has_brine;
|
bool has_brine;
|
||||||
|
bool has_zFraction;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Check or assign presence of a formed, free phase. Limited to
|
/// Check or assign presence of a formed, free phase. Limited to
|
||||||
|
@ -132,6 +132,16 @@ namespace Opm
|
|||||||
else
|
else
|
||||||
pu.phase_pos[BlackoilPhases::Brine] = -1;
|
pu.phase_pos[BlackoilPhases::Brine] = -1;
|
||||||
|
|
||||||
|
// Add zFraction info
|
||||||
|
pu.has_zFraction = phases.active(Phase::ZFRACTION);
|
||||||
|
if (pu.has_zFraction) {
|
||||||
|
pu.phase_pos[BlackoilPhases::ZFraction] = numActivePhases;
|
||||||
|
++ numActivePhases;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pu.phase_pos[BlackoilPhases::ZFraction] = -1;
|
||||||
|
|
||||||
|
|
||||||
return pu;
|
return pu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
# include <flow/flow_ebos_oilwater.hpp>
|
# include <flow/flow_ebos_oilwater.hpp>
|
||||||
# include <flow/flow_ebos_solvent.hpp>
|
# include <flow/flow_ebos_solvent.hpp>
|
||||||
# include <flow/flow_ebos_polymer.hpp>
|
# include <flow/flow_ebos_polymer.hpp>
|
||||||
|
# include <flow/flow_ebos_extbo.hpp>
|
||||||
# include <flow/flow_ebos_foam.hpp>
|
# include <flow/flow_ebos_foam.hpp>
|
||||||
# include <flow/flow_ebos_brine.hpp>
|
# include <flow/flow_ebos_brine.hpp>
|
||||||
# include <flow/flow_ebos_oilwater_brine.hpp>
|
# include <flow/flow_ebos_oilwater_brine.hpp>
|
||||||
@ -292,6 +293,14 @@ namespace Opm
|
|||||||
std::move(summaryConfig_));
|
std::move(summaryConfig_));
|
||||||
return Opm::flowEbosSolventMain(argc_, argv_, outputCout_, outputFiles_);
|
return Opm::flowEbosSolventMain(argc_, argv_, outputCout_, outputFiles_);
|
||||||
}
|
}
|
||||||
|
// Extended BO case
|
||||||
|
else if ( phases.active( Opm::Phase::ZFRACTION ) ) {
|
||||||
|
Opm::flowEbosExtboSetDeck(setupTime_, std::move(deck_),
|
||||||
|
std::move(eclipseState_),
|
||||||
|
std::move(schedule_),
|
||||||
|
std::move(summaryConfig_));
|
||||||
|
return Opm::flowEbosExtboMain(argc_, argv_, outputCout_, outputFiles_);
|
||||||
|
}
|
||||||
// Energy case
|
// Energy case
|
||||||
else if (eclipseState_->getSimulationConfig().isThermal()) {
|
else if (eclipseState_->getSimulationConfig().isThermal()) {
|
||||||
Opm::flowEbosEnergySetDeck(setupTime_, std::move(deck_),
|
Opm::flowEbosEnergySetDeck(setupTime_, std::move(deck_),
|
||||||
|
@ -296,6 +296,7 @@ namespace Opm {
|
|||||||
const ModelParameters param_;
|
const ModelParameters param_;
|
||||||
bool terminal_output_;
|
bool terminal_output_;
|
||||||
bool has_solvent_;
|
bool has_solvent_;
|
||||||
|
bool has_zFraction_;
|
||||||
bool has_polymer_;
|
bool has_polymer_;
|
||||||
std::vector<int> pvt_region_idx_;
|
std::vector<int> pvt_region_idx_;
|
||||||
PhaseUsage phase_usage_;
|
PhaseUsage phase_usage_;
|
||||||
|
@ -33,6 +33,7 @@ namespace Opm {
|
|||||||
BlackoilWellModel(Simulator& ebosSimulator)
|
BlackoilWellModel(Simulator& ebosSimulator)
|
||||||
: ebosSimulator_(ebosSimulator)
|
: ebosSimulator_(ebosSimulator)
|
||||||
, has_solvent_(getPropValue<TypeTag, Properties::EnableSolvent>())
|
, has_solvent_(getPropValue<TypeTag, Properties::EnableSolvent>())
|
||||||
|
, has_zFraction_(getPropValue<TypeTag, Properties::EnableExtbo>())
|
||||||
, has_polymer_(getPropValue<TypeTag, Properties::EnablePolymer>())
|
, has_polymer_(getPropValue<TypeTag, Properties::EnablePolymer>())
|
||||||
{
|
{
|
||||||
terminal_output_ = false;
|
terminal_output_ = false;
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
|
|
||||||
#include <opm/models/blackoil/blackoilpolymermodules.hh>
|
#include <opm/models/blackoil/blackoilpolymermodules.hh>
|
||||||
#include <opm/models/blackoil/blackoilsolventmodules.hh>
|
#include <opm/models/blackoil/blackoilsolventmodules.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>
|
||||||
|
|
||||||
@ -74,6 +75,7 @@ namespace Opm
|
|||||||
using Base::numEq;
|
using Base::numEq;
|
||||||
|
|
||||||
using Base::has_solvent;
|
using Base::has_solvent;
|
||||||
|
using Base::has_zFraction;
|
||||||
using Base::has_polymer;
|
using Base::has_polymer;
|
||||||
using Base::has_foam;
|
using Base::has_foam;
|
||||||
using Base::has_brine;
|
using Base::has_brine;
|
||||||
@ -89,9 +91,10 @@ namespace Opm
|
|||||||
static const int numEnergyEq = Indices::numEnergy;
|
static const int numEnergyEq = Indices::numEnergy;
|
||||||
static const int numFoamEq = Indices::numFoam;
|
static const int numFoamEq = Indices::numFoam;
|
||||||
static const int numBrineEq = Indices::numBrine;
|
static const int numBrineEq = Indices::numBrine;
|
||||||
|
static const int numExtbos = Indices::numExtbos;
|
||||||
|
|
||||||
// number of the conservation equations
|
// number of the conservation equations
|
||||||
static const int numWellConservationEq = numEq - numPolymerEq - numEnergyEq - numFoamEq - numBrineEq;
|
static const int numWellConservationEq = numEq - numPolymerEq - numEnergyEq - numFoamEq - numBrineEq - numExtbos;
|
||||||
// number of the well control equations
|
// number of the well control equations
|
||||||
static const int numWellControlEq = 1;
|
static const int numWellControlEq = 1;
|
||||||
// number of the well equations that will always be used
|
// number of the well equations that will always be used
|
||||||
@ -147,6 +150,7 @@ namespace Opm
|
|||||||
typedef DenseAd::DynamicEvaluation<Scalar, numStaticWellEq + numEq + 1> EvalWell;
|
typedef DenseAd::DynamicEvaluation<Scalar, numStaticWellEq + numEq + 1> EvalWell;
|
||||||
|
|
||||||
using Base::contiSolventEqIdx;
|
using Base::contiSolventEqIdx;
|
||||||
|
using Base::contiZfracEqIdx;
|
||||||
using Base::contiPolymerEqIdx;
|
using Base::contiPolymerEqIdx;
|
||||||
using Base::contiFoamEqIdx;
|
using Base::contiFoamEqIdx;
|
||||||
using Base::contiBrineEqIdx;
|
using Base::contiBrineEqIdx;
|
||||||
@ -523,6 +527,7 @@ namespace Opm
|
|||||||
std::vector<RateVector>& connectionRates,
|
std::vector<RateVector>& connectionRates,
|
||||||
std::vector<EvalWell>& cq_s,
|
std::vector<EvalWell>& cq_s,
|
||||||
EvalWell& water_flux_s,
|
EvalWell& water_flux_s,
|
||||||
|
EvalWell& cq_s_zfrac_effective,
|
||||||
Opm::DeferredLogger& deferred_logger) const;
|
Opm::DeferredLogger& deferred_logger) const;
|
||||||
|
|
||||||
// check whether the well is operable under the current reservoir condition
|
// check whether the well is operable under the current reservoir condition
|
||||||
|
@ -388,6 +388,12 @@ namespace Opm
|
|||||||
b_perfcells_dense[contiSolventEqIdx] = extendEval(intQuants.solventInverseFormationVolumeFactor());
|
b_perfcells_dense[contiSolventEqIdx] = extendEval(intQuants.solventInverseFormationVolumeFactor());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (has_zFraction && this->isInjector()) {
|
||||||
|
const unsigned gasCompIdx = Indices::canonicalToActiveComponentIndex(FluidSystem::gasCompIdx);
|
||||||
|
b_perfcells_dense[gasCompIdx] *= (1.0 - wsolvent());
|
||||||
|
b_perfcells_dense[gasCompIdx] += wsolvent()*intQuants.zPureInvFormationVolumeFactor().value();
|
||||||
|
}
|
||||||
|
|
||||||
// Pressure drawdown (also used to determine direction of flow)
|
// Pressure drawdown (also used to determine direction of flow)
|
||||||
const EvalWell well_pressure = bhp + perf_pressure_diffs_[perf];
|
const EvalWell well_pressure = bhp + perf_pressure_diffs_[perf];
|
||||||
EvalWell drawdown = pressure - well_pressure;
|
EvalWell drawdown = pressure - well_pressure;
|
||||||
@ -605,7 +611,8 @@ namespace Opm
|
|||||||
// Calculate perforation quantities.
|
// Calculate perforation quantities.
|
||||||
std::vector<EvalWell> cq_s(num_components_, {numWellEq_ + numEq, 0.0});
|
std::vector<EvalWell> cq_s(num_components_, {numWellEq_ + numEq, 0.0});
|
||||||
EvalWell water_flux_s{numWellEq_ + numEq, 0.0};
|
EvalWell water_flux_s{numWellEq_ + numEq, 0.0};
|
||||||
calculateSinglePerf(ebosSimulator, perf, well_state, connectionRates, cq_s, water_flux_s, deferred_logger);
|
EvalWell cq_s_zfrac_effective{numWellEq_ + numEq, 0.0};
|
||||||
|
calculateSinglePerf(ebosSimulator, perf, well_state, connectionRates, cq_s, water_flux_s, cq_s_zfrac_effective, deferred_logger);
|
||||||
|
|
||||||
// Equation assembly for this perforation.
|
// Equation assembly for this perforation.
|
||||||
if (has_polymer && this->has_polymermw && this->isInjector()) {
|
if (has_polymer && this->has_polymermw && this->isInjector()) {
|
||||||
@ -639,6 +646,12 @@ namespace Opm
|
|||||||
well_state.perfPhaseRates()[(first_perf_ + perf) * np + ebosCompIdxToFlowCompIdx(componentIdx)] = cq_s[componentIdx].value();
|
well_state.perfPhaseRates()[(first_perf_ + perf) * np + ebosCompIdxToFlowCompIdx(componentIdx)] = cq_s[componentIdx].value();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (has_zFraction) {
|
||||||
|
for (int pvIdx = 0; pvIdx < numWellEq_; ++pvIdx) {
|
||||||
|
duneC_[0][cell_idx][pvIdx][contiZfracEqIdx] -= cq_s_zfrac_effective.derivative(pvIdx+numEq);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Update the connection
|
// Update the connection
|
||||||
connectionRates_ = connectionRates;
|
connectionRates_ = connectionRates;
|
||||||
@ -686,6 +699,7 @@ namespace Opm
|
|||||||
std::vector<RateVector>& connectionRates,
|
std::vector<RateVector>& connectionRates,
|
||||||
std::vector<EvalWell>& cq_s,
|
std::vector<EvalWell>& cq_s,
|
||||||
EvalWell& water_flux_s,
|
EvalWell& water_flux_s,
|
||||||
|
EvalWell& cq_s_zfrac_effective,
|
||||||
Opm::DeferredLogger& deferred_logger) const
|
Opm::DeferredLogger& deferred_logger) const
|
||||||
{
|
{
|
||||||
const bool allow_cf = getAllowCrossFlow() || openCrossFlowAvoidSingularity(ebosSimulator);
|
const bool allow_cf = getAllowCrossFlow() || openCrossFlowAvoidSingularity(ebosSimulator);
|
||||||
@ -812,6 +826,22 @@ namespace Opm
|
|||||||
connectionRates[perf][contiFoamEqIdx] = Base::restrictEval(cq_s_foam);
|
connectionRates[perf][contiFoamEqIdx] = Base::restrictEval(cq_s_foam);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (has_zFraction) {
|
||||||
|
// TODO: the application of well efficiency factor has not been tested with an example yet
|
||||||
|
const unsigned gasCompIdx = Indices::canonicalToActiveComponentIndex(FluidSystem::gasCompIdx);
|
||||||
|
cq_s_zfrac_effective = cq_s[gasCompIdx];
|
||||||
|
if (this->isInjector()) {
|
||||||
|
cq_s_zfrac_effective *= wsolvent();
|
||||||
|
} else if (cq_s_zfrac_effective.value() != 0.0) {
|
||||||
|
const double dis_gas_frac = perf_dis_gas_rate / cq_s_zfrac_effective.value();
|
||||||
|
cq_s_zfrac_effective *= extendEval(dis_gas_frac*intQuants.xVolume() + (1.0-dis_gas_frac)*intQuants.yVolume());
|
||||||
|
}
|
||||||
|
well_state.perfRateSolvent()[first_perf_ + perf] = cq_s_zfrac_effective.value();
|
||||||
|
|
||||||
|
cq_s_zfrac_effective *= well_efficiency_factor_;
|
||||||
|
connectionRates[perf][contiZfracEqIdx] = Base::restrictEval(cq_s_zfrac_effective);
|
||||||
|
}
|
||||||
|
|
||||||
if (has_brine) {
|
if (has_brine) {
|
||||||
// TODO: the application of well efficiency factor has not been tested with an example yet
|
// TODO: the application of well efficiency factor has not been tested with an example yet
|
||||||
const unsigned waterCompIdx = Indices::canonicalToActiveComponentIndex(FluidSystem::waterCompIdx);
|
const unsigned waterCompIdx = Indices::canonicalToActiveComponentIndex(FluidSystem::waterCompIdx);
|
||||||
@ -1978,7 +2008,7 @@ namespace Opm
|
|||||||
const double oilrate = std::abs(well_state.wellRates()[oilpos_well]); //in order to handle negative rates in producers
|
const double oilrate = std::abs(well_state.wellRates()[oilpos_well]); //in order to handle negative rates in producers
|
||||||
rvmax_perf[perf] = FluidSystem::gasPvt().saturatedOilVaporizationFactor(fs.pvtRegionIndex(), temperature, p_avg);
|
rvmax_perf[perf] = FluidSystem::gasPvt().saturatedOilVaporizationFactor(fs.pvtRegionIndex(), temperature, p_avg);
|
||||||
if (oilrate > 0) {
|
if (oilrate > 0) {
|
||||||
const double gasrate = std::abs(well_state.wellRates()[gaspos_well]) - well_state.solventWellRate(w);
|
const double gasrate = std::abs(well_state.wellRates()[gaspos_well]) - (has_solvent ? well_state.solventWellRate(w) : 0.0);
|
||||||
double rv = 0.0;
|
double rv = 0.0;
|
||||||
if (gasrate > 0) {
|
if (gasrate > 0) {
|
||||||
rv = oilrate / gasrate;
|
rv = oilrate / gasrate;
|
||||||
@ -2003,7 +2033,7 @@ namespace Opm
|
|||||||
if (gasPresent) {
|
if (gasPresent) {
|
||||||
rsmax_perf[perf] = FluidSystem::oilPvt().saturatedGasDissolutionFactor(fs.pvtRegionIndex(), temperature, p_avg);
|
rsmax_perf[perf] = FluidSystem::oilPvt().saturatedGasDissolutionFactor(fs.pvtRegionIndex(), temperature, p_avg);
|
||||||
const int gaspos_well = pu.phase_pos[Gas] + w * pu.num_phases;
|
const int gaspos_well = pu.phase_pos[Gas] + w * pu.num_phases;
|
||||||
const double gasrate = std::abs(well_state.wellRates()[gaspos_well]) - well_state.solventWellRate(w);
|
const double gasrate = std::abs(well_state.wellRates()[gaspos_well]) - (has_solvent ? well_state.solventWellRate(w) : 0.0);
|
||||||
if (gasrate > 0) {
|
if (gasrate > 0) {
|
||||||
const double oilrate = std::abs(well_state.wellRates()[oilpos_well]);
|
const double oilrate = std::abs(well_state.wellRates()[oilpos_well]);
|
||||||
double rs = 0.0;
|
double rs = 0.0;
|
||||||
@ -2224,7 +2254,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()) == num_components_) || has_polymer || has_energy || has_foam || has_brine);
|
assert((int(B_avg.size()) == num_components_) || has_polymer || has_energy || has_foam || has_brine || has_zFraction);
|
||||||
|
|
||||||
const double tol_wells = param_.tolerance_wells_;
|
const double tol_wells = param_.tolerance_wells_;
|
||||||
const double maxResidualAllowed = param_.max_residual_allowed_;
|
const double maxResidualAllowed = param_.max_residual_allowed_;
|
||||||
@ -2900,7 +2930,8 @@ namespace Opm
|
|||||||
primary_variables_[WFrac] = scalingFactor(pu.phase_pos[Water]) * well_state.wellRates()[np*well_index + pu.phase_pos[Water]] / total_well_rate;
|
primary_variables_[WFrac] = scalingFactor(pu.phase_pos[Water]) * well_state.wellRates()[np*well_index + pu.phase_pos[Water]] / total_well_rate;
|
||||||
}
|
}
|
||||||
if (FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx)) {
|
if (FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx)) {
|
||||||
primary_variables_[GFrac] = scalingFactor(pu.phase_pos[Gas]) * (well_state.wellRates()[np*well_index + pu.phase_pos[Gas]] - well_state.solventWellRate(well_index)) / total_well_rate ;
|
primary_variables_[GFrac] = scalingFactor(pu.phase_pos[Gas]) * (well_state.wellRates()[np*well_index + pu.phase_pos[Gas]]
|
||||||
|
- (has_solvent ? well_state.solventWellRate(well_index) : 0.0) ) / total_well_rate ;
|
||||||
}
|
}
|
||||||
if (has_solvent) {
|
if (has_solvent) {
|
||||||
primary_variables_[SFrac] = scalingFactor(pu.phase_pos[Gas]) * well_state.solventWellRate(well_index) / total_well_rate ;
|
primary_variables_[SFrac] = scalingFactor(pu.phase_pos[Gas]) * well_state.solventWellRate(well_index) / total_well_rate ;
|
||||||
@ -2919,8 +2950,9 @@ namespace Opm
|
|||||||
|
|
||||||
if (FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx)) {
|
if (FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx)) {
|
||||||
if (phase == InjectorType::GAS) {
|
if (phase == InjectorType::GAS) {
|
||||||
primary_variables_[GFrac] = 1.0 - wsolvent();
|
primary_variables_[GFrac] = 1.0;
|
||||||
if (has_solvent) {
|
if (has_solvent) {
|
||||||
|
primary_variables_[GFrac] = 1.0 - wsolvent();
|
||||||
primary_variables_[SFrac] = wsolvent();
|
primary_variables_[SFrac] = wsolvent();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -92,6 +92,7 @@ namespace Opm
|
|||||||
typedef DenseAd::Evaluation<double, /*size=*/numEq> Eval;
|
typedef DenseAd::Evaluation<double, /*size=*/numEq> Eval;
|
||||||
|
|
||||||
static const bool has_solvent = getPropValue<TypeTag, Properties::EnableSolvent>();
|
static const bool has_solvent = getPropValue<TypeTag, Properties::EnableSolvent>();
|
||||||
|
static const bool has_zFraction = getPropValue<TypeTag, Properties::EnableExtbo>();
|
||||||
static const bool has_polymer = getPropValue<TypeTag, Properties::EnablePolymer>();
|
static const bool has_polymer = getPropValue<TypeTag, Properties::EnablePolymer>();
|
||||||
static const bool has_energy = getPropValue<TypeTag, Properties::EnableEnergy>();
|
static const bool has_energy = getPropValue<TypeTag, Properties::EnableEnergy>();
|
||||||
static const bool has_temperature = getPropValue<TypeTag, Properties::EnableTemperature>();
|
static const bool has_temperature = getPropValue<TypeTag, Properties::EnableTemperature>();
|
||||||
@ -100,6 +101,7 @@ namespace Opm
|
|||||||
static const bool has_foam = getPropValue<TypeTag, Properties::EnableFoam>();
|
static const bool has_foam = getPropValue<TypeTag, Properties::EnableFoam>();
|
||||||
static const bool has_brine = getPropValue<TypeTag, Properties::EnableBrine>();
|
static const bool has_brine = getPropValue<TypeTag, Properties::EnableBrine>();
|
||||||
static const int contiSolventEqIdx = Indices::contiSolventEqIdx;
|
static const int contiSolventEqIdx = Indices::contiSolventEqIdx;
|
||||||
|
static const int contiZfracEqIdx = Indices::contiZfracEqIdx;
|
||||||
static const int contiPolymerEqIdx = Indices::contiPolymerEqIdx;
|
static const int contiPolymerEqIdx = Indices::contiPolymerEqIdx;
|
||||||
// index for the polymer molecular weight continuity equation
|
// index for the polymer molecular weight continuity equation
|
||||||
static const int contiPolymerMWEqIdx = Indices::contiPolymerMWEqIdx;
|
static const int contiPolymerMWEqIdx = Indices::contiPolymerMWEqIdx;
|
||||||
|
@ -94,7 +94,7 @@ namespace Opm
|
|||||||
|
|
||||||
wsolvent_ = 0.0;
|
wsolvent_ = 0.0;
|
||||||
|
|
||||||
if (has_solvent && well.isInjector()) {
|
if ((has_solvent || has_zFraction) && well.isInjector()) {
|
||||||
auto injectorType = well_ecl_.injectorType();
|
auto injectorType = well_ecl_.injectorType();
|
||||||
if (injectorType == InjectorType::GAS) {
|
if (injectorType == InjectorType::GAS) {
|
||||||
wsolvent_ = well_ecl_.getSolventFraction();
|
wsolvent_ = well_ecl_.getSolventFraction();
|
||||||
|
@ -163,7 +163,6 @@ namespace Opm
|
|||||||
|
|
||||||
perfRateBrine_.clear();
|
perfRateBrine_.clear();
|
||||||
perfRateBrine_.resize(nperf, 0.0);
|
perfRateBrine_.resize(nperf, 0.0);
|
||||||
|
|
||||||
// intialize wells that have been there before
|
// intialize wells that have been there before
|
||||||
// order may change so the mapping is based on the well name
|
// order may change so the mapping is based on the well name
|
||||||
if (prevState && !prevState->wellMap().empty()) {
|
if (prevState && !prevState->wellMap().empty()) {
|
||||||
@ -576,7 +575,7 @@ namespace Opm
|
|||||||
well.rates.set( rt::well_potential_gas, this->well_potentials_[well_rate_index + pu.phase_pos[Gas]] );
|
well.rates.set( rt::well_potential_gas, this->well_potentials_[well_rate_index + pu.phase_pos[Gas]] );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( pu.has_solvent ) {
|
if ( pu.has_solvent || pu.has_zFraction) {
|
||||||
well.rates.set( rt::solvent, solventWellRate(w) );
|
well.rates.set( rt::solvent, solventWellRate(w) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -621,7 +620,7 @@ namespace Opm
|
|||||||
if ( pu.has_brine ) {
|
if ( pu.has_brine ) {
|
||||||
comp.rates.set( rt::brine, this->perfRateBrine()[wt.second[1] + local_comp_index]);
|
comp.rates.set( rt::brine, this->perfRateBrine()[wt.second[1] + local_comp_index]);
|
||||||
}
|
}
|
||||||
if ( pu.has_solvent ) {
|
if ( pu.has_solvent || pu.has_zFraction) {
|
||||||
comp.rates.set( rt::solvent, this->perfRateSolvent()[wt.second[1] + local_comp_index]);
|
comp.rates.set( rt::solvent, this->perfRateSolvent()[wt.second[1] + local_comp_index]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user