mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
Merge pull request #3420 from totto82/removeDerivate
remove derivatives from well rate computations
This commit is contained in:
@@ -961,160 +961,6 @@ computeConnectionDensities(const std::vector<double>& perfComponentRates,
|
||||
}
|
||||
}
|
||||
|
||||
template<class FluidSystem, class Indices, class Scalar>
|
||||
void
|
||||
StandardWellEval<FluidSystem,Indices,Scalar>::
|
||||
computePerfRate(const std::vector<EvalWell>& mob,
|
||||
const EvalWell& pressure,
|
||||
const EvalWell& bhp,
|
||||
const EvalWell& rs,
|
||||
const EvalWell& rv,
|
||||
std::vector<EvalWell>& b_perfcells_dense,
|
||||
const double Tw,
|
||||
const int perf,
|
||||
const bool allow_cf,
|
||||
const bool enable_polymermw,
|
||||
std::vector<EvalWell>& cq_s,
|
||||
double& perf_dis_gas_rate,
|
||||
double& perf_vap_oil_rate,
|
||||
DeferredLogger& deferred_logger) const
|
||||
{
|
||||
// Pressure drawdown (also used to determine direction of flow)
|
||||
const EvalWell well_pressure = bhp + this->perf_pressure_diffs_[perf];
|
||||
EvalWell drawdown = pressure - well_pressure;
|
||||
|
||||
if (enable_polymermw) {
|
||||
if (baseif_.isInjector()) {
|
||||
const int pskin_index = Bhp + 1 + baseif_.numPerfs() + perf;
|
||||
const EvalWell& skin_pressure = primary_variables_evaluation_[pskin_index];
|
||||
drawdown += skin_pressure;
|
||||
}
|
||||
}
|
||||
|
||||
// producing perforations
|
||||
if ( drawdown.value() > 0 ) {
|
||||
//Do nothing if crossflow is not allowed
|
||||
if (!allow_cf && baseif_.isInjector()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// compute component volumetric rates at standard conditions
|
||||
for (int componentIdx = 0; componentIdx < baseif_.numComponents(); ++componentIdx) {
|
||||
const EvalWell cq_p = - Tw * (mob[componentIdx] * drawdown);
|
||||
cq_s[componentIdx] = b_perfcells_dense[componentIdx] * cq_p;
|
||||
}
|
||||
|
||||
if (FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx) && FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx)) {
|
||||
const unsigned oilCompIdx = Indices::canonicalToActiveComponentIndex(FluidSystem::oilCompIdx);
|
||||
const unsigned gasCompIdx = Indices::canonicalToActiveComponentIndex(FluidSystem::gasCompIdx);
|
||||
const EvalWell cq_sOil = cq_s[oilCompIdx];
|
||||
const EvalWell cq_sGas = cq_s[gasCompIdx];
|
||||
const EvalWell dis_gas = rs * cq_sOil;
|
||||
const EvalWell 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 (baseif_.isProducer()) {
|
||||
perf_dis_gas_rate = dis_gas.value();
|
||||
perf_vap_oil_rate = vap_oil.value();
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
//Do nothing if crossflow is not allowed
|
||||
if (!allow_cf && baseif_.isProducer()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Using total mobilities
|
||||
EvalWell total_mob_dense = mob[0];
|
||||
for (int componentIdx = 1; componentIdx < baseif_.numComponents(); ++componentIdx) {
|
||||
total_mob_dense += mob[componentIdx];
|
||||
}
|
||||
|
||||
// injection perforations total volume rates
|
||||
const EvalWell cqt_i = - Tw * (total_mob_dense * drawdown);
|
||||
|
||||
// surface volume fraction of fluids within wellbore
|
||||
std::vector<EvalWell> cmix_s(baseif_.numComponents(), EvalWell{numWellEq_ + Indices::numEq});
|
||||
for (int componentIdx = 0; componentIdx < baseif_.numComponents(); ++componentIdx) {
|
||||
cmix_s[componentIdx] = wellSurfaceVolumeFraction(componentIdx);
|
||||
}
|
||||
|
||||
// compute volume ratio between connection at standard conditions
|
||||
EvalWell volumeRatio(numWellEq_ + Indices::numEq, 0.);
|
||||
if (FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx)) {
|
||||
const unsigned waterCompIdx = Indices::canonicalToActiveComponentIndex(FluidSystem::waterCompIdx);
|
||||
volumeRatio += cmix_s[waterCompIdx] / b_perfcells_dense[waterCompIdx];
|
||||
}
|
||||
|
||||
if constexpr (Indices::enableSolvent) {
|
||||
volumeRatio += cmix_s[Indices::contiSolventEqIdx] / b_perfcells_dense[Indices::contiSolventEqIdx];
|
||||
}
|
||||
|
||||
if (FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx) && FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx)) {
|
||||
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 EvalWell d = EvalWell(numWellEq_ + Indices::numEq, 1.0) - rv * rs;
|
||||
|
||||
if (d.value() == 0.0) {
|
||||
OPM_DEFLOG_THROW(NumericalIssue, "Zero d value obtained for well " << baseif_.name() << " during flux calcuation"
|
||||
<< " with rs " << rs << " and rv " << rv, deferred_logger);
|
||||
}
|
||||
|
||||
const EvalWell tmp_oil = (cmix_s[oilCompIdx] - rv * cmix_s[gasCompIdx]) / d;
|
||||
//std::cout << "tmp_oil " <<tmp_oil << std::endl;
|
||||
volumeRatio += tmp_oil / b_perfcells_dense[oilCompIdx];
|
||||
|
||||
const EvalWell tmp_gas = (cmix_s[gasCompIdx] - rs * cmix_s[oilCompIdx]) / d;
|
||||
//std::cout << "tmp_gas " <<tmp_gas << std::endl;
|
||||
volumeRatio += tmp_gas / b_perfcells_dense[gasCompIdx];
|
||||
}
|
||||
else {
|
||||
if (FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx)) {
|
||||
const unsigned oilCompIdx = Indices::canonicalToActiveComponentIndex(FluidSystem::oilCompIdx);
|
||||
volumeRatio += cmix_s[oilCompIdx] / b_perfcells_dense[oilCompIdx];
|
||||
}
|
||||
if (FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx)) {
|
||||
const unsigned gasCompIdx = Indices::canonicalToActiveComponentIndex(FluidSystem::gasCompIdx);
|
||||
volumeRatio += cmix_s[gasCompIdx] / b_perfcells_dense[gasCompIdx];
|
||||
}
|
||||
}
|
||||
|
||||
// injecting connections total volumerates at standard conditions
|
||||
EvalWell cqt_is = cqt_i/volumeRatio;
|
||||
//std::cout << "volrat " << volumeRatio << " " << volrat_perf_[perf] << std::endl;
|
||||
for (int componentIdx = 0; componentIdx < baseif_.numComponents(); ++componentIdx) {
|
||||
cq_s[componentIdx] = cmix_s[componentIdx] * cqt_is; // * b_perfcells_dense[phase];
|
||||
}
|
||||
|
||||
// calculating the perforation solution gas rate and solution oil rates
|
||||
if (baseif_.isProducer()) {
|
||||
if (FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx) && FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx)) {
|
||||
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 * g_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 double d = 1.0 - rv.value() * rs.value();
|
||||
// vaporized oil into gas
|
||||
// rv * q_gr * b_g = rv * (q_gs - rs * q_os) / d
|
||||
perf_vap_oil_rate = rv.value() * (cq_s[gasCompIdx].value() - rs.value() * cq_s[oilCompIdx].value()) / d;
|
||||
// dissolved of gas in oil
|
||||
// rs * q_or * b_o = rs * (q_os - rv * q_gs) / d
|
||||
perf_dis_gas_rate = rs.value() * (cq_s[oilCompIdx].value() - rv.value() * cq_s[gasCompIdx].value()) / d;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<class FluidSystem, class Indices, class Scalar>
|
||||
void
|
||||
|
||||
Reference in New Issue
Block a user