mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
implement Saltvd
This commit is contained in:
@@ -148,6 +148,10 @@ public:
|
|||||||
fluidState.setDensity(phaseIdx, rho);
|
fluidState.setDensity(phaseIdx, rho);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set salt concentration
|
||||||
|
if (enableBrine)
|
||||||
|
fluidState.setSaltConcentration(initialState.saltConcentration()[elemIdx]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -411,6 +411,7 @@ class EclProblem : public GET_PROP_TYPE(TypeTag, BaseProblem)
|
|||||||
enum { enableExperiments = GET_PROP_VALUE(TypeTag, EnableExperiments) };
|
enum { enableExperiments = GET_PROP_VALUE(TypeTag, EnableExperiments) };
|
||||||
enum { enableSolvent = GET_PROP_VALUE(TypeTag, EnableSolvent) };
|
enum { enableSolvent = GET_PROP_VALUE(TypeTag, EnableSolvent) };
|
||||||
enum { enablePolymer = GET_PROP_VALUE(TypeTag, EnablePolymer) };
|
enum { enablePolymer = GET_PROP_VALUE(TypeTag, EnablePolymer) };
|
||||||
|
enum { enableBrine = GET_PROP_VALUE(TypeTag, EnableBrine) };
|
||||||
enum { enablePolymerMolarWeight = GET_PROP_VALUE(TypeTag, EnablePolymerMW) };
|
enum { enablePolymerMolarWeight = GET_PROP_VALUE(TypeTag, EnablePolymerMW) };
|
||||||
enum { enableFoam = GET_PROP_VALUE(TypeTag, EnableFoam) };
|
enum { enableFoam = GET_PROP_VALUE(TypeTag, EnableFoam) };
|
||||||
enum { enableTemperature = GET_PROP_VALUE(TypeTag, EnableTemperature) };
|
enum { enableTemperature = GET_PROP_VALUE(TypeTag, EnableTemperature) };
|
||||||
@@ -1567,6 +1568,9 @@ public:
|
|||||||
if (enablePolymerMolarWeight)
|
if (enablePolymerMolarWeight)
|
||||||
values[Indices::polymerMoleWeightIdx]= polymerMoleWeight_[globalDofIdx];
|
values[Indices::polymerMoleWeightIdx]= polymerMoleWeight_[globalDofIdx];
|
||||||
|
|
||||||
|
if (enableBrine)
|
||||||
|
values[Indices::saltConcentrationIdx] = initialFluidStates_[globalDofIdx].saltConcentration();
|
||||||
|
|
||||||
values.checkDefined();
|
values.checkDefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -612,6 +612,8 @@ private:
|
|||||||
*/
|
*/
|
||||||
class EquilReg
|
class EquilReg
|
||||||
{
|
{
|
||||||
|
using TabulatedFunction = typename Opm::Tabulated1DFunction<double>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
@@ -624,10 +626,12 @@ public:
|
|||||||
EquilReg(const Opm::EquilRecord& rec,
|
EquilReg(const Opm::EquilRecord& rec,
|
||||||
std::shared_ptr<Miscibility::RsFunction> rs,
|
std::shared_ptr<Miscibility::RsFunction> rs,
|
||||||
std::shared_ptr<Miscibility::RsFunction> rv,
|
std::shared_ptr<Miscibility::RsFunction> rv,
|
||||||
|
const TabulatedFunction& saltVdTable,
|
||||||
const int pvtIdx)
|
const int pvtIdx)
|
||||||
: rec_ (rec)
|
: rec_ (rec)
|
||||||
, rs_ (rs)
|
, rs_ (rs)
|
||||||
, rv_ (rv)
|
, rv_ (rv)
|
||||||
|
, saltVdTable_ (saltVdTable)
|
||||||
, pvtIdx_ (pvtIdx)
|
, pvtIdx_ (pvtIdx)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@@ -701,6 +705,8 @@ public:
|
|||||||
const CalcEvaporation&
|
const CalcEvaporation&
|
||||||
evaporationCalculator() const { return *this->rv_; }
|
evaporationCalculator() const { return *this->rv_; }
|
||||||
|
|
||||||
|
const TabulatedFunction&
|
||||||
|
saltVdTable() const { return saltVdTable_;}
|
||||||
/**
|
/**
|
||||||
* Retrieve pvtIdx of the region.
|
* Retrieve pvtIdx of the region.
|
||||||
*/
|
*/
|
||||||
@@ -710,6 +716,7 @@ private:
|
|||||||
Opm::EquilRecord rec_; /**< Equilibration data */
|
Opm::EquilRecord rec_; /**< Equilibration data */
|
||||||
std::shared_ptr<Miscibility::RsFunction> rs_; /**< RS calculator */
|
std::shared_ptr<Miscibility::RsFunction> rs_; /**< RS calculator */
|
||||||
std::shared_ptr<Miscibility::RsFunction> rv_; /**< RV calculator */
|
std::shared_ptr<Miscibility::RsFunction> rv_; /**< RV calculator */
|
||||||
|
const TabulatedFunction& saltVdTable_;
|
||||||
const int pvtIdx_;
|
const int pvtIdx_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -46,6 +46,7 @@
|
|||||||
#include <opm/parser/eclipse/EclipseState/Tables/RvvdTable.hpp>
|
#include <opm/parser/eclipse/EclipseState/Tables/RvvdTable.hpp>
|
||||||
#include <opm/parser/eclipse/EclipseState/Tables/PbvdTable.hpp>
|
#include <opm/parser/eclipse/EclipseState/Tables/PbvdTable.hpp>
|
||||||
#include <opm/parser/eclipse/EclipseState/Tables/PdvdTable.hpp>
|
#include <opm/parser/eclipse/EclipseState/Tables/PdvdTable.hpp>
|
||||||
|
#include <opm/parser/eclipse/EclipseState/Tables/SaltvdTable.hpp>
|
||||||
#include <opm/common/OpmLog/OpmLog.hpp>
|
#include <opm/common/OpmLog/OpmLog.hpp>
|
||||||
#include <opm/common/data/SimulationDataContainer.hpp>
|
#include <opm/common/data/SimulationDataContainer.hpp>
|
||||||
|
|
||||||
@@ -148,31 +149,36 @@ namespace PhasePressODE {
|
|||||||
template <class FluidSystem>
|
template <class FluidSystem>
|
||||||
class Water
|
class Water
|
||||||
{
|
{
|
||||||
|
using TabulatedFunction = typename Opm::Tabulated1DFunction<double>;
|
||||||
public:
|
public:
|
||||||
Water(const double temp,
|
Water(const double temp,
|
||||||
|
const TabulatedFunction& saltVdTable,
|
||||||
const int pvtRegionIdx,
|
const int pvtRegionIdx,
|
||||||
const double normGrav)
|
const double normGrav)
|
||||||
: temp_(temp)
|
: temp_(temp)
|
||||||
|
, saltVdTable_(saltVdTable)
|
||||||
, pvtRegionIdx_(pvtRegionIdx)
|
, pvtRegionIdx_(pvtRegionIdx)
|
||||||
, g_(normGrav)
|
, g_(normGrav)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
double
|
double
|
||||||
operator()(const double /* depth */,
|
operator()(const double depth,
|
||||||
const double press) const
|
const double press) const
|
||||||
{
|
{
|
||||||
return this->density(press) * g_;
|
return this->density(depth, press) * g_;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const double temp_;
|
const double temp_;
|
||||||
|
const TabulatedFunction& saltVdTable_;
|
||||||
const int pvtRegionIdx_;
|
const int pvtRegionIdx_;
|
||||||
const double g_;
|
const double g_;
|
||||||
|
|
||||||
double
|
double
|
||||||
density(const double press) const
|
density(const double depth,
|
||||||
|
const double press) const
|
||||||
{
|
{
|
||||||
double saltConcentration = 0.0; // TODO allow for non-zero initial salt concentration
|
double saltConcentration = saltVdTable_.eval(depth);
|
||||||
double rho = FluidSystem::waterPvt().inverseFormationVolumeFactor(pvtRegionIdx_, temp_, press, saltConcentration);
|
double rho = FluidSystem::waterPvt().inverseFormationVolumeFactor(pvtRegionIdx_, temp_, press, saltConcentration);
|
||||||
rho *= FluidSystem::referenceDensity(FluidSystem::waterPhaseIdx, pvtRegionIdx_);
|
rho *= FluidSystem::referenceDensity(FluidSystem::waterPhaseIdx, pvtRegionIdx_);
|
||||||
return rho;
|
return rho;
|
||||||
@@ -523,6 +529,7 @@ private:
|
|||||||
double gravity_;
|
double gravity_;
|
||||||
int nsample_;
|
int nsample_;
|
||||||
double temperature_{ 273.15 + 20 };
|
double temperature_{ 273.15 + 20 };
|
||||||
|
double saltConcentration_{0.0};
|
||||||
|
|
||||||
std::unique_ptr<OPress> oil_{};
|
std::unique_ptr<OPress> oil_{};
|
||||||
std::unique_ptr<GPress> gas_{};
|
std::unique_ptr<GPress> gas_{};
|
||||||
@@ -749,7 +756,7 @@ makeWatPressure(const typename WPress::InitCond& ic,
|
|||||||
const VSpan& span)
|
const VSpan& span)
|
||||||
{
|
{
|
||||||
const auto drho = WatPressODE {
|
const auto drho = WatPressODE {
|
||||||
this->temperature_, reg.pvtIdx(), this->gravity_
|
this->temperature_, reg.saltVdTable(), reg.pvtIdx(), this->gravity_
|
||||||
};
|
};
|
||||||
|
|
||||||
this->wat_ = std::make_unique<WPress>(drho, ic, this->nsample_, span);
|
this->wat_ = std::make_unique<WPress>(drho, ic, this->nsample_, span);
|
||||||
@@ -1576,6 +1583,7 @@ public:
|
|||||||
const double grav = Opm::unit::gravity,
|
const double grav = Opm::unit::gravity,
|
||||||
const bool applySwatInit = true)
|
const bool applySwatInit = true)
|
||||||
: temperature_(grid.size(/*codim=*/0)),
|
: temperature_(grid.size(/*codim=*/0)),
|
||||||
|
saltConcentration_(grid.size(/*codim=*/0)),
|
||||||
pp_(FluidSystem::numPhases,
|
pp_(FluidSystem::numPhases,
|
||||||
std::vector<double>(grid.size(/*codim=*/0))),
|
std::vector<double>(grid.size(/*codim=*/0))),
|
||||||
sat_(FluidSystem::numPhases,
|
sat_(FluidSystem::numPhases,
|
||||||
@@ -1699,6 +1707,9 @@ public:
|
|||||||
// EXTRACT the initial temperature
|
// EXTRACT the initial temperature
|
||||||
updateInitialTemperature_(eclipseState);
|
updateInitialTemperature_(eclipseState);
|
||||||
|
|
||||||
|
// EXTRACT the initial salt concentration
|
||||||
|
updateInitialSaltConcentration_(eclipseState, eqlmap, grid);
|
||||||
|
|
||||||
// Compute pressures, saturations, rs and rv factors.
|
// Compute pressures, saturations, rs and rv factors.
|
||||||
calcPressSatRsRv(eqlmap, rec, materialLawManager, grid, grav);
|
calcPressSatRsRv(eqlmap, rec, materialLawManager, grid, grav);
|
||||||
|
|
||||||
@@ -1710,6 +1721,7 @@ public:
|
|||||||
typedef std::vector<Vec> PVec; // One per phase.
|
typedef std::vector<Vec> PVec; // One per phase.
|
||||||
|
|
||||||
const Vec& temperature() const { return temperature_; }
|
const Vec& temperature() const { return temperature_; }
|
||||||
|
const Vec& saltConcentration() const { return saltConcentration_; }
|
||||||
const PVec& press() const { return pp_; }
|
const PVec& press() const { return pp_; }
|
||||||
const PVec& saturation() const { return sat_; }
|
const PVec& saturation() const { return sat_; }
|
||||||
const Vec& rs() const { return rs_; }
|
const Vec& rs() const { return rs_; }
|
||||||
@@ -1721,10 +1733,31 @@ private:
|
|||||||
this->temperature_ = eclState.fieldProps().get_double("TEMPI");
|
this->temperature_ = eclState.fieldProps().get_double("TEMPI");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class RMap>
|
||||||
|
void updateInitialSaltConcentration_(const Opm::EclipseState& eclState, const RMap& reg, const Grid& grid)
|
||||||
|
{
|
||||||
|
const auto& tables = eclState.getTableManager();
|
||||||
|
const Opm::TableContainer& saltvdTables = tables.getSaltvdTables();
|
||||||
|
saltVdTable_.resize(saltvdTables.size());
|
||||||
|
for (size_t i = 0; i < saltvdTables.size(); ++i) {
|
||||||
|
const Opm::SaltvdTable& saltvdTable = saltvdTables.getTable<Opm::SaltvdTable>(i);
|
||||||
|
saltVdTable_[i].setXYContainers(saltvdTable.getDepthColumn(), saltvdTable.getSaltColumn());
|
||||||
|
|
||||||
|
const auto& cells = reg.cells(i);
|
||||||
|
for (const auto& cell : cells) {
|
||||||
|
const double depth = UgGridHelpers::cellCenterDepth(grid, cell);
|
||||||
|
this->saltConcentration_[cell] = saltVdTable_[i].eval(depth);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::vector< std::shared_ptr<Miscibility::RsFunction> > rsFunc_;
|
std::vector< std::shared_ptr<Miscibility::RsFunction> > rsFunc_;
|
||||||
std::vector< std::shared_ptr<Miscibility::RsFunction> > rvFunc_;
|
std::vector< std::shared_ptr<Miscibility::RsFunction> > rvFunc_;
|
||||||
|
using TabulatedFunction = typename Opm::Tabulated1DFunction<double>;
|
||||||
|
std::vector<TabulatedFunction> saltVdTable_;
|
||||||
std::vector<int> regionPvtIdx_;
|
std::vector<int> regionPvtIdx_;
|
||||||
Vec temperature_;
|
Vec temperature_;
|
||||||
|
Vec saltConcentration_;
|
||||||
PVec pp_;
|
PVec pp_;
|
||||||
PVec sat_;
|
PVec sat_;
|
||||||
Vec rs_;
|
Vec rs_;
|
||||||
@@ -1768,7 +1801,7 @@ private:
|
|||||||
Details::verticalExtent(grid, cells, vspan);
|
Details::verticalExtent(grid, cells, vspan);
|
||||||
|
|
||||||
const auto eqreg = EquilReg {
|
const auto eqreg = EquilReg {
|
||||||
rec[r], this->rsFunc_[r], this->rvFunc_[r], this->regionPvtIdx_[r]
|
rec[r], this->rsFunc_[r], this->rvFunc_[r], this->saltVdTable_[r], this->regionPvtIdx_[r]
|
||||||
};
|
};
|
||||||
|
|
||||||
// Ensure gas/oil and oil/water contacts are within the span for the
|
// Ensure gas/oil and oil/water contacts are within the span for the
|
||||||
|
|||||||
@@ -653,7 +653,6 @@ namespace MissingFeatures {
|
|||||||
"SALT",
|
"SALT",
|
||||||
"SALTNODE",
|
"SALTNODE",
|
||||||
"SALTREST",
|
"SALTREST",
|
||||||
"SALTVD",
|
|
||||||
"SCALELIM",
|
"SCALELIM",
|
||||||
"SCDATAB",
|
"SCDATAB",
|
||||||
"SCDETAB",
|
"SCDETAB",
|
||||||
|
|||||||
Reference in New Issue
Block a user