mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
Merge pull request #4719 from akva2/connection_rate_to_connections
Move connection rate helpers to StandardWellConnections
This commit is contained in:
@@ -438,35 +438,11 @@ namespace Opm
|
||||
DeferredLogger& deferred_logger) const;
|
||||
|
||||
private:
|
||||
Eval connectionRateBrine(double& rate,
|
||||
const double vap_wat_rate,
|
||||
const std::vector<EvalWell>& cq_s,
|
||||
const IntensiveQuantities& intQuants) const;
|
||||
|
||||
Eval connectionRateEnergy(const double maxOilSaturation,
|
||||
const std::vector<EvalWell>& cq_s,
|
||||
const IntensiveQuantities& intQuants,
|
||||
DeferredLogger& deferred_logger) const;
|
||||
|
||||
Eval connectionRateFoam(const std::vector<EvalWell>& cq_s,
|
||||
const IntensiveQuantities& intQuants,
|
||||
DeferredLogger& deferred_logger) const;
|
||||
|
||||
std::tuple<Eval,Eval,Eval>
|
||||
connectionRatesMICP(const std::vector<EvalWell>& cq_s,
|
||||
const IntensiveQuantities& intQuants) const;
|
||||
|
||||
std::tuple<Eval,EvalWell>
|
||||
connectionRatePolymer(double& rate,
|
||||
const std::vector<EvalWell>& cq_s,
|
||||
const IntensiveQuantities& intQuants) const;
|
||||
|
||||
std::tuple<Eval,EvalWell>
|
||||
connectionRatezFraction(double& rate,
|
||||
const double dis_gas_rate,
|
||||
const std::vector<EvalWell>& cq_s,
|
||||
const IntensiveQuantities& intQuants) const;
|
||||
|
||||
template<class Value>
|
||||
void gasOilPerfRateInj(const std::vector<Value>& cq_s,
|
||||
PerforationRates& perf_rates,
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#include <opm/models/blackoil/blackoilonephaseindices.hh>
|
||||
#include <opm/models/blackoil/blackoiltwophaseindices.hh>
|
||||
|
||||
#include <opm/simulators/utils/DeferredLogger.hpp>
|
||||
#include <opm/simulators/utils/DeferredLoggingErrorHelpers.hpp>
|
||||
#include <opm/simulators/wells/ParallelWellInfo.hpp>
|
||||
#include <opm/simulators/wells/WellInterfaceIndices.hpp>
|
||||
#include <opm/simulators/wells/WellState.hpp>
|
||||
@@ -514,8 +514,160 @@ computeProperties(const WellState& well_state,
|
||||
this->computePressureDelta();
|
||||
}
|
||||
|
||||
template<class FluidSystem, class Indices, class Scalar>
|
||||
typename StandardWellConnections<FluidSystem,Indices,Scalar>::Eval
|
||||
StandardWellConnections<FluidSystem,Indices,Scalar>::
|
||||
connectionRateBrine(double& rate,
|
||||
const double vap_wat_rate,
|
||||
const std::vector<EvalWell>& cq_s,
|
||||
const std::variant<Scalar,EvalWell>& saltConcentration) const
|
||||
{
|
||||
// TODO: the application of well efficiency factor has not been tested with an example yet
|
||||
const unsigned waterCompIdx = Indices::canonicalToActiveComponentIndex(FluidSystem::waterCompIdx);
|
||||
// Correction salt rate; evaporated water does not contain salt
|
||||
EvalWell cq_s_sm = cq_s[waterCompIdx] - vap_wat_rate;
|
||||
if (well_.isInjector()) {
|
||||
cq_s_sm *= std::get<Scalar>(saltConcentration);
|
||||
} else {
|
||||
cq_s_sm *= std::get<EvalWell>(saltConcentration);
|
||||
}
|
||||
|
||||
// Note. Efficiency factor is handled in the output layer
|
||||
rate = cq_s_sm.value();
|
||||
|
||||
cq_s_sm *= well_.wellEfficiencyFactor();
|
||||
return well_.restrictEval(cq_s_sm);
|
||||
}
|
||||
|
||||
template<class FluidSystem, class Indices, class Scalar>
|
||||
typename StandardWellConnections<FluidSystem,Indices,Scalar>::Eval
|
||||
StandardWellConnections<FluidSystem,Indices,Scalar>::
|
||||
connectionRateFoam(const std::vector<EvalWell>& cq_s,
|
||||
const std::variant<Scalar,EvalWell>& foamConcentration,
|
||||
const Phase transportPhase,
|
||||
DeferredLogger& deferred_logger) const
|
||||
{
|
||||
// TODO: the application of well efficiency factor has not been tested with an example yet
|
||||
auto getFoamTransportIdx = [&deferred_logger,transportPhase] {
|
||||
switch (transportPhase) {
|
||||
case Phase::WATER: {
|
||||
return Indices::canonicalToActiveComponentIndex(FluidSystem::waterCompIdx);
|
||||
}
|
||||
case Phase::GAS: {
|
||||
return Indices::canonicalToActiveComponentIndex(FluidSystem::gasCompIdx);
|
||||
}
|
||||
case Phase::SOLVENT: {
|
||||
if constexpr (Indices::enableSolvent)
|
||||
return static_cast<unsigned>(Indices::contiSolventEqIdx);
|
||||
else
|
||||
OPM_DEFLOG_THROW(std::runtime_error, "Foam transport phase is SOLVENT but SOLVENT is not activated.", deferred_logger);
|
||||
}
|
||||
default: {
|
||||
OPM_DEFLOG_THROW(std::runtime_error, "Foam transport phase must be GAS/WATER/SOLVENT.", deferred_logger);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
EvalWell cq_s_foam = cq_s[getFoamTransportIdx()] * well_.wellEfficiencyFactor();;
|
||||
if (well_.isInjector()) {
|
||||
cq_s_foam *= std::get<Scalar>(foamConcentration);
|
||||
} else {
|
||||
cq_s_foam *= std::get<EvalWell>(foamConcentration);
|
||||
}
|
||||
|
||||
return well_.restrictEval(cq_s_foam);
|
||||
}
|
||||
|
||||
template<class FluidSystem, class Indices, class Scalar>
|
||||
std::tuple<typename StandardWellConnections<FluidSystem,Indices,Scalar>::Eval,
|
||||
typename StandardWellConnections<FluidSystem,Indices,Scalar>::Eval,
|
||||
typename StandardWellConnections<FluidSystem,Indices,Scalar>::Eval>
|
||||
StandardWellConnections<FluidSystem,Indices,Scalar>::
|
||||
connectionRatesMICP(const std::vector<EvalWell>& cq_s,
|
||||
const std::variant<Scalar,EvalWell>& microbialConcentration,
|
||||
const std::variant<Scalar,EvalWell>& oxygenConcentration,
|
||||
const std::variant<Scalar,EvalWell>& ureaConcentration) const
|
||||
{
|
||||
const unsigned waterCompIdx = Indices::canonicalToActiveComponentIndex(FluidSystem::waterCompIdx);
|
||||
EvalWell cq_s_microbe = cq_s[waterCompIdx];
|
||||
if (well_.isInjector()) {
|
||||
cq_s_microbe *= std::get<Scalar>(microbialConcentration);
|
||||
} else {
|
||||
cq_s_microbe *= std::get<EvalWell>(microbialConcentration);
|
||||
}
|
||||
|
||||
EvalWell cq_s_oxygen = cq_s[waterCompIdx];
|
||||
if (well_.isInjector()) {
|
||||
cq_s_oxygen *= std::get<Scalar>(oxygenConcentration);
|
||||
} else {
|
||||
cq_s_oxygen *= std::get<EvalWell>(oxygenConcentration);
|
||||
}
|
||||
|
||||
EvalWell cq_s_urea = cq_s[waterCompIdx];
|
||||
if (well_.isInjector()) {
|
||||
cq_s_urea *= std::get<Scalar>(ureaConcentration);
|
||||
} else {
|
||||
cq_s_urea *= std::get<EvalWell>(ureaConcentration);
|
||||
}
|
||||
|
||||
return {well_.restrictEval(cq_s_microbe),
|
||||
well_.restrictEval(cq_s_oxygen),
|
||||
well_.restrictEval(cq_s_urea)};
|
||||
}
|
||||
|
||||
template<class FluidSystem, class Indices, class Scalar>
|
||||
std::tuple<typename StandardWellConnections<FluidSystem,Indices,Scalar>::Eval,
|
||||
typename StandardWellConnections<FluidSystem,Indices,Scalar>::EvalWell>
|
||||
StandardWellConnections<FluidSystem,Indices,Scalar>::
|
||||
connectionRatePolymer(double& rate,
|
||||
const std::vector<EvalWell>& cq_s,
|
||||
const std::variant<Scalar,EvalWell>& polymerConcentration) const
|
||||
{
|
||||
// TODO: the application of well efficiency factor has not been tested with an example yet
|
||||
const unsigned waterCompIdx = Indices::canonicalToActiveComponentIndex(FluidSystem::waterCompIdx);
|
||||
EvalWell cq_s_poly = cq_s[waterCompIdx];
|
||||
if (well_.isInjector()) {
|
||||
cq_s_poly *= std::get<Scalar>(polymerConcentration);
|
||||
} else {
|
||||
cq_s_poly *= std::get<EvalWell>(polymerConcentration);
|
||||
}
|
||||
// Note. Efficiency factor is handled in the output layer
|
||||
rate = cq_s_poly.value();
|
||||
|
||||
cq_s_poly *= well_.wellEfficiencyFactor();
|
||||
|
||||
return {well_.restrictEval(cq_s_poly), cq_s_poly};
|
||||
}
|
||||
|
||||
template<class FluidSystem, class Indices, class Scalar>
|
||||
std::tuple<typename StandardWellConnections<FluidSystem,Indices,Scalar>::Eval,
|
||||
typename StandardWellConnections<FluidSystem,Indices,Scalar>::EvalWell>
|
||||
StandardWellConnections<FluidSystem,Indices,Scalar>::
|
||||
connectionRatezFraction(double& rate,
|
||||
const double dis_gas_rate,
|
||||
const std::vector<EvalWell>& cq_s,
|
||||
const std::variant<Scalar, std::array<EvalWell,2>>& solventConcentration) const
|
||||
{
|
||||
// TODO: the application of well efficiency factor has not been tested with an example yet
|
||||
const unsigned gasCompIdx = Indices::canonicalToActiveComponentIndex(FluidSystem::gasCompIdx);
|
||||
EvalWell cq_s_zfrac_effective = cq_s[gasCompIdx];
|
||||
if (well_.isInjector()) {
|
||||
cq_s_zfrac_effective *= std::get<Scalar>(solventConcentration);
|
||||
} else if (cq_s_zfrac_effective.value() != 0.0) {
|
||||
const double dis_gas_frac = dis_gas_rate / cq_s_zfrac_effective.value();
|
||||
const auto& vol = std::get<std::array<EvalWell,2>>(solventConcentration);
|
||||
cq_s_zfrac_effective *= dis_gas_frac * vol[0] + (1.0 - dis_gas_frac) * vol[1];
|
||||
}
|
||||
|
||||
rate = cq_s_zfrac_effective.value();
|
||||
|
||||
cq_s_zfrac_effective *= well_.wellEfficiencyFactor();
|
||||
return {well_.restrictEval(cq_s_zfrac_effective), cq_s_zfrac_effective};
|
||||
}
|
||||
|
||||
#define INSTANCE(...) \
|
||||
template class StandardWellConnections<BlackOilFluidSystem<double,BlackOilDefaultIndexTraits>,__VA_ARGS__,double>;
|
||||
template class StandardWellConnections<BlackOilFluidSystem<double,BlackOilDefaultIndexTraits>, \
|
||||
__VA_ARGS__,double>;
|
||||
|
||||
// One phase
|
||||
INSTANCE(BlackOilOnePhaseIndices<0u,0u,0u,0u,false,false,0u,1u,0u>)
|
||||
|
||||
@@ -23,13 +23,17 @@
|
||||
#ifndef OPM_STANDARDWELL_CONNECTIONS_HEADER_INCLUDED
|
||||
#define OPM_STANDARDWELL_CONNECTIONS_HEADER_INCLUDED
|
||||
|
||||
#include <opm/simulators/wells/StandardWellPrimaryVariables.hpp>
|
||||
|
||||
#include <functional>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
namespace Opm
|
||||
{
|
||||
|
||||
class DeferredLogger;
|
||||
enum class Phase;
|
||||
template<class FluidSystem, class Indices, class Scalar> class WellInterfaceIndices;
|
||||
class WellState;
|
||||
|
||||
@@ -76,6 +80,36 @@ public:
|
||||
Scalar pressure_diff(const unsigned perf) const
|
||||
{ return perf_pressure_diffs_[perf]; }
|
||||
|
||||
using Eval = typename WellInterfaceIndices<FluidSystem,Indices,Scalar>::Eval;
|
||||
using EvalWell = typename StandardWellPrimaryVariables<FluidSystem,Indices,Scalar>::EvalWell;
|
||||
|
||||
Eval connectionRateBrine(double& rate,
|
||||
const double vap_wat_rate,
|
||||
const std::vector<EvalWell>& cq_s,
|
||||
const std::variant<Scalar,EvalWell>& saltConcentration) const;
|
||||
|
||||
Eval connectionRateFoam(const std::vector<EvalWell>& cq_s,
|
||||
const std::variant<Scalar,EvalWell>& foamConcentration,
|
||||
const Phase transportPhase,
|
||||
DeferredLogger& deferred_logger) const;
|
||||
|
||||
std::tuple<Eval,EvalWell>
|
||||
connectionRatePolymer(double& rate,
|
||||
const std::vector<EvalWell>& cq_s,
|
||||
const std::variant<Scalar,EvalWell>& polymerConcentration) const;
|
||||
|
||||
std::tuple<Eval,Eval,Eval>
|
||||
connectionRatesMICP(const std::vector<EvalWell>& cq_s,
|
||||
const std::variant<Scalar,EvalWell>& microbialConcentration,
|
||||
const std::variant<Scalar,EvalWell>& oxygenConcentration,
|
||||
const std::variant<Scalar,EvalWell>& ureaConcentration) const;
|
||||
|
||||
std::tuple<Eval,EvalWell>
|
||||
connectionRatezFraction(double& rate,
|
||||
const double dis_gas_rate,
|
||||
const std::vector<EvalWell>& cq_s,
|
||||
const std::variant<Scalar, std::array<EvalWell,2>>& solventConcentration) const;
|
||||
|
||||
private:
|
||||
void computePressureDelta();
|
||||
|
||||
|
||||
@@ -526,11 +526,19 @@ namespace Opm
|
||||
}
|
||||
|
||||
if constexpr (has_polymer) {
|
||||
std::variant<Scalar,EvalWell> polymerConcentration;
|
||||
if (this->isInjector()) {
|
||||
polymerConcentration = this->wpolymer();
|
||||
} else {
|
||||
polymerConcentration = this->extendEval(intQuants.polymerConcentration() *
|
||||
intQuants.polymerViscosityCorrection());
|
||||
}
|
||||
|
||||
[[maybe_unused]] EvalWell cq_s_poly;
|
||||
std::tie(connectionRates[perf][Indices::contiPolymerEqIdx],
|
||||
cq_s_poly) =
|
||||
connectionRatePolymer(perf_data.polymer_rates[perf],
|
||||
cq_s, intQuants);
|
||||
this->connections_.connectionRatePolymer(perf_data.polymer_rates[perf],
|
||||
cq_s, polymerConcentration);
|
||||
|
||||
if constexpr (Base::has_polymermw) {
|
||||
updateConnectionRatePolyMW(cq_s_poly, intQuants, well_state,
|
||||
@@ -539,28 +547,67 @@ namespace Opm
|
||||
}
|
||||
|
||||
if constexpr (has_foam) {
|
||||
std::variant<Scalar,EvalWell> foamConcentration;
|
||||
if (this->isInjector()) {
|
||||
foamConcentration = this->wfoam();
|
||||
} else {
|
||||
foamConcentration = this->extendEval(intQuants.foamConcentration());
|
||||
}
|
||||
connectionRates[perf][Indices::contiFoamEqIdx] =
|
||||
connectionRateFoam(cq_s, intQuants, deferred_logger);
|
||||
this->connections_.connectionRateFoam(cq_s, foamConcentration,
|
||||
FoamModule::transportPhase(),
|
||||
deferred_logger);
|
||||
}
|
||||
|
||||
if constexpr (has_zFraction) {
|
||||
std::variant<Scalar,std::array<EvalWell,2>> solventConcentration;
|
||||
if (this->isInjector()) {
|
||||
solventConcentration = this->wsolvent();
|
||||
} else {
|
||||
solventConcentration = std::array{this->extendEval(intQuants.xVolume()),
|
||||
this->extendEval(intQuants.yVolume())};
|
||||
}
|
||||
std::tie(connectionRates[perf][Indices::contiZfracEqIdx],
|
||||
cq_s_zfrac_effective) =
|
||||
connectionRatezFraction(perf_data.solvent_rates[perf],
|
||||
perf_rates.dis_gas, cq_s, intQuants);
|
||||
this->connections_.connectionRatezFraction(perf_data.solvent_rates[perf],
|
||||
perf_rates.dis_gas, cq_s,
|
||||
solventConcentration);
|
||||
}
|
||||
|
||||
if constexpr (has_brine) {
|
||||
std::variant<Scalar,EvalWell> saltConcentration;
|
||||
if (this->isInjector()) {
|
||||
saltConcentration = this->wsalt();
|
||||
} else {
|
||||
saltConcentration = this->extendEval(intQuants.fluidState().saltConcentration());
|
||||
}
|
||||
|
||||
connectionRates[perf][Indices::contiBrineEqIdx] =
|
||||
connectionRateBrine(perf_data.brine_rates[perf],
|
||||
perf_rates.vap_wat, cq_s, intQuants);
|
||||
this->connections_.connectionRateBrine(perf_data.brine_rates[perf],
|
||||
perf_rates.vap_wat, cq_s,
|
||||
saltConcentration);
|
||||
}
|
||||
|
||||
if constexpr (has_micp) {
|
||||
std::variant<Scalar,EvalWell> microbialConcentration;
|
||||
std::variant<Scalar,EvalWell> oxygenConcentration;
|
||||
std::variant<Scalar,EvalWell> ureaConcentration;
|
||||
if (this->isInjector()) {
|
||||
microbialConcentration = this->wmicrobes();
|
||||
oxygenConcentration = this->woxygen();
|
||||
ureaConcentration = this->wurea();
|
||||
} else {
|
||||
microbialConcentration = this->extendEval(intQuants.microbialConcentration());
|
||||
oxygenConcentration = this->extendEval(intQuants.oxygenConcentration());
|
||||
ureaConcentration = this->extendEval(intQuants.ureaConcentration());
|
||||
}
|
||||
std::tie(connectionRates[perf][Indices::contiMicrobialEqIdx],
|
||||
connectionRates[perf][Indices::contiOxygenEqIdx],
|
||||
connectionRates[perf][Indices::contiUreaEqIdx]) =
|
||||
connectionRatesMICP(cq_s, intQuants);
|
||||
this->connections_.connectionRatesMICP(cq_s,
|
||||
microbialConcentration,
|
||||
oxygenConcentration,
|
||||
ureaConcentration);
|
||||
}
|
||||
|
||||
// Store the perforation pressure for later usage.
|
||||
@@ -2138,32 +2185,6 @@ namespace Opm
|
||||
}
|
||||
|
||||
|
||||
template <typename TypeTag>
|
||||
typename StandardWell<TypeTag>::Eval
|
||||
StandardWell<TypeTag>::
|
||||
connectionRateBrine(double& rate,
|
||||
const double vap_wat_rate,
|
||||
const std::vector<EvalWell>& cq_s,
|
||||
const IntensiveQuantities& intQuants) const
|
||||
{
|
||||
// TODO: the application of well efficiency factor has not been tested with an example yet
|
||||
const unsigned waterCompIdx = Indices::canonicalToActiveComponentIndex(FluidSystem::waterCompIdx);
|
||||
// Correction salt rate; evaporated water does not contain salt
|
||||
EvalWell cq_s_sm = cq_s[waterCompIdx] - vap_wat_rate;
|
||||
if (this->isInjector()) {
|
||||
cq_s_sm *= this->wsalt();
|
||||
} else {
|
||||
cq_s_sm *= this->extendEval(intQuants.fluidState().saltConcentration());
|
||||
}
|
||||
|
||||
// Note. Efficiency factor is handled in the output layer
|
||||
rate = cq_s_sm.value();
|
||||
|
||||
cq_s_sm *= this->well_efficiency_factor_;
|
||||
return Base::restrictEval(cq_s_sm);
|
||||
}
|
||||
|
||||
|
||||
template <typename TypeTag>
|
||||
typename StandardWell<TypeTag>::Eval
|
||||
StandardWell<TypeTag>::
|
||||
@@ -2245,130 +2266,6 @@ namespace Opm
|
||||
}
|
||||
|
||||
|
||||
template <typename TypeTag>
|
||||
typename StandardWell<TypeTag>::Eval
|
||||
StandardWell<TypeTag>::
|
||||
connectionRateFoam(const std::vector<EvalWell>& cq_s,
|
||||
const IntensiveQuantities& intQuants,
|
||||
DeferredLogger& deferred_logger) const
|
||||
{
|
||||
// TODO: the application of well efficiency factor has not been tested with an example yet
|
||||
auto getFoamTransportIdx = [&deferred_logger] {
|
||||
switch (FoamModule::transportPhase()) {
|
||||
case Phase::WATER: {
|
||||
return Indices::canonicalToActiveComponentIndex(FluidSystem::waterCompIdx);
|
||||
}
|
||||
case Phase::GAS: {
|
||||
return Indices::canonicalToActiveComponentIndex(FluidSystem::gasCompIdx);
|
||||
}
|
||||
case Phase::SOLVENT: {
|
||||
if constexpr (has_solvent)
|
||||
return static_cast<unsigned>(Indices::contiSolventEqIdx);
|
||||
else
|
||||
OPM_DEFLOG_THROW(std::runtime_error, "Foam transport phase is SOLVENT but SOLVENT is not activated.", deferred_logger);
|
||||
}
|
||||
default: {
|
||||
OPM_DEFLOG_THROW(std::runtime_error, "Foam transport phase must be GAS/WATER/SOLVENT.", deferred_logger);
|
||||
}
|
||||
}
|
||||
};
|
||||
EvalWell cq_s_foam = cq_s[getFoamTransportIdx()] * this->well_efficiency_factor_;
|
||||
if (this->isInjector()) {
|
||||
cq_s_foam *= this->wfoam();
|
||||
} else {
|
||||
cq_s_foam *= this->extendEval(intQuants.foamConcentration());
|
||||
}
|
||||
return Base::restrictEval(cq_s_foam);
|
||||
}
|
||||
|
||||
|
||||
template <typename TypeTag>
|
||||
std::tuple<typename StandardWell<TypeTag>::Eval,
|
||||
typename StandardWell<TypeTag>::Eval,
|
||||
typename StandardWell<TypeTag>::Eval>
|
||||
StandardWell<TypeTag>::
|
||||
connectionRatesMICP(const std::vector<EvalWell>& cq_s,
|
||||
const IntensiveQuantities& intQuants) const
|
||||
{
|
||||
const unsigned waterCompIdx = Indices::canonicalToActiveComponentIndex(FluidSystem::waterCompIdx);
|
||||
EvalWell cq_s_microbe = cq_s[waterCompIdx];
|
||||
if (this->isInjector()) {
|
||||
cq_s_microbe *= this->wmicrobes();
|
||||
} else {
|
||||
cq_s_microbe *= this->extendEval(intQuants.microbialConcentration());
|
||||
}
|
||||
|
||||
EvalWell cq_s_oxygen = cq_s[waterCompIdx];
|
||||
if (this->isInjector()) {
|
||||
cq_s_oxygen *= this->woxygen();
|
||||
} else {
|
||||
cq_s_oxygen *= this->extendEval(intQuants.oxygenConcentration());
|
||||
}
|
||||
|
||||
EvalWell cq_s_urea = cq_s[waterCompIdx];
|
||||
if (this->isInjector()) {
|
||||
cq_s_urea *= this->wurea();
|
||||
} else {
|
||||
cq_s_urea *= this->extendEval(intQuants.ureaConcentration());
|
||||
}
|
||||
|
||||
return {Base::restrictEval(cq_s_microbe),
|
||||
Base::restrictEval(cq_s_oxygen),
|
||||
Base::restrictEval(cq_s_urea)};
|
||||
}
|
||||
|
||||
|
||||
template <typename TypeTag>
|
||||
std::tuple<typename StandardWell<TypeTag>::Eval,
|
||||
typename StandardWell<TypeTag>::EvalWell>
|
||||
StandardWell<TypeTag>::
|
||||
connectionRatePolymer(double& rate,
|
||||
const std::vector<EvalWell>& cq_s,
|
||||
const IntensiveQuantities& intQuants) const
|
||||
{
|
||||
// TODO: the application of well efficiency factor has not been tested with an example yet
|
||||
const unsigned waterCompIdx = Indices::canonicalToActiveComponentIndex(FluidSystem::waterCompIdx);
|
||||
EvalWell cq_s_poly = cq_s[waterCompIdx];
|
||||
if (this->isInjector()) {
|
||||
cq_s_poly *= this->wpolymer();
|
||||
} else {
|
||||
cq_s_poly *= this->extendEval(intQuants.polymerConcentration() * intQuants.polymerViscosityCorrection());
|
||||
}
|
||||
// Note. Efficiency factor is handled in the output layer
|
||||
rate = cq_s_poly.value();
|
||||
|
||||
cq_s_poly *= this->well_efficiency_factor_;
|
||||
|
||||
return {Base::restrictEval(cq_s_poly), cq_s_poly};
|
||||
}
|
||||
|
||||
|
||||
template <typename TypeTag>
|
||||
std::tuple<typename StandardWell<TypeTag>::Eval,
|
||||
typename StandardWell<TypeTag>::EvalWell>
|
||||
StandardWell<TypeTag>::
|
||||
connectionRatezFraction(double& rate,
|
||||
const double dis_gas_rate,
|
||||
const std::vector<EvalWell>& cq_s,
|
||||
const IntensiveQuantities& intQuants) const
|
||||
{
|
||||
// TODO: the application of well efficiency factor has not been tested with an example yet
|
||||
const unsigned gasCompIdx = Indices::canonicalToActiveComponentIndex(FluidSystem::gasCompIdx);
|
||||
EvalWell cq_s_zfrac_effective = cq_s[gasCompIdx];
|
||||
if (this->isInjector()) {
|
||||
cq_s_zfrac_effective *= this->wsolvent();
|
||||
} else if (cq_s_zfrac_effective.value() != 0.0) {
|
||||
const double dis_gas_frac = dis_gas_rate / cq_s_zfrac_effective.value();
|
||||
cq_s_zfrac_effective *= this->extendEval(dis_gas_frac*intQuants.xVolume() + (1.0-dis_gas_frac)*intQuants.yVolume());
|
||||
}
|
||||
|
||||
rate = cq_s_zfrac_effective.value();
|
||||
|
||||
cq_s_zfrac_effective *= this->well_efficiency_factor_;
|
||||
return {Base::restrictEval(cq_s_zfrac_effective), cq_s_zfrac_effective};
|
||||
}
|
||||
|
||||
|
||||
template <typename TypeTag>
|
||||
template<class Value>
|
||||
void
|
||||
|
||||
@@ -72,6 +72,9 @@ class WellInterface : public WellInterfaceIndices<GetPropType<TypeTag, Propertie
|
||||
GetPropType<TypeTag, Properties::Indices>,
|
||||
GetPropType<TypeTag, Properties::Scalar>>
|
||||
{
|
||||
using Base = WellInterfaceIndices<GetPropType<TypeTag, Properties::FluidSystem>,
|
||||
GetPropType<TypeTag, Properties::Indices>,
|
||||
GetPropType<TypeTag, Properties::Scalar>>;
|
||||
public:
|
||||
using ModelParameters = BlackoilModelParametersEbos<TypeTag>;
|
||||
|
||||
@@ -94,8 +97,8 @@ public:
|
||||
|
||||
using VectorBlockType = Dune::FieldVector<Scalar, Indices::numEq>;
|
||||
using MatrixBlockType = Dune::FieldMatrix<Scalar, Indices::numEq, Indices::numEq>;
|
||||
using Eval = typename Base::Eval;
|
||||
using BVector = Dune::BlockVector<VectorBlockType>;
|
||||
using Eval = DenseAd::Evaluation<Scalar, /*size=*/Indices::numEq>;
|
||||
using PressureMatrix = Dune::BCRSMatrix<Opm::MatrixBlock<double, 1, 1>>;
|
||||
|
||||
using RateConverterType =
|
||||
@@ -270,17 +273,6 @@ public:
|
||||
|
||||
Scalar volumetricSurfaceRateForConnection(int cellIdx, int phaseIdx) const;
|
||||
|
||||
template <class EvalWell>
|
||||
Eval restrictEval(const EvalWell& in) const
|
||||
{
|
||||
Eval out = 0.0;
|
||||
out.setValue(in.value());
|
||||
for (int eqIdx = 0; eqIdx < Indices::numEq; ++eqIdx) {
|
||||
out.setDerivative(eqIdx, in.derivative(eqIdx));
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
// TODO: theoretically, it should be a const function
|
||||
// Simulator is not const is because that assembleWellEq is non-const Simulator
|
||||
void wellTesting(const Simulator& simulator,
|
||||
|
||||
@@ -197,6 +197,10 @@ public:
|
||||
|
||||
bool stopppedOrZeroRateTarget(const SummaryState& summary_state,
|
||||
const WellState& well_state) const;
|
||||
|
||||
double wellEfficiencyFactor() const
|
||||
{ return well_efficiency_factor_; }
|
||||
|
||||
protected:
|
||||
bool getAllowCrossFlow() const;
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
#ifndef OPM_WELLINTERFACE_INDICES_HEADER_INCLUDED
|
||||
#define OPM_WELLINTERFACE_INDICES_HEADER_INCLUDED
|
||||
|
||||
#include <opm/material/densead/Evaluation.hpp>
|
||||
|
||||
#include <opm/simulators/wells/WellInterfaceFluidSystem.hpp>
|
||||
|
||||
namespace Opm
|
||||
@@ -35,11 +37,23 @@ public:
|
||||
using WellInterfaceFluidSystem<FluidSystem>::Gas;
|
||||
using WellInterfaceFluidSystem<FluidSystem>::Oil;
|
||||
using WellInterfaceFluidSystem<FluidSystem>::Water;
|
||||
using Eval = DenseAd::Evaluation<Scalar, /*size=*/Indices::numEq>;
|
||||
|
||||
int flowPhaseToEbosCompIdx(const int phaseIdx) const;
|
||||
int ebosCompIdxToFlowCompIdx(const unsigned compIdx) const;
|
||||
double scalingFactor(const int phaseIdx) const;
|
||||
|
||||
template <class EvalWell>
|
||||
Eval restrictEval(const EvalWell& in) const
|
||||
{
|
||||
Eval out = 0.0;
|
||||
out.setValue(in.value());
|
||||
for (int eqIdx = 0; eqIdx < Indices::numEq; ++eqIdx) {
|
||||
out.setDerivative(eqIdx, in.derivative(eqIdx));
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
protected:
|
||||
WellInterfaceIndices(const Well& well,
|
||||
const ParallelWellInfo& parallel_well_info,
|
||||
|
||||
Reference in New Issue
Block a user