fixing the function checkMaxWaterCutLimit

when looking for the worst offending completion
This commit is contained in:
Kai Bao 2019-06-20 11:52:23 +02:00
parent 8be28e8448
commit 01c9935b02

View File

@ -608,77 +608,71 @@ namespace Opm
checkMaxWaterCutLimit(const WellEconProductionLimits& econ_production_limits, checkMaxWaterCutLimit(const WellEconProductionLimits& econ_production_limits,
const WellState& well_state) const const WellState& well_state) const
{ {
bool water_cut_limit_violated = false;
int worst_offending_completion = INVALIDCOMPLETION;
double violation_extent = -1.0;
const int np = number_of_phases_;
const Opm::PhaseUsage& pu = phaseUsage();
const int well_number = index_of_well_;
assert(FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx)); assert(FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx));
assert(FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx)); assert(FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx));
const double oil_rate = well_state.wellRates()[well_number * np + pu.phase_pos[ Oil ] ]; auto waterCut = [](const double oil_rate, const double water_rate) {
const double water_rate = well_state.wellRates()[well_number * np + pu.phase_pos[ Water ] ];
// both rate should be in the same direction
assert(oil_rate * water_rate >= 0.);
const double liquid_rate = oil_rate + water_rate; const double liquid_rate = oil_rate + water_rate;
double water_cut; if (liquid_rate != 0.) {
if (std::abs(liquid_rate) != 0.) { return (water_rate / liquid_rate);
water_cut = water_rate / liquid_rate;
} else { } else {
water_cut = 0.0; return 0.;
} }
};
const int np = number_of_phases_;
const Opm::PhaseUsage& pu = phaseUsage();
const double oil_rate = well_state.wellRates()[index_of_well_ * np + pu.phase_pos[ Oil ] ];
const double water_rate = well_state.wellRates()[index_of_well_ * np + pu.phase_pos[ Water ] ];
const double water_cut = waterCut(oil_rate, water_rate);
const double max_water_cut_limit = econ_production_limits.maxWaterCut(); const double max_water_cut_limit = econ_production_limits.maxWaterCut();
if (water_cut > max_water_cut_limit) { assert(max_water_cut_limit != 0.);
water_cut_limit_violated = true;
} const bool water_cut_limit_violated = (water_cut > max_water_cut_limit);
int worst_offending_completion = INVALIDCOMPLETION;
double violation_extent = -1.0;
if (water_cut_limit_violated) { if (water_cut_limit_violated) {
// need to handle the worst_offending_connection // the maximum water cut value of the completions
const int perf_start = first_perf_; double max_water_cut_completion = 0.;
const int perf_number = number_of_perforations_;
std::vector<double> water_cut_perf(perf_number); // look for the worst_offending_completion
for (int perf = 0; perf < perf_number; ++perf) { for (const auto& completion : completions_) {
const int i_perf = perf_start + perf;
const double oil_perf_rate = well_state.perfPhaseRates()[i_perf * np + pu.phase_pos[ Oil ] ];
const double water_perf_rate = well_state.perfPhaseRates()[i_perf * np + pu.phase_pos[ Water ] ];
const double liquid_perf_rate = oil_perf_rate + water_perf_rate;
if (std::abs(liquid_perf_rate) != 0.) {
water_cut_perf[perf] = water_perf_rate / liquid_perf_rate;
} else {
water_cut_perf[perf] = 0.;
}
}
const auto& completions = well_ecl_.getCompletions();
const auto& connections = well_ecl_.getConnections();
int complnumIdx = 0; double oil_completion_rate = 0.;
std::vector<double> water_cut_in_completions(completions.size(), 0.0); double water_completion_rate = 0.;
for (const auto& completion : completions) {
int complnum = completion.first; const std::vector<int>& conns = completion.second;
for (int perf = 0; perf < perf_number; ++perf) { for(const int c : conns) {
if (complnum == connections.get ( perf ).complnum()) { const int index_con = c + first_perf_;
water_cut_in_completions[complnumIdx] += water_cut_perf[perf];
} const double oil_connection_rate = well_state.perfPhaseRates()[index_con * np + pu.phase_pos[ Oil ] ];
} oil_completion_rate += oil_connection_rate;
complnumIdx++;
const double water_connection_rate = well_state.perfPhaseRates()[index_con * np + pu.phase_pos[ Water ] ];
water_completion_rate += water_connection_rate;
} }
double max_water_cut_perf = 0.; const double water_cut_completion = waterCut(oil_completion_rate, water_completion_rate);
complnumIdx = 0;
for (const auto& completion : completions) { if (water_cut_completion > max_water_cut_completion) {
if (water_cut_in_completions[complnumIdx] > max_water_cut_perf) {
worst_offending_completion = completion.first; worst_offending_completion = completion.first;
max_water_cut_perf = water_cut_in_completions[complnumIdx]; max_water_cut_completion = water_cut_completion;
}
complnumIdx++;
} }
} // end of for (const auto& completion : completions_)
assert(max_water_cut_limit != 0.); assert(max_water_cut_completion >= max_water_cut_limit);
assert(worst_offending_completion != INVALIDCOMPLETION); assert(worst_offending_completion != INVALIDCOMPLETION);
violation_extent = max_water_cut_perf / max_water_cut_limit;
violation_extent = max_water_cut_completion / max_water_cut_limit;
} }
return std::make_tuple(water_cut_limit_violated, worst_offending_completion, violation_extent); return std::make_tuple(water_cut_limit_violated, worst_offending_completion, violation_extent);