mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
blackoilsolventparams: introduce translation unit
move code for loading parameters from eclipse state into it
This commit is contained in:
parent
6ceeb3098e
commit
55a0a6da54
@ -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
|
||||
|
@ -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.
|
||||
|
334
opm/models/blackoil/blackoilsolventparams.cpp
Normal file
334
opm/models/blackoil/blackoilsolventparams.cpp
Normal 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
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user