diff --git a/CMakeLists_files.cmake b/CMakeLists_files.cmake
index 05c83b1f6..4588c2dd9 100644
--- a/CMakeLists_files.cmake
+++ b/CMakeLists_files.cmake
@@ -186,6 +186,7 @@ list (APPEND MAIN_SOURCE_FILES
opm/simulators/wells/ParallelWellInfo.cpp
opm/simulators/wells/PerfData.cpp
opm/simulators/wells/RateConverter.cpp
+ opm/simulators/wells/RatioCalculator.cpp
opm/simulators/wells/SegmentState.cpp
opm/simulators/wells/SingleWellState.cpp
opm/simulators/wells/StandardWellAssemble.cpp
@@ -988,6 +989,7 @@ list (APPEND PUBLIC_HEADER_FILES
opm/simulators/wells/PerfData.hpp
opm/simulators/wells/PerforationData.hpp
opm/simulators/wells/RateConverter.hpp
+ opm/simulators/wells/RatioCalculator.hpp
opm/simulators/wells/RegionAttributeHelpers.hpp
opm/simulators/wells/RegionAverageCalculator.hpp
opm/simulators/wells/SingleWellState.hpp
diff --git a/opm/simulators/wells/RatioCalculator.cpp b/opm/simulators/wells/RatioCalculator.cpp
new file mode 100644
index 000000000..d64990b7c
--- /dev/null
+++ b/opm/simulators/wells/RatioCalculator.cpp
@@ -0,0 +1,268 @@
+/*
+ Copyright 2017 SINTEF Digital, Mathematics and Cybernetics.
+ Copyright 2017 Statoil ASA.
+ Copyright 2016 - 2017 IRIS AS.
+
+ 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 .
+*/
+
+#include
+#include
+
+#include
+#include
+
+#include
+#include
+
+#include
+
+namespace {
+ template
+ auto dValueError(const dValue& d,
+ const std::string& name,
+ const std::string& methodName,
+ const Value& Rs,
+ const Value& Rv,
+ const Value& pressure)
+ {
+ return fmt::format("Problematic d value {} obtained for well {}"
+ " during {} calculations with rs {}"
+ ", rv {} and pressure {}."
+ " Continue as if no dissolution (rs = 0) and vaporization (rv = 0) "
+ " for this connection.", d, name, methodName, Rs, Rv, pressure);
+ }
+}
+
+namespace Opm {
+
+template
+RatioCalculator::
+RatioCalculator(unsigned gasCompIdx,
+ unsigned oilCompIdx,
+ unsigned waterCompIdx,
+ std::string_view name)
+ : gasComp_{gasCompIdx}
+ , oilComp_(oilCompIdx)
+ , waterComp_{waterCompIdx}
+ , name_(name)
+{
+}
+
+template
+void
+RatioCalculator::
+disOilVapWatVolumeRatio(Value& volumeRatio,
+ const Value& rvw,
+ const Value& rsw,
+ const Value& pressure,
+ const std::vector& cmix_s,
+ const std::vector& b_perfcells_dense,
+ DeferredLogger& deferred_logger) const
+{
+ // Incorporate RSW/RVW factors if both water and gas active
+ const Value d = 1.0 - rvw * rsw;
+
+ if (d <= 0.0) {
+ deferred_logger.debug(dValueError(d, name_,
+ "disOilVapWatVolumeRatio",
+ rsw, rvw, pressure));
+ }
+ const Value tmp_wat = d > 0.0 ? (cmix_s[waterComp_] - rvw * cmix_s[gasComp_]) / d
+ : cmix_s[waterComp_];
+ volumeRatio += tmp_wat / b_perfcells_dense[waterComp_];
+
+ const Value tmp_gas = d > 0.0 ? (cmix_s[gasComp_] - rsw * cmix_s[waterComp_]) / d
+ : cmix_s[gasComp_];
+ volumeRatio += tmp_gas / b_perfcells_dense[gasComp_];
+}
+
+template
+void
+RatioCalculator::
+gasOilPerfRateInj(const std::vector& cq_s,
+ PerforationRates& perf_rates,
+ const Value& rv,
+ const Value& rs,
+ const Value& pressure,
+ const Value& rvw,
+ const bool waterActive,
+ DeferredLogger& deferred_logger) const
+{
+ // TODO: the formulations here remain to be tested with cases with strong crossflow through production wells
+ // s means standard condition, r means reservoir condition
+ // q_os = q_or * b_o + rv * q_gr * b_g
+ // q_gs = q_gr * b_g + rs * q_or * b_o
+ // d = 1.0 - rs * rv
+ // q_or = 1 / (b_o * d) * (q_os - rv * q_gs)
+ // q_gr = 1 / (b_g * d) * (q_gs - rs * q_os)
+
+ const Scalar d = 1.0 - getValue(rv) * getValue(rs);
+
+ if (d <= 0.0) {
+ deferred_logger.debug(dValueError(d, name_,
+ "gasOilPerfRateInj",
+ rs, rv, pressure));
+ } else {
+ // vaporized oil into gas
+ // rv * q_gr * b_g = rv * (q_gs - rs * q_os) / d
+ perf_rates.vap_oil = getValue(rv) * (getValue(cq_s[gasComp_]) -
+ getValue(rs) * getValue(cq_s[oilComp_])) / d;
+ // dissolved of gas in oil
+ // rs * q_or * b_o = rs * (q_os - rv * q_gs) / d
+ perf_rates.dis_gas = getValue(rs) * (getValue(cq_s[oilComp_]) -
+ getValue(rv) * getValue(cq_s[gasComp_])) / d;
+ }
+
+ if (waterActive) {
+ // q_ws = q_wr * b_w + rvw * q_gr * b_g
+ // q_wr = 1 / b_w * (q_ws - rvw * q_gr * b_g) = 1 / b_w * (q_ws - rvw * 1 / d (q_gs - rs * q_os))
+ // vaporized water in gas
+ // rvw * q_gr * b_g = q_ws -q_wr *b_w = rvw * (q_gs -rs *q_os) / d
+ perf_rates.vap_wat = getValue(rvw) * (getValue(cq_s[gasComp_]) -
+ getValue(rs) * getValue(cq_s[oilComp_])) / d;
+ }
+}
+
+template
+void
+RatioCalculator::
+gasOilPerfRateProd(std::vector& cq_s,
+ PerforationRates& perf_rates,
+ const Value& rv,
+ const Value& rs,
+ const Value& rvw,
+ const bool waterActive,
+ const bool isProducer) const
+{
+ const Value cq_sOil = cq_s[oilComp_];
+ const Value cq_sGas = cq_s[gasComp_];
+ const Value dis_gas = rs * cq_sOil;
+ const Value vap_oil = rv * cq_sGas;
+
+ cq_s[gasComp_] += dis_gas;
+ cq_s[oilComp_] += vap_oil;
+
+ // recording the perforation solution gas rate and solution oil rates
+ if (isProducer) {
+ perf_rates.dis_gas = getValue(dis_gas);
+ perf_rates.vap_oil = getValue(vap_oil);
+ }
+
+ if (waterActive) {
+ const Value vap_wat = rvw * cq_sGas;
+ cq_s[waterComp_] += vap_wat;
+ if (isProducer) {
+ perf_rates.vap_wat = getValue(vap_wat);
+ }
+ }
+}
+
+template
+void
+RatioCalculator::
+gasOilVolumeRatio(Value& volumeRatio,
+ const Value& rv,
+ const Value& rs,
+ const Value& pressure,
+ const std::vector& cmix_s,
+ const std::vector& b_perfcells_dense,
+ DeferredLogger& deferred_logger) const
+{
+ // Incorporate RS/RV factors if both oil and gas active
+ const Value d = 1.0 - rv * rs;
+
+ if (d <= 0.0) {
+ deferred_logger.debug(dValueError(d, name_,
+ "gasOilVolumeRatio",
+ rs, rv, pressure));
+ }
+ const Value tmp_oil = d > 0.0 ? (cmix_s[oilComp_] - rv * cmix_s[gasComp_]) / d
+ : cmix_s[oilComp_];
+ volumeRatio += tmp_oil / b_perfcells_dense[oilComp_];
+
+ const Value tmp_gas = d > 0.0 ? (cmix_s[gasComp_] - rs * cmix_s[oilComp_]) / d
+ : cmix_s[gasComp_];
+ volumeRatio += tmp_gas / b_perfcells_dense[gasComp_];
+}
+
+template
+void
+RatioCalculator::
+gasWaterPerfRateInj(const std::vector& cq_s,
+ PerforationRates& perf_rates,
+ const Value& rvw,
+ const Value& rsw,
+ const Value& pressure,
+ DeferredLogger& deferred_logger) const
+{
+ const Scalar dw = 1.0 - getValue(rvw) * getValue(rsw);
+
+ if (dw <= 0.0) {
+ deferred_logger.debug(dValueError(dw, name_,
+ "gasWaterPerfRateInj",
+ rsw, rvw, pressure));
+ } else {
+ // vaporized water into gas
+ // rvw * q_gr * b_g = rvw * (q_gs - rsw * q_ws) / dw
+ perf_rates.vap_wat = getValue(rvw) * (getValue(cq_s[gasComp_]) -
+ getValue(rsw) * getValue(cq_s[waterComp_])) / dw;
+ // dissolved gas in water
+ // rsw * q_wr * b_w = rsw * (q_ws - rvw * q_gs) / dw
+ perf_rates.dis_gas_in_water = getValue(rsw) * (getValue(cq_s[waterComp_]) -
+ getValue(rvw) * getValue(cq_s[gasComp_])) / dw;
+ }
+}
+
+template
+void
+RatioCalculator::
+gasWaterPerfRateProd(std::vector& cq_s,
+ PerforationRates& perf_rates,
+ const Value& rvw,
+ const Value& rsw,
+ const bool isProducer) const
+{
+ const Value cq_sWat = cq_s[waterComp_];
+ const Value cq_sGas = cq_s[gasComp_];
+ const Value vap_wat = rvw * cq_sGas;
+ const Value dis_gas_wat = rsw * cq_sWat;
+ cq_s[waterComp_] += vap_wat;
+ cq_s[gasComp_] += dis_gas_wat;
+ if (isProducer) {
+ perf_rates.vap_wat = getValue(vap_wat);
+ perf_rates.dis_gas_in_water = getValue(dis_gas_wat);
+ }
+}
+
+#define INSTANTIATE_TYPE(T) \
+ template class RatioCalculator; \
+ template class RatioCalculator>; \
+ template class RatioCalculator>; \
+ template class RatioCalculator>; \
+ template class RatioCalculator>; \
+ template class RatioCalculator>; \
+ template class RatioCalculator>; \
+ template class RatioCalculator>; \
+ template class RatioCalculator>;
+
+INSTANTIATE_TYPE(double)
+
+#if FLOW_INSTANTIATE_FLOAT
+INSTANTIATE_TYPE(float)
+#endif
+
+}
diff --git a/opm/simulators/wells/RatioCalculator.hpp b/opm/simulators/wells/RatioCalculator.hpp
new file mode 100644
index 000000000..8121c3bb1
--- /dev/null
+++ b/opm/simulators/wells/RatioCalculator.hpp
@@ -0,0 +1,102 @@
+/*
+ Copyright 2017 SINTEF Digital, Mathematics and Cybernetics.
+ Copyright 2017 Statoil ASA.
+ Copyright 2016 - 2017 IRIS AS.
+
+ 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 .
+*/
+
+#ifndef RATIO_CALCULATOR_HPP
+#define RATIO_CALCULATOR_HPP
+
+#include
+
+#include
+#include
+#include
+
+namespace Opm {
+
+class DeferredLogger;
+template struct PerforationRates;
+
+template
+class RatioCalculator
+{
+public:
+ using Scalar = decltype(getValue(Value{}));
+
+ RatioCalculator(unsigned gasCompIdx,
+ unsigned oilCompIdx,
+ unsigned waterCompIdx,
+ std::string_view name);
+
+ void disOilVapWatVolumeRatio(Value& volumeRatio,
+ const Value& rvw,
+ const Value& rsw,
+ const Value& pressure,
+ const std::vector& cmix_s,
+ const std::vector& b_perfcells_dense,
+ DeferredLogger& deferred_logger) const;
+
+ void gasOilPerfRateInj(const std::vector& cq_s,
+ PerforationRates& perf_rates,
+ const Value& rv,
+ const Value& rs,
+ const Value& pressure,
+ const Value& rvw,
+ const bool waterActive,
+ DeferredLogger& deferred_logger) const;
+
+ void gasOilPerfRateProd(std::vector& cq_s,
+ PerforationRates& perf_rates,
+ const Value& rv,
+ const Value& rs,
+ const Value& rvw,
+ const bool waterActive,
+ const bool isProducer) const;
+
+ void gasOilVolumeRatio(Value& volumeRatio,
+ const Value& rv,
+ const Value& rs,
+ const Value& pressure,
+ const std::vector& cmix_s,
+ const std::vector& b_perfcells_dense,
+ DeferredLogger& deferred_logger) const;
+
+ void gasWaterPerfRateInj(const std::vector& cq_s,
+ PerforationRates& perf_rates,
+ const Value& rvw,
+ const Value& rsw,
+ const Value& pressure,
+ DeferredLogger& deferred_logger) const;
+
+ void gasWaterPerfRateProd(std::vector& cq_s,
+ PerforationRates& perf_rates,
+ const Value& rvw,
+ const Value& rsw,
+ const bool isProducer) const;
+
+private:
+ unsigned gasComp_;
+ unsigned oilComp_;
+ unsigned waterComp_;
+ std::string name_;
+};
+
+} // namespace Opm
+
+#endif // RATIO_CALCULATOR_HPP
diff --git a/opm/simulators/wells/StandardWell.hpp b/opm/simulators/wells/StandardWell.hpp
index 12353c318..dec3145cd 100644
--- a/opm/simulators/wells/StandardWell.hpp
+++ b/opm/simulators/wells/StandardWell.hpp
@@ -25,6 +25,7 @@
#include
#include
+#include
#include
#include
#include
@@ -466,54 +467,6 @@ namespace Opm
const std::vector& cq_s,
const IntensiveQuantities& intQuants,
DeferredLogger& deferred_logger) const;
-
- template
- void gasOilPerfRateInj(const std::vector& cq_s,
- PerforationRates& perf_rates,
- const Value& rv,
- const Value& rs,
- const Value& pressure,
- const Value& rvw,
- DeferredLogger& deferred_logger) const;
-
- template
- void gasOilPerfRateProd(std::vector& cq_s,
- PerforationRates& perf_rates,
- const Value& rv,
- const Value& rs,
- const Value& rvw) const;
-
- template
- void gasWaterPerfRateProd(std::vector& cq_s,
- PerforationRates& perf_rates,
- const Value& rvw,
- const Value& rsw) const;
-
- template
- void gasWaterPerfRateInj(const std::vector& cq_s,
- PerforationRates& perf_rates,
- const Value& rvw,
- const Value& rsw,
- const Value& pressure,
- DeferredLogger& deferred_logger) const;
-
- template
- void disOilVapWatVolumeRatio(Value& volumeRatio,
- const Value& rvw,
- const Value& rsw,
- const Value& pressure,
- const std::vector& cmix_s,
- const std::vector& b_perfcells_dense,
- DeferredLogger& deferred_logger) const;
-
- template
- void gasOilVolumeRatio(Value& volumeRatio,
- const Value& rv,
- const Value& rs,
- const Value& pressure,
- const std::vector& cmix_s,
- const std::vector& b_perfcells_dense,
- DeferredLogger& deferred_logger) const;
};
}
diff --git a/opm/simulators/wells/StandardWellEval.cpp b/opm/simulators/wells/StandardWellEval.cpp
index f557485bb..bea571816 100644
--- a/opm/simulators/wells/StandardWellEval.cpp
+++ b/opm/simulators/wells/StandardWellEval.cpp
@@ -22,6 +22,7 @@
#include
#include
+#include
#include
#include
@@ -39,8 +40,9 @@
#include
#include
-namespace Opm
-{
+#include
+
+namespace Opm {
template
StandardWellEval::
@@ -208,7 +210,7 @@ init(std::vector& perf_depth,
template
using FS = BlackOilFluidSystem;
-#define INSTANTIATE(T,...) \
+#define INSTANTIATE(T,...) \
template class StandardWellEval,__VA_ARGS__>;
#define INSTANTIATE_TYPE(T) \
diff --git a/opm/simulators/wells/StandardWellEval.hpp b/opm/simulators/wells/StandardWellEval.hpp
index cf832c639..f8967a9f9 100644
--- a/opm/simulators/wells/StandardWellEval.hpp
+++ b/opm/simulators/wells/StandardWellEval.hpp
@@ -19,7 +19,6 @@
along with OPM. If not, see .
*/
-
#ifndef OPM_STANDARDWELL_EVAL_HEADER_INCLUDED
#define OPM_STANDARDWELL_EVAL_HEADER_INCLUDED
diff --git a/opm/simulators/wells/StandardWell_impl.hpp b/opm/simulators/wells/StandardWell_impl.hpp
index 0f089667e..7c11c187e 100644
--- a/opm/simulators/wells/StandardWell_impl.hpp
+++ b/opm/simulators/wells/StandardWell_impl.hpp
@@ -30,39 +30,17 @@
#include
-#include
-
#include
#include
#include
#include
#include
-#include
-
#include
#include
#include
-#include
-namespace {
-
-template
-auto dValueError(const dValue& d,
- const std::string& name,
- const std::string& methodName,
- const Value& Rs,
- const Value& Rv,
- const Value& pressure)
-{
- return fmt::format("Problematic d value {} obtained for well {}"
- " during {} calculations with rs {}"
- ", rv {} and pressure {}."
- " Continue as if no dissolution (rs = 0) and vaporization (rv = 0) "
- " for this connection.", d, name, methodName, Rs, Rv, pressure);
-}
-
-}
+#include
namespace Opm
{
@@ -246,6 +224,19 @@ namespace Opm
drawdown += skin_pressure;
}
+ RatioCalculator ratioCalc{
+ FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx)
+ ? Indices::canonicalToActiveComponentIndex(FluidSystem::gasCompIdx)
+ : -1,
+ FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx)
+ ? Indices::canonicalToActiveComponentIndex(FluidSystem::oilCompIdx)
+ : -1,
+ FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx)
+ ? Indices::canonicalToActiveComponentIndex(FluidSystem::waterCompIdx)
+ : -1,
+ this->name()
+ };
+
// producing perforations
if (drawdown > 0) {
// Do nothing if crossflow is not allowed
@@ -259,10 +250,16 @@ namespace Opm
cq_s[componentIdx] = b_perfcells_dense[componentIdx] * cq_p;
}
- if (FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx) && FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx)) {
- gasOilPerfRateProd(cq_s, perf_rates, rv, rs, rvw);
- } else if (FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx) && FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx)) {
- gasWaterPerfRateProd(cq_s, perf_rates, rvw, rsw);
+ if (FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx) &&
+ FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx))
+ {
+ ratioCalc.gasOilPerfRateProd(cq_s, perf_rates, rv, rs, rvw,
+ FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx),
+ this->isProducer());
+ } else if (FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx) &&
+ FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx))
+ {
+ ratioCalc.gasWaterPerfRateProd(cq_s, perf_rates, rvw, rsw, this->isProducer());
}
} else {
// Do nothing if crossflow is not allowed
@@ -280,8 +277,8 @@ namespace Opm
Value volumeRatio = bhp * 0.0; // initialize it with the correct type
if (FluidSystem::enableVaporizedWater() && FluidSystem::enableDissolvedGasInWater()) {
- disOilVapWatVolumeRatio(volumeRatio, rvw, rsw, pressure,
- cmix_s, b_perfcells_dense, deferred_logger);
+ ratioCalc.disOilVapWatVolumeRatio(volumeRatio, rvw, rsw, pressure,
+ cmix_s, b_perfcells_dense, deferred_logger);
// DISGASW only supported for gas-water CO2STORE/H2STORE case
// and the simulator will throw long before it reach to this point in the code
// For blackoil support of DISGASW we need to add the oil component here
@@ -299,9 +296,12 @@ namespace Opm
volumeRatio += cmix_s[Indices::contiSolventEqIdx] / b_perfcells_dense[Indices::contiSolventEqIdx];
}
- if (FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx) && FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx)) {
- gasOilVolumeRatio(volumeRatio, rv, rs, pressure,
- cmix_s, b_perfcells_dense, deferred_logger);
+ if (FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx) &&
+ FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx))
+ {
+ ratioCalc.gasOilVolumeRatio(volumeRatio, rv, rs, pressure,
+ cmix_s, b_perfcells_dense,
+ deferred_logger);
} else {
if (FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx)) {
const unsigned oilCompIdx = Indices::canonicalToActiveComponentIndex(FluidSystem::oilCompIdx);
@@ -323,14 +323,20 @@ namespace Opm
// calculating the perforation solution gas rate and solution oil rates
if (this->isProducer()) {
- if (FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx) && FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx)) {
- gasOilPerfRateInj(cq_s, perf_rates,
- rv, rs, pressure, rvw, deferred_logger);
+ if (FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx) &&
+ FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx))
+ {
+ ratioCalc.gasOilPerfRateInj(cq_s, perf_rates,
+ rv, rs, pressure, rvw,
+ FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx),
+ deferred_logger);
}
- if (FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx) && FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx)) {
+ if (FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx) &&
+ FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx))
+ {
//no oil
- gasWaterPerfRateInj(cq_s, perf_rates, rvw, rsw,
- pressure, deferred_logger);
+ ratioCalc.gasWaterPerfRateInj(cq_s, perf_rates, rvw, rsw,
+ pressure, deferred_logger);
}
}
}
@@ -2639,207 +2645,4 @@ namespace Opm
return result * this->well_efficiency_factor_;
}
-
-
- template
- template
- void
- StandardWell::
- gasOilPerfRateInj(const std::vector& cq_s,
- PerforationRates& perf_rates,
- const Value& rv,
- const Value& rs,
- const Value& pressure,
- const Value& rvw,
- DeferredLogger& deferred_logger) const
- {
- const unsigned oilCompIdx = Indices::canonicalToActiveComponentIndex(FluidSystem::oilCompIdx);
- const unsigned gasCompIdx = Indices::canonicalToActiveComponentIndex(FluidSystem::gasCompIdx);
- // TODO: the formulations here remain to be tested with cases with strong crossflow through production wells
- // s means standard condition, r means reservoir condition
- // q_os = q_or * b_o + rv * q_gr * b_g
- // q_gs = q_gr * b_g + rs * q_or * b_o
- // d = 1.0 - rs * rv
- // q_or = 1 / (b_o * d) * (q_os - rv * q_gs)
- // q_gr = 1 / (b_g * d) * (q_gs - rs * q_os)
-
- const Scalar d = 1.0 - getValue(rv) * getValue(rs);
-
- if (d <= 0.0) {
- deferred_logger.debug(dValueError(d, this->name(),
- "gasOilPerfRateInj",
- rs, rv, pressure));
- } else {
- // vaporized oil into gas
- // rv * q_gr * b_g = rv * (q_gs - rs * q_os) / d
- perf_rates.vap_oil = getValue(rv) * (getValue(cq_s[gasCompIdx]) - getValue(rs) * getValue(cq_s[oilCompIdx])) / d;
- // dissolved of gas in oil
- // rs * q_or * b_o = rs * (q_os - rv * q_gs) / d
- perf_rates.dis_gas = getValue(rs) * (getValue(cq_s[oilCompIdx]) - getValue(rv) * getValue(cq_s[gasCompIdx])) / d;
- }
-
- if (FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx)) {
- // q_ws = q_wr * b_w + rvw * q_gr * b_g
- // q_wr = 1 / b_w * (q_ws - rvw * q_gr * b_g) = 1 / b_w * (q_ws - rvw * 1 / d (q_gs - rs * q_os))
- // vaporized water in gas
- // rvw * q_gr * b_g = q_ws -q_wr *b_w = rvw * (q_gs -rs *q_os) / d
- perf_rates.vap_wat = getValue(rvw) * (getValue(cq_s[gasCompIdx]) - getValue(rs) * getValue(cq_s[oilCompIdx])) / d;
- }
- }
-
-
-
- template
- template
- void
- StandardWell::
- gasOilPerfRateProd(std::vector& cq_s,
- PerforationRates& perf_rates,
- const Value& rv,
- const Value& rs,
- const Value& rvw) const
- {
- const unsigned oilCompIdx = Indices::canonicalToActiveComponentIndex(FluidSystem::oilCompIdx);
- const unsigned gasCompIdx = Indices::canonicalToActiveComponentIndex(FluidSystem::gasCompIdx);
- const Value cq_sOil = cq_s[oilCompIdx];
- const Value cq_sGas = cq_s[gasCompIdx];
- const Value dis_gas = rs * cq_sOil;
- const Value vap_oil = rv * cq_sGas;
-
- cq_s[gasCompIdx] += dis_gas;
- cq_s[oilCompIdx] += vap_oil;
-
- // recording the perforation solution gas rate and solution oil rates
- if (this->isProducer()) {
- perf_rates.dis_gas = getValue(dis_gas);
- perf_rates.vap_oil = getValue(vap_oil);
- }
-
- if (FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx)) {
- const unsigned waterCompIdx = Indices::canonicalToActiveComponentIndex(FluidSystem::waterCompIdx);
- const Value vap_wat = rvw * cq_sGas;
- cq_s[waterCompIdx] += vap_wat;
- if (this->isProducer())
- perf_rates.vap_wat = getValue(vap_wat);
- }
- }
-
-
- template
- template
- void
- StandardWell::
- gasWaterPerfRateProd(std::vector& cq_s,
- PerforationRates& perf_rates,
- const Value& rvw,
- const Value& rsw) const
- {
- const unsigned waterCompIdx = Indices::canonicalToActiveComponentIndex(FluidSystem::waterCompIdx);
- const unsigned gasCompIdx = Indices::canonicalToActiveComponentIndex(FluidSystem::gasCompIdx);
- const Value cq_sWat = cq_s[waterCompIdx];
- const Value cq_sGas = cq_s[gasCompIdx];
- const Value vap_wat = rvw * cq_sGas;
- const Value dis_gas_wat = rsw * cq_sWat;
- cq_s[waterCompIdx] += vap_wat;
- cq_s[gasCompIdx] += dis_gas_wat;
- if (this->isProducer()) {
- perf_rates.vap_wat = getValue(vap_wat);
- perf_rates.dis_gas_in_water = getValue(dis_gas_wat);
- }
- }
-
-
- template
- template
- void
- StandardWell::
- gasWaterPerfRateInj(const std::vector& cq_s,
- PerforationRates& perf_rates,
- const Value& rvw,
- const Value& rsw,
- const Value& pressure,
- DeferredLogger& deferred_logger) const
-
- {
- const unsigned gasCompIdx = Indices::canonicalToActiveComponentIndex(FluidSystem::gasCompIdx);
- const unsigned waterCompIdx = Indices::canonicalToActiveComponentIndex(FluidSystem::waterCompIdx);
-
- const Scalar dw = 1.0 - getValue(rvw) * getValue(rsw);
-
- if (dw <= 0.0) {
- deferred_logger.debug(dValueError(dw, this->name(),
- "gasWaterPerfRateInj",
- rsw, rvw, pressure));
- } else {
- // vaporized water into gas
- // rvw * q_gr * b_g = rvw * (q_gs - rsw * q_ws) / dw
- perf_rates.vap_wat = getValue(rvw) * (getValue(cq_s[gasCompIdx]) - getValue(rsw) * getValue(cq_s[waterCompIdx])) / dw;
- // dissolved gas in water
- // rsw * q_wr * b_w = rsw * (q_ws - rvw * q_gs) / dw
- perf_rates.dis_gas_in_water = getValue(rsw) * (getValue(cq_s[waterCompIdx]) - getValue(rvw) * getValue(cq_s[gasCompIdx])) / dw;
- }
- }
-
-
- template
- template
- void
- StandardWell::
- disOilVapWatVolumeRatio(Value& volumeRatio,
- const Value& rvw,
- const Value& rsw,
- const Value& pressure,
- const std::vector& cmix_s,
- const std::vector& b_perfcells_dense,
- DeferredLogger& deferred_logger) const
- {
- const unsigned waterCompIdx = Indices::canonicalToActiveComponentIndex(FluidSystem::waterCompIdx);
- const unsigned gasCompIdx = Indices::canonicalToActiveComponentIndex(FluidSystem::gasCompIdx);
- // Incorporate RSW/RVW factors if both water and gas active
- const Value d = 1.0 - rvw * rsw;
-
- if (d <= 0.0) {
- deferred_logger.debug(dValueError(d, this->name(),
- "disOilVapWatVolumeRatio",
- rsw, rvw, pressure));
- }
- const Value tmp_wat = d > 0.0 ? (cmix_s[waterCompIdx] - rvw * cmix_s[gasCompIdx]) / d
- : cmix_s[waterCompIdx];
- volumeRatio += tmp_wat / b_perfcells_dense[waterCompIdx];
-
- const Value tmp_gas = d > 0.0 ? (cmix_s[gasCompIdx] - rsw * cmix_s[waterCompIdx]) / d
- : cmix_s[gasCompIdx];
- volumeRatio += tmp_gas / b_perfcells_dense[gasCompIdx];
- }
-
-
- template
- template
- void
- StandardWell::
- gasOilVolumeRatio(Value& volumeRatio,
- const Value& rv,
- const Value& rs,
- const Value& pressure,
- const std::vector& cmix_s,
- const std::vector& b_perfcells_dense,
- DeferredLogger& deferred_logger) const
- {
- const unsigned oilCompIdx = Indices::canonicalToActiveComponentIndex(FluidSystem::oilCompIdx);
- const unsigned gasCompIdx = Indices::canonicalToActiveComponentIndex(FluidSystem::gasCompIdx);
- // Incorporate RS/RV factors if both oil and gas active
- const Value d = 1.0 - rv * rs;
-
- if (d <= 0.0) {
- deferred_logger.debug(dValueError(d, this->name(),
- "gasOilVolumeRatio",
- rs, rv, pressure));
- }
- const Value tmp_oil = d > 0.0? (cmix_s[oilCompIdx] - rv * cmix_s[gasCompIdx]) / d : cmix_s[oilCompIdx];
- volumeRatio += tmp_oil / b_perfcells_dense[oilCompIdx];
-
- const Value tmp_gas = d > 0.0? (cmix_s[gasCompIdx] - rs * cmix_s[oilCompIdx]) / d : cmix_s[gasCompIdx];
- volumeRatio += tmp_gas / b_perfcells_dense[gasCompIdx];
- }
-
} // namespace Opm