blackoilsolventparams: introduce translation unit

move code for loading parameters from eclipse state into it
This commit is contained in:
Arne Morten Kvarving 2024-09-03 13:54:04 +02:00
parent 6ceeb3098e
commit 55a0a6da54
5 changed files with 363 additions and 287 deletions

View File

@ -60,6 +60,7 @@ list (APPEND MAIN_SOURCE_FILES
opm/models/blackoil/blackoilfoamparams.cpp
opm/models/blackoil/blackoilmicpparams.cpp
opm/models/blackoil/blackoilpolymerparams.cpp
opm/models/blackoil/blackoilsolventparams.cpp
opm/simulators/flow/ActionHandler.cpp
opm/simulators/flow/Banners.cpp
opm/simulators/flow/BlackoilModelParameters.cpp

View File

@ -40,18 +40,6 @@
#include <opm/models/io/vtkblackoilsolventmodule.hh>
#if HAVE_ECL_INPUT
#include <opm/input/eclipse/EclipseState/EclipseState.hpp>
#include <opm/input/eclipse/EclipseState/Tables/SsfnTable.hpp>
#include <opm/input/eclipse/EclipseState/Tables/Sof2Table.hpp>
#include <opm/input/eclipse/EclipseState/Tables/MsfnTable.hpp>
#include <opm/input/eclipse/EclipseState/Tables/PmiscTable.hpp>
#include <opm/input/eclipse/EclipseState/Tables/MiscTable.hpp>
#include <opm/input/eclipse/EclipseState/Tables/SorwmisTable.hpp>
#include <opm/input/eclipse/EclipseState/Tables/SgcwmisTable.hpp>
#include <opm/input/eclipse/EclipseState/Tables/TlpmixpaTable.hpp>
#endif
#include <opm/material/common/Valgrind.hpp>
#include <dune/common/fvector.hh>
@ -97,261 +85,12 @@ class BlackOilSolventModule
static constexpr bool blackoilConserveSurfaceVolume = getPropValue<TypeTag, Properties::BlackoilConserveSurfaceVolume>();
static constexpr int waterPhaseIdx = FluidSystem::waterPhaseIdx;
public:
#if HAVE_ECL_INPUT
/*!
* \brief Initialize all internal data structures needed by the solvent module
*/
static void initFromState(const EclipseState& eclState, const Schedule& schedule)
//! \brief Set parameters.
static void setParams(BlackOilSolventParams<Scalar>&& params)
{
// some sanity checks: if solvents are enabled, the SOLVENT keyword must be
// present, if solvents are disabled the keyword must not be present.
if (enableSolvent && !eclState.runspec().phases().active(Phase::SOLVENT))
throw std::runtime_error("Non-trivial solvent treatment requested at compile "
"time, but the deck does not contain the SOLVENT keyword");
else if (!enableSolvent && eclState.runspec().phases().active(Phase::SOLVENT))
throw std::runtime_error("Solvent treatment disabled at compile time, but the deck "
"contains the SOLVENT keyword");
if (!eclState.runspec().phases().active(Phase::SOLVENT))
return; // solvent treatment is supposed to be disabled
params_.co2sol_ = eclState.runspec().co2Sol();
params_.h2sol_ = eclState.runspec().h2Sol();
if (isCO2Sol() && isH2Sol()) {
throw std::runtime_error("CO2SOL and H2SOL can not be used together");
}
if (isCO2Sol() || isH2Sol() ) {
if (isCO2Sol()) {
params_.co2GasPvt_.initFromState(eclState, schedule);
params_.brineCo2Pvt_.initFromState(eclState, schedule);
} else {
params_.h2GasPvt_.initFromState(eclState, schedule);
params_.brineH2Pvt_.initFromState(eclState, schedule);
}
if (eclState.getSimulationConfig().hasDISGASW()) {
params_.rsSolw_active_ = true;
}
} else
params_.solventPvt_.initFromState(eclState, schedule);
const auto& tableManager = eclState.getTableManager();
// initialize the objects which deal with the SSFN keyword
const auto& ssfnTables = tableManager.getSsfnTables();
unsigned numSatRegions = tableManager.getTabdims().getNumSatTables();
params_.setNumSatRegions(numSatRegions);
for (unsigned satRegionIdx = 0; satRegionIdx < numSatRegions; ++ satRegionIdx) {
const auto& ssfnTable = ssfnTables.template getTable<SsfnTable>(satRegionIdx);
params_.ssfnKrg_[satRegionIdx].setXYContainers(ssfnTable.getSolventFractionColumn(),
ssfnTable.getGasRelPermMultiplierColumn(),
/*sortInput=*/true);
params_.ssfnKrs_[satRegionIdx].setXYContainers(ssfnTable.getSolventFractionColumn(),
ssfnTable.getSolventRelPermMultiplierColumn(),
/*sortInput=*/true);
}
// initialize the objects needed for miscible solvent and oil simulations
params_.isMiscible_ = false;
if (!eclState.getTableManager().getMiscTables().empty()) {
params_.isMiscible_ = true;
unsigned numMiscRegions = 1;
// misicible hydrocabon relative permeability wrt water
const auto& sof2Tables = tableManager.getSof2Tables();
if (!sof2Tables.empty()) {
// resize the attributes of the object
params_.sof2Krn_.resize(numSatRegions);
for (unsigned satRegionIdx = 0; satRegionIdx < numSatRegions; ++ satRegionIdx) {
const auto& sof2Table = sof2Tables.template getTable<Sof2Table>(satRegionIdx);
params_.sof2Krn_[satRegionIdx].setXYContainers(sof2Table.getSoColumn(),
sof2Table.getKroColumn(),
/*sortInput=*/true);
}
}
else if(eclState.runspec().phases().active(Phase::OIL))
throw std::runtime_error("SOF2 must be specified in MISCIBLE (SOLVENT and OIL) runs\n");
const auto& miscTables = tableManager.getMiscTables();
if (!miscTables.empty()) {
assert(numMiscRegions == miscTables.size());
// resize the attributes of the object
params_.misc_.resize(numMiscRegions);
for (unsigned miscRegionIdx = 0; miscRegionIdx < numMiscRegions; ++miscRegionIdx) {
const auto& miscTable = miscTables.template getTable<MiscTable>(miscRegionIdx);
// solventFraction = Ss / (Ss + Sg);
const auto& solventFraction = miscTable.getSolventFractionColumn();
const auto& misc = miscTable.getMiscibilityColumn();
params_.misc_[miscRegionIdx].setXYContainers(solventFraction, misc);
}
}
else
throw std::runtime_error("MISC must be specified in MISCIBLE (SOLVENT) runs\n");
// resize the attributes of the object
params_.pmisc_.resize(numMiscRegions);
const auto& pmiscTables = tableManager.getPmiscTables();
if (!pmiscTables.empty()) {
assert(numMiscRegions == pmiscTables.size());
for (unsigned regionIdx = 0; regionIdx < numMiscRegions; ++regionIdx) {
const auto& pmiscTable = pmiscTables.template getTable<PmiscTable>(regionIdx);
// Copy data
const auto& po = pmiscTable.getOilPhasePressureColumn();
const auto& pmisc = pmiscTable.getMiscibilityColumn();
params_.pmisc_[regionIdx].setXYContainers(po, pmisc);
}
}
else {
std::vector<double> x = {0.0,1.0e20};
std::vector<double> y = {1.0,1.0};
TabulatedFunction constant = TabulatedFunction(2, x, y);
for (unsigned regionIdx = 0; regionIdx < numMiscRegions; ++regionIdx) {
params_.pmisc_[regionIdx] = constant;
}
}
// miscible relative permeability multipleiers
params_.msfnKrsg_.resize(numSatRegions);
params_.msfnKro_.resize(numSatRegions);
const auto& msfnTables = tableManager.getMsfnTables();
if (!msfnTables.empty()) {
assert(numSatRegions == msfnTables.size());
for (unsigned regionIdx = 0; regionIdx < numSatRegions; ++regionIdx) {
const MsfnTable& msfnTable = msfnTables.template getTable<MsfnTable>(regionIdx);
// Copy data
// Ssg = Ss + Sg;
const auto& Ssg = msfnTable.getGasPhaseFractionColumn();
const auto& krsg = msfnTable.getGasSolventRelpermMultiplierColumn();
const auto& kro = msfnTable.getOilRelpermMultiplierColumn();
params_.msfnKrsg_[regionIdx].setXYContainers(Ssg, krsg);
params_.msfnKro_[regionIdx].setXYContainers(Ssg, kro);
}
}
else {
std::vector<double> x = {0.0,1.0};
std::vector<double> y = {1.0,0.0};
TabulatedFunction unit = TabulatedFunction(2, x, x);
TabulatedFunction invUnit = TabulatedFunction(2, x, y);
for (unsigned regionIdx = 0; regionIdx < numSatRegions; ++regionIdx) {
params_.setMsfn(regionIdx, unit, invUnit);
}
}
// resize the attributes of the object
params_.sorwmis_.resize(numMiscRegions);
const auto& sorwmisTables = tableManager.getSorwmisTables();
if (!sorwmisTables.empty()) {
assert(numMiscRegions == sorwmisTables.size());
for (unsigned regionIdx = 0; regionIdx < numMiscRegions; ++regionIdx) {
const auto& sorwmisTable = sorwmisTables.template getTable<SorwmisTable>(regionIdx);
// Copy data
const auto& sw = sorwmisTable.getWaterSaturationColumn();
const auto& sorwmis = sorwmisTable.getMiscibleResidualOilColumn();
params_.sorwmis_[regionIdx].setXYContainers(sw, sorwmis);
}
}
else {
// default
std::vector<double> x = {0.0,1.0};
std::vector<double> y = {0.0,0.0};
TabulatedFunction zero = TabulatedFunction(2, x, y);
for (unsigned regionIdx = 0; regionIdx < numMiscRegions; ++regionIdx) {
params_.sorwmis_[regionIdx] = zero;
}
}
// resize the attributes of the object
params_.sgcwmis_.resize(numMiscRegions);
const auto& sgcwmisTables = tableManager.getSgcwmisTables();
if (!sgcwmisTables.empty()) {
assert(numMiscRegions == sgcwmisTables.size());
for (unsigned regionIdx = 0; regionIdx < numMiscRegions; ++regionIdx) {
const auto& sgcwmisTable = sgcwmisTables.template getTable<SgcwmisTable>(regionIdx);
// Copy data
const auto& sw = sgcwmisTable.getWaterSaturationColumn();
const auto& sgcwmis = sgcwmisTable.getMiscibleResidualGasColumn();
params_.sgcwmis_[regionIdx].setXYContainers(sw, sgcwmis);
}
}
else {
// default
std::vector<double> x = {0.0,1.0};
std::vector<double> y = {0.0,0.0};
TabulatedFunction zero = TabulatedFunction(2, x, y);
for (unsigned regionIdx = 0; regionIdx < numMiscRegions; ++regionIdx)
params_.sgcwmis_[regionIdx] = zero;
}
const auto& tlmixpar = eclState.getTableManager().getTLMixpar();
if (!tlmixpar.empty()) {
// resize the attributes of the object
params_.tlMixParamViscosity_.resize(numMiscRegions);
params_.tlMixParamDensity_.resize(numMiscRegions);
assert(numMiscRegions == tlmixpar.size());
for (unsigned regionIdx = 0; regionIdx < numMiscRegions; ++regionIdx) {
const auto& tlp = tlmixpar[regionIdx];
params_.tlMixParamViscosity_[regionIdx] = tlp.viscosity_parameter;
params_.tlMixParamDensity_[regionIdx] = tlp.density_parameter;
}
}
else
throw std::runtime_error("TLMIXPAR must be specified in MISCIBLE (SOLVENT) runs\n");
// resize the attributes of the object
params_.tlPMixTable_.resize(numMiscRegions);
if (!eclState.getTableManager().getTlpmixpaTables().empty()) {
const auto& tlpmixparTables = tableManager.getTlpmixpaTables();
if (!tlpmixparTables.empty()) {
assert(numMiscRegions == tlpmixparTables.size());
for (unsigned regionIdx = 0; regionIdx < numMiscRegions; ++regionIdx) {
const auto& tlpmixparTable = tlpmixparTables.template getTable<TlpmixpaTable>(regionIdx);
// Copy data
const auto& po = tlpmixparTable.getOilPhasePressureColumn();
const auto& tlpmixpa = tlpmixparTable.getMiscibilityColumn();
params_.tlPMixTable_[regionIdx].setXYContainers(po, tlpmixpa);
}
}
else {
// if empty keyword. Try to use the pmisc table as default.
if (params_.pmisc_.size() > 0)
params_.tlPMixTable_ = params_.pmisc_;
else
throw std::invalid_argument("If the pressure dependent TL values in "
"TLPMIXPA is defaulted (no entries), then "
"the PMISC tables must be specified.");
}
}
else {
// default
std::vector<double> x = {0.0,1.0e20};
std::vector<double> y = {1.0,1.0};
TabulatedFunction ones = TabulatedFunction(2, x, y);
for (unsigned regionIdx = 0; regionIdx < numMiscRegions; ++regionIdx)
params_.tlPMixTable_[regionIdx] = ones;
}
}
params_ = params;
}
#endif
/*!
* \brief Specify the solvent PVT of a all PVT regions.

View File

@ -0,0 +1,334 @@
// -*- 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.
*/
#include <config.h>
#include <opm/models/blackoil/blackoilsolventparams.hpp>
#if HAVE_ECL_INPUT
#include <opm/input/eclipse/EclipseState/EclipseState.hpp>
#include <opm/input/eclipse/EclipseState/Tables/SsfnTable.hpp>
#include <opm/input/eclipse/EclipseState/Tables/Sof2Table.hpp>
#include <opm/input/eclipse/EclipseState/Tables/MsfnTable.hpp>
#include <opm/input/eclipse/EclipseState/Tables/PmiscTable.hpp>
#include <opm/input/eclipse/EclipseState/Tables/MiscTable.hpp>
#include <opm/input/eclipse/EclipseState/Tables/SorwmisTable.hpp>
#include <opm/input/eclipse/EclipseState/Tables/SgcwmisTable.hpp>
#include <opm/input/eclipse/EclipseState/Tables/TlpmixpaTable.hpp>
#endif
namespace Opm {
#if HAVE_ECL_INPUT
template<class Scalar>
template<bool enableSolvent>
void BlackOilSolventParams<Scalar>::
initFromState(const EclipseState& eclState, const Schedule& schedule)
{
// some sanity checks: if solvents are enabled, the SOLVENT keyword must be
// present, if solvents are disabled the keyword must not be present.
if constexpr (enableSolvent) {
if (!eclState.runspec().phases().active(Phase::SOLVENT)) {
throw std::runtime_error("Non-trivial solvent treatment requested at compile "
"time, but the deck does not contain the SOLVENT keyword");
}
} else {
if (eclState.runspec().phases().active(Phase::SOLVENT)) {
throw std::runtime_error("Solvent treatment disabled at compile time, but the deck "
"contains the SOLVENT keyword");
}
}
if (!eclState.runspec().phases().active(Phase::SOLVENT)) {
return; // solvent treatment is supposed to be disabled
}
co2sol_ = eclState.runspec().co2Sol();
h2sol_ = eclState.runspec().h2Sol();
if (co2sol_ && h2sol_) {
throw std::runtime_error("CO2SOL and H2SOL can not be used together");
}
if (co2sol_ || h2sol_) {
if (co2sol_) {
co2GasPvt_.initFromState(eclState, schedule);
brineCo2Pvt_.initFromState(eclState, schedule);
} else {
h2GasPvt_.initFromState(eclState, schedule);
brineH2Pvt_.initFromState(eclState, schedule);
}
if (eclState.getSimulationConfig().hasDISGASW()) {
rsSolw_active_ = true;
}
} else
solventPvt_.initFromState(eclState, schedule);
const auto& tableManager = eclState.getTableManager();
// initialize the objects which deal with the SSFN keyword
const auto& ssfnTables = tableManager.getSsfnTables();
unsigned numSatRegions = tableManager.getTabdims().getNumSatTables();
setNumSatRegions(numSatRegions);
for (unsigned satRegionIdx = 0; satRegionIdx < numSatRegions; ++satRegionIdx) {
const auto& ssfnTable = ssfnTables.template getTable<SsfnTable>(satRegionIdx);
ssfnKrg_[satRegionIdx].setXYContainers(ssfnTable.getSolventFractionColumn(),
ssfnTable.getGasRelPermMultiplierColumn(),
/*sortInput=*/true);
ssfnKrs_[satRegionIdx].setXYContainers(ssfnTable.getSolventFractionColumn(),
ssfnTable.getSolventRelPermMultiplierColumn(),
/*sortInput=*/true);
}
// initialize the objects needed for miscible solvent and oil simulations
isMiscible_ = false;
if (!eclState.getTableManager().getMiscTables().empty()) {
isMiscible_ = true;
unsigned numMiscRegions = 1;
// misicible hydrocabon relative permeability wrt water
const auto& sof2Tables = tableManager.getSof2Tables();
if (!sof2Tables.empty()) {
// resize the attributes of the object
sof2Krn_.resize(numSatRegions);
for (unsigned satRegionIdx = 0; satRegionIdx < numSatRegions; ++satRegionIdx) {
const auto& sof2Table = sof2Tables.template getTable<Sof2Table>(satRegionIdx);
sof2Krn_[satRegionIdx].setXYContainers(sof2Table.getSoColumn(),
sof2Table.getKroColumn(),
/*sortInput=*/true);
}
}
else if (eclState.runspec().phases().active(Phase::OIL)) {
throw std::runtime_error("SOF2 must be specified in MISCIBLE (SOLVENT and OIL) runs\n");
}
const auto& miscTables = tableManager.getMiscTables();
if (!miscTables.empty()) {
assert(numMiscRegions == miscTables.size());
// resize the attributes of the object
misc_.resize(numMiscRegions);
for (unsigned miscRegionIdx = 0; miscRegionIdx < numMiscRegions; ++miscRegionIdx) {
const auto& miscTable = miscTables.template getTable<MiscTable>(miscRegionIdx);
// solventFraction = Ss / (Ss + Sg);
const auto& solventFraction = miscTable.getSolventFractionColumn();
const auto& misc = miscTable.getMiscibilityColumn();
misc_[miscRegionIdx].setXYContainers(solventFraction, misc);
}
}
else {
throw std::runtime_error("MISC must be specified in MISCIBLE (SOLVENT) runs\n");
}
// resize the attributes of the object
pmisc_.resize(numMiscRegions);
const auto& pmiscTables = tableManager.getPmiscTables();
if (!pmiscTables.empty()) {
assert(numMiscRegions == pmiscTables.size());
for (unsigned regionIdx = 0; regionIdx < numMiscRegions; ++regionIdx) {
const auto& pmiscTable = pmiscTables.template getTable<PmiscTable>(regionIdx);
// Copy data
const auto& po = pmiscTable.getOilPhasePressureColumn();
const auto& pmisc = pmiscTable.getMiscibilityColumn();
pmisc_[regionIdx].setXYContainers(po, pmisc);
}
}
else {
std::vector<double> x = {0.0,1.0e20};
std::vector<double> y = {1.0,1.0};
TabulatedFunction constant = TabulatedFunction(2, x, y);
for (unsigned regionIdx = 0; regionIdx < numMiscRegions; ++regionIdx) {
pmisc_[regionIdx] = constant;
}
}
// miscible relative permeability multipleiers
msfnKrsg_.resize(numSatRegions);
msfnKro_.resize(numSatRegions);
const auto& msfnTables = tableManager.getMsfnTables();
if (!msfnTables.empty()) {
assert(numSatRegions == msfnTables.size());
for (unsigned regionIdx = 0; regionIdx < numSatRegions; ++regionIdx) {
const MsfnTable& msfnTable = msfnTables.template getTable<MsfnTable>(regionIdx);
// Copy data
// Ssg = Ss + Sg;
const auto& Ssg = msfnTable.getGasPhaseFractionColumn();
const auto& krsg = msfnTable.getGasSolventRelpermMultiplierColumn();
const auto& kro = msfnTable.getOilRelpermMultiplierColumn();
msfnKrsg_[regionIdx].setXYContainers(Ssg, krsg);
msfnKro_[regionIdx].setXYContainers(Ssg, kro);
}
}
else {
std::vector<double> x = {0.0,1.0};
std::vector<double> y = {1.0,0.0};
TabulatedFunction unit = TabulatedFunction(2, x, x);
TabulatedFunction invUnit = TabulatedFunction(2, x, y);
for (unsigned regionIdx = 0; regionIdx < numSatRegions; ++regionIdx) {
setMsfn(regionIdx, unit, invUnit);
}
}
// resize the attributes of the object
sorwmis_.resize(numMiscRegions);
const auto& sorwmisTables = tableManager.getSorwmisTables();
if (!sorwmisTables.empty()) {
assert(numMiscRegions == sorwmisTables.size());
for (unsigned regionIdx = 0; regionIdx < numMiscRegions; ++regionIdx) {
const auto& sorwmisTable = sorwmisTables.template getTable<SorwmisTable>(regionIdx);
// Copy data
const auto& sw = sorwmisTable.getWaterSaturationColumn();
const auto& sorwmis = sorwmisTable.getMiscibleResidualOilColumn();
sorwmis_[regionIdx].setXYContainers(sw, sorwmis);
}
}
else {
// default
std::vector<double> x = {0.0,1.0};
std::vector<double> y = {0.0,0.0};
TabulatedFunction zero = TabulatedFunction(2, x, y);
for (unsigned regionIdx = 0; regionIdx < numMiscRegions; ++regionIdx) {
sorwmis_[regionIdx] = zero;
}
}
// resize the attributes of the object
sgcwmis_.resize(numMiscRegions);
const auto& sgcwmisTables = tableManager.getSgcwmisTables();
if (!sgcwmisTables.empty()) {
assert(numMiscRegions == sgcwmisTables.size());
for (unsigned regionIdx = 0; regionIdx < numMiscRegions; ++regionIdx) {
const auto& sgcwmisTable = sgcwmisTables.template getTable<SgcwmisTable>(regionIdx);
// Copy data
const auto& sw = sgcwmisTable.getWaterSaturationColumn();
const auto& sgcwmis = sgcwmisTable.getMiscibleResidualGasColumn();
sgcwmis_[regionIdx].setXYContainers(sw, sgcwmis);
}
}
else {
// default
std::vector<double> x = {0.0,1.0};
std::vector<double> y = {0.0,0.0};
TabulatedFunction zero = TabulatedFunction(2, x, y);
for (unsigned regionIdx = 0; regionIdx < numMiscRegions; ++regionIdx)
sgcwmis_[regionIdx] = zero;
}
const auto& tlmixpar = eclState.getTableManager().getTLMixpar();
if (!tlmixpar.empty()) {
// resize the attributes of the object
tlMixParamViscosity_.resize(numMiscRegions);
tlMixParamDensity_.resize(numMiscRegions);
assert(numMiscRegions == tlmixpar.size());
for (unsigned regionIdx = 0; regionIdx < numMiscRegions; ++regionIdx) {
const auto& tlp = tlmixpar[regionIdx];
tlMixParamViscosity_[regionIdx] = tlp.viscosity_parameter;
tlMixParamDensity_[regionIdx] = tlp.density_parameter;
}
}
else
throw std::runtime_error("TLMIXPAR must be specified in MISCIBLE (SOLVENT) runs\n");
// resize the attributes of the object
tlPMixTable_.resize(numMiscRegions);
if (!eclState.getTableManager().getTlpmixpaTables().empty()) {
const auto& tlpmixparTables = tableManager.getTlpmixpaTables();
if (!tlpmixparTables.empty()) {
assert(numMiscRegions == tlpmixparTables.size());
for (unsigned regionIdx = 0; regionIdx < numMiscRegions; ++regionIdx) {
const auto& tlpmixparTable = tlpmixparTables.template getTable<TlpmixpaTable>(regionIdx);
// Copy data
const auto& po = tlpmixparTable.getOilPhasePressureColumn();
const auto& tlpmixpa = tlpmixparTable.getMiscibilityColumn();
tlPMixTable_[regionIdx].setXYContainers(po, tlpmixpa);
}
}
else {
// if empty keyword. Try to use the pmisc table as default.
if (!pmisc_.empty()) {
tlPMixTable_ = pmisc_;
}
else {
throw std::invalid_argument("If the pressure dependent TL values in "
"TLPMIXPA is defaulted (no entries), then "
"the PMISC tables must be specified.");
}
}
}
else {
// default
std::vector<double> x = {0.0,1.0e20};
std::vector<double> y = {1.0,1.0};
TabulatedFunction ones = TabulatedFunction(2, x, y);
for (unsigned regionIdx = 0; regionIdx < numMiscRegions; ++regionIdx)
tlPMixTable_[regionIdx] = ones;
}
}
}
#endif
template<class Scalar>
void BlackOilSolventParams<Scalar>::
setNumSatRegions(unsigned numRegions)
{
ssfnKrg_.resize(numRegions);
ssfnKrs_.resize(numRegions);
}
template<class Scalar>
void BlackOilSolventParams<Scalar>::
setMsfn(unsigned satRegionIdx,
const TabulatedFunction& msfnKrsg,
const TabulatedFunction& msfnKro)
{
msfnKrsg_[satRegionIdx] = msfnKrsg;
msfnKro_[satRegionIdx] = msfnKro;
}
#define INSTANTIATE_TYPE(T) \
template struct BlackOilSolventParams<T>; \
template void BlackOilSolventParams<T>::initFromState<false>(const EclipseState&, const Schedule&); \
template void BlackOilSolventParams<T>::initFromState<true>(const EclipseState&, const Schedule&);
INSTANTIATE_TYPE(double)
#if FLOW_INSTANTIATE_FLOAT
INSTANTIATE_TYPE(float)
#endif
} // namespace Opm

View File

@ -38,25 +38,32 @@
namespace Opm {
#if HAVE_ECL_INPUT
class EclipseState;
class Schedule;
#endif
//! \brief Struct holding the parameters for the BlackOilSolventModule class.
template<class Scalar>
struct BlackOilSolventParams {
struct BlackOilSolventParams
{
using BrineCo2Pvt = ::Opm::BrineCo2Pvt<Scalar>;
using BrineH2Pvt = ::Opm::BrineH2Pvt<Scalar>;
using Co2GasPvt = ::Opm::Co2GasPvt<Scalar>;
using H2GasPvt = ::Opm::H2GasPvt<Scalar>;
using SolventPvt = ::Opm::SolventPvt<Scalar>;
using TabulatedFunction = Tabulated1DFunction<Scalar>;
using SolventPvt = ::Opm::SolventPvt<Scalar>;
SolventPvt solventPvt_;
#if HAVE_ECL_INPUT
template<bool enableSolvent>
void initFromState(const EclipseState& eclState, const Schedule& schedule);
#endif
using Co2GasPvt = ::Opm::Co2GasPvt<Scalar>;
Co2GasPvt co2GasPvt_;
using H2GasPvt = ::Opm::H2GasPvt<Scalar>;
H2GasPvt h2GasPvt_;
using BrineCo2Pvt = ::Opm::BrineCo2Pvt<Scalar>;
BrineCo2Pvt brineCo2Pvt_;
using BrineH2Pvt = ::Opm::BrineH2Pvt<Scalar>;
BrineH2Pvt brineH2Pvt_;
Co2GasPvt co2GasPvt_;
H2GasPvt h2GasPvt_;
SolventPvt solventPvt_;
std::vector<TabulatedFunction> ssfnKrg_; // the krg(Fs) column of the SSFN table
std::vector<TabulatedFunction> ssfnKrs_; // the krs(Fs) column of the SSFN table
@ -82,11 +89,7 @@ struct BlackOilSolventParams {
*
* This must be called before setting the SSFN of any region.
*/
void setNumSatRegions(unsigned numRegions)
{
ssfnKrg_.resize(numRegions);
ssfnKrs_.resize(numRegions);
}
void setNumSatRegions(unsigned numRegions);
/*!
* \brief Specify miscible relative permeability multipliers of a single region.
@ -95,11 +98,7 @@ struct BlackOilSolventParams {
*/
void setMsfn(unsigned satRegionIdx,
const TabulatedFunction& msfnKrsg,
const TabulatedFunction& msfnKro)
{
msfnKrsg_[satRegionIdx] = msfnKrsg;
msfnKro_[satRegionIdx] = msfnKro;
}
const TabulatedFunction& msfnKro);
};
} // namespace Opm

View File

@ -274,7 +274,6 @@ public:
this->model().addOutputModule(new VtkTracerModule<TypeTag>(simulator));
// Tell the black-oil extensions to initialize their internal data structures
const auto& vanguard = simulator.vanguard();
SolventModule::initFromState(vanguard.eclState(), vanguard.schedule());
BlackOilBrineParams<Scalar> brineParams;
brineParams.template initFromState<enableBrine,
@ -300,6 +299,10 @@ public:
polymerParams.template initFromState<enablePolymer, enablePolymerMolarWeight>(vanguard.eclState());
PolymerModule::setParams(std::move(polymerParams));
BlackOilSolventParams<Scalar> solventParams;
solventParams.template initFromState<enableSolvent>(vanguard.eclState(), vanguard.schedule());
SolventModule::setParams(std::move(solventParams));
// create the ECL writer
eclWriter_ = std::make_unique<EclWriterType>(simulator);
#if HAVE_DAMARIS