mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
adding computePerfRate() in MultisegmentWell
not tested yet.
This commit is contained in:
parent
5d79a7f11b
commit
1ffa87561b
@ -711,6 +711,141 @@ namespace Opm
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<typename TypeTag>
|
||||||
|
void
|
||||||
|
MultisegmentWell<TypeTag>::
|
||||||
|
computePerfRate(const IntensiveQuantities& int_quants,
|
||||||
|
const std::vector<EvalWell>& mob_perfcells,
|
||||||
|
const int seg,
|
||||||
|
const double well_index,
|
||||||
|
const EvalWell& segment_pressure,
|
||||||
|
const bool& allow_cf,
|
||||||
|
std::vector<EvalWell>& cq_s) const
|
||||||
|
{
|
||||||
|
const int num_comp = numComponents();
|
||||||
|
std::vector<EvalWell> cmix_s(num_comp, 0.0);
|
||||||
|
|
||||||
|
// the composition of the components inside wellbore
|
||||||
|
for (int comp_idx = 0; comp_idx < num_comp; ++comp_idx) {
|
||||||
|
cmix_s[comp_idx] = surfaceVolumeFraction(seg, comp_idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& fs = int_quants.fluidState();
|
||||||
|
|
||||||
|
const EvalWell pressure_cell = extendEval(fs.pressure(FluidSystem::oilPhaseIdx));
|
||||||
|
const EvalWell rs = extendEval(fs.Rs());
|
||||||
|
const EvalWell rv = extendEval(fs.Rv());
|
||||||
|
|
||||||
|
// not using number_of_phases_ because of solvent
|
||||||
|
std::vector<EvalWell> b_perfcells(num_comp, 0.0);
|
||||||
|
|
||||||
|
for (int phase = 0; phase < number_of_phases_; ++phase) {
|
||||||
|
const int phase_idx_ebos = flowPhaseToEbosPhaseIdx(phase);
|
||||||
|
b_perfcells[phase] = extendEval(fs.invB(phase_idx_ebos));
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: not handling solvent for now
|
||||||
|
// if (has_solvent) {
|
||||||
|
// b_perfcells[contiSolventEqIdx] = extendEval(intQuants.solventInverseFormationVolumeFactor());
|
||||||
|
// }
|
||||||
|
|
||||||
|
// the pressure of the segment
|
||||||
|
const EvalWell seg_pressure = getSegmentPressure(seg);
|
||||||
|
|
||||||
|
// Pressure drawdown (also used to determine direction of flow)
|
||||||
|
// TODO: not considering the two pressure difference for now. Trying to finish the framework first.
|
||||||
|
const EvalWell drawdown = seg_pressure - pressure_cell;
|
||||||
|
|
||||||
|
const Opm::PhaseUsage& pu = phaseUsage();
|
||||||
|
// producing perforations
|
||||||
|
if ( drawdown > 0.0) {
|
||||||
|
// Do nothing is crossflow is not allowed
|
||||||
|
if (!allow_cf && well_type_ == INJECTOR) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// compute component volumetric rates at standard conditions
|
||||||
|
for (int comp_idx = 0; comp_idx < num_comp; ++comp_idx) {
|
||||||
|
const EvalWell cq_p = - well_index * (mob_perfcells[comp_idx] * drawdown);
|
||||||
|
cq_s[comp_idx] = b_perfcells[comp_idx] * cq_p;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (active()[Oil] && active()[Gas]) {
|
||||||
|
const int oilpos = pu.phase_pos[Oil];
|
||||||
|
const int gaspos = pu.phase_pos[Gas];
|
||||||
|
const EvalWell cq_s_oil = cq_s[oilpos];
|
||||||
|
const EvalWell cq_s_gas = cq_s[gaspos];
|
||||||
|
cq_s[gaspos] += rs * cq_s_oil;
|
||||||
|
cq_s[oilpos] += rv * cq_s_gas;
|
||||||
|
}
|
||||||
|
} else { // injecting perforations
|
||||||
|
// Do nothing if crossflow is not allowed
|
||||||
|
if (!allow_cf && well_type_ == PRODUCER) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// for injecting perforations, we use total mobility
|
||||||
|
EvalWell total_mob = mob_perfcells[0];
|
||||||
|
for (int comp_idx = 1; comp_idx < num_comp; ++comp_idx) {
|
||||||
|
total_mob += mob_perfcells[comp_idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
// injection perforations total volume rates
|
||||||
|
const EvalWell cqt_i = - well_index * (total_mob * drawdown);
|
||||||
|
|
||||||
|
// compute volume ratio between connection and at standard conditions
|
||||||
|
EvalWell volume_ratio = 0.0;
|
||||||
|
if (active()[Water]) {
|
||||||
|
const int watpos = pu.phase_pos[Water];
|
||||||
|
volume_ratio += cmix_s[watpos] / b_perfcells[watpos];
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: not handling
|
||||||
|
// if (has_solvent) {
|
||||||
|
// volumeRatio += cmix_s[contiSolventEqIdx] / b_perfcells_dense[contiSolventEqIdx];
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (active()[Oil] && active()[Gas]) {
|
||||||
|
const int oilpos = pu.phase_pos[Oil];
|
||||||
|
const int gaspos = pu.phase_pos[Gas];
|
||||||
|
|
||||||
|
// Incorporate RS/RV factors if both oil and gas active
|
||||||
|
// TODO: not sure we use rs rv from the perforation cells when handling injecting perforations
|
||||||
|
// basically, for injecting perforations, the wellbore is the upstreaming side.
|
||||||
|
const EvalWell d = 1.0 - rv * rs;
|
||||||
|
|
||||||
|
if (d.value() == 0.0) {
|
||||||
|
OPM_THROW(Opm::NumericalProblem, "Zero d value obtained for well " << name() << " during flux calcuation"
|
||||||
|
<< " with rs " << rs << " and rv " << rv);
|
||||||
|
}
|
||||||
|
|
||||||
|
const EvalWell tmp_oil = (cmix_s[oilpos] - rv * cmix_s[gaspos]) / d;
|
||||||
|
volume_ratio += tmp_oil / b_perfcells[oilpos];
|
||||||
|
|
||||||
|
const EvalWell tmp_gas = (cmix_s[gaspos] - rs * cmix_s[oilpos]) / d;
|
||||||
|
volume_ratio += tmp_gas / b_perfcells[gaspos];
|
||||||
|
} else { // not having gas and oil at the same time
|
||||||
|
if (active()[Oil]) {
|
||||||
|
const int oilpos = pu.phase_pos[Oil];
|
||||||
|
volume_ratio += cmix_s[oilpos] / b_perfcells[oilpos];
|
||||||
|
}
|
||||||
|
if (active()[Gas]) {
|
||||||
|
const int gaspos = pu.phase_pos[Gas];
|
||||||
|
volume_ratio += cmix_s[gaspos] / b_perfcells[gaspos];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// injecting connections total volumerates at standard conditions
|
||||||
|
EvalWell cqt_is = cqt_i / volume_ratio;
|
||||||
|
for (int comp_idx = 0; comp_idx < num_comp; ++comp_idx) {
|
||||||
|
cq_s[comp_idx] = cmix_s[comp_idx] * cqt_is; // // TODO: checking there * b_perfcells[phase];
|
||||||
|
}
|
||||||
|
} // end for injection perforations
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template<typename TypeTag>
|
template<typename TypeTag>
|
||||||
typename MultisegmentWell<TypeTag>::EvalWell
|
typename MultisegmentWell<TypeTag>::EvalWell
|
||||||
MultisegmentWell<TypeTag>::
|
MultisegmentWell<TypeTag>::
|
||||||
@ -857,6 +992,9 @@ namespace Opm
|
|||||||
surf_dens[phase] = FluidSystem::referenceDensity( flowPhaseToEbosPhaseIdx(phase), pvt_region_index );
|
surf_dens[phase] = FluidSystem::referenceDensity( flowPhaseToEbosPhaseIdx(phase), pvt_region_index );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: not handling solvent for now.
|
||||||
|
|
||||||
EvalWell density(0.0);
|
EvalWell density(0.0);
|
||||||
for (int comp_idx = 0; comp_idx < num_comp; ++comp_idx) {
|
for (int comp_idx = 0; comp_idx < num_comp; ++comp_idx) {
|
||||||
density += surf_dens[comp_idx] * mix_s[comp_idx];
|
density += surf_dens[comp_idx] * mix_s[comp_idx];
|
||||||
|
Loading…
Reference in New Issue
Block a user