mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-16 20:24:48 -06:00
Initial well rates with the well potentials and scale the segment rates
Initialize the well rates with well potentials when computing rates from bhp or bhp(thp) The bhp was already initialized. Scale the segment rates and pressure to adapt to changes in well rate and bhp Improves convergence of the well potential calculations
This commit is contained in:
parent
02bab0957d
commit
d027205c34
@ -339,10 +339,8 @@ namespace Opm
|
|||||||
const double relaxation_factor=1.0) const;
|
const double relaxation_factor=1.0) const;
|
||||||
|
|
||||||
|
|
||||||
// initialize the segment rates with well rates
|
// scale the segment rates and pressure based on well rates and bhp
|
||||||
// when there is no more accurate way to initialize the segment rates, we initialize
|
void scaleSegmentRatesAndPressureWithWellRatesAndPressure(WellState& well_state) const;
|
||||||
// the segment rates based on well rates with a simple strategy
|
|
||||||
void initSegmentRatesWithWellRates(WellState& well_state) const;
|
|
||||||
|
|
||||||
// computing the accumulation term for later use in well mass equations
|
// computing the accumulation term for later use in well mass equations
|
||||||
void computeInitialSegmentFluids(const Simulator& ebos_simulator);
|
void computeInitialSegmentFluids(const Simulator& ebos_simulator);
|
||||||
|
@ -364,12 +364,13 @@ namespace Opm
|
|||||||
}
|
}
|
||||||
case Well::InjectorCMode::BHP:
|
case Well::InjectorCMode::BHP:
|
||||||
{
|
{
|
||||||
well_state.segPress()[top_segment_index] = controls.bhp_limit;
|
well_state.bhp()[well_index] = controls.bhp_limit;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Well::InjectorCMode::GRUP:
|
case Well::InjectorCMode::GRUP:
|
||||||
{
|
{
|
||||||
//do nothing at the moment
|
// for GRUP the well rates are scaled
|
||||||
|
// in checkGroupConstraints
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Well::InjectorCMode::CMODE_UNDEFINED:
|
case Well::InjectorCMode::CMODE_UNDEFINED:
|
||||||
@ -478,7 +479,7 @@ namespace Opm
|
|||||||
}
|
}
|
||||||
case Well::ProducerCMode::BHP:
|
case Well::ProducerCMode::BHP:
|
||||||
{
|
{
|
||||||
well_state.segPress()[top_segment_index] = controls.bhp_limit;
|
well_state.bhp()[well_index] = controls.bhp_limit;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Well::ProducerCMode::THP:
|
case Well::ProducerCMode::THP:
|
||||||
@ -493,7 +494,8 @@ namespace Opm
|
|||||||
}
|
}
|
||||||
case Well::ProducerCMode::GRUP:
|
case Well::ProducerCMode::GRUP:
|
||||||
{
|
{
|
||||||
//do nothing at the moment
|
// for GRUP the well rates are scaled
|
||||||
|
// in checkGroupConstraints
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Well::ProducerCMode::CMODE_UNDEFINED:
|
case Well::ProducerCMode::CMODE_UNDEFINED:
|
||||||
@ -508,8 +510,9 @@ namespace Opm
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// compute the segment rates based on the wellRates
|
// scale segment rates based on the wellRates
|
||||||
initSegmentRatesWithWellRates(well_state);
|
// and segment pressure based on bhp
|
||||||
|
scaleSegmentRatesAndPressureWithWellRatesAndPressure(well_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -519,31 +522,33 @@ namespace Opm
|
|||||||
template <typename TypeTag>
|
template <typename TypeTag>
|
||||||
void
|
void
|
||||||
MultisegmentWell<TypeTag>::
|
MultisegmentWell<TypeTag>::
|
||||||
initSegmentRatesWithWellRates(WellState& well_state) const
|
scaleSegmentRatesAndPressureWithWellRatesAndPressure(WellState& well_state) const
|
||||||
{
|
{
|
||||||
|
const int top_segment_index = well_state.topSegmentIndex(index_of_well_);
|
||||||
|
|
||||||
for (int phase = 0; phase < number_of_phases_; ++phase) {
|
for (int phase = 0; phase < number_of_phases_; ++phase) {
|
||||||
const double perf_phaserate = well_state.wellRates()[number_of_phases_ * index_of_well_ + phase] / number_of_perforations_;
|
const double well_phase_rate = well_state.wellRates()[number_of_phases_*index_of_well_ + phase];
|
||||||
for (int perf = 0; perf < number_of_perforations_; ++perf) {
|
const double unscaled_top_seg_rate = well_state.segRates()[number_of_phases_*top_segment_index + phase];
|
||||||
well_state.perfPhaseRates()[number_of_phases_ * (first_perf_ + perf) + phase] = perf_phaserate;
|
if (std::abs(unscaled_top_seg_rate) > 1e-12)
|
||||||
|
{
|
||||||
|
for (int seg = 0; seg < numberOfSegments(); ++seg) {
|
||||||
|
const int seg_index = top_segment_index + seg;
|
||||||
|
well_state.segRates()[number_of_phases_*seg_index + phase] *= well_phase_rate/unscaled_top_seg_rate;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<double> perforation_rates(well_state.perfPhaseRates().begin() + number_of_phases_ * first_perf_,
|
//scale segment pressures
|
||||||
well_state.perfPhaseRates().begin() +
|
const double bhp = well_state.bhp()[index_of_well_];
|
||||||
number_of_phases_ * (first_perf_ + number_of_perforations_) );
|
const double unscaled_top_seg_pressure = well_state.segPress()[top_segment_index];
|
||||||
std::vector<double> segment_rates;
|
for (int seg = 0; seg < numberOfSegments(); ++seg) {
|
||||||
WellState::calculateSegmentRates(segment_inlets_, segment_perforations_, perforation_rates, number_of_phases_,
|
const int seg_index = top_segment_index + seg;
|
||||||
0, segment_rates);
|
well_state.segPress()[seg_index] *= bhp/unscaled_top_seg_pressure;
|
||||||
const int top_segment_index = well_state.topSegmentIndex(index_of_well_);
|
}
|
||||||
std::copy(segment_rates.begin(), segment_rates.end(),
|
|
||||||
well_state.segRates().begin() + number_of_phases_ * top_segment_index );
|
|
||||||
// we need to check the top segment rates should be same with the well rates
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template <typename TypeTag>
|
template <typename TypeTag>
|
||||||
ConvergenceReport
|
ConvergenceReport
|
||||||
MultisegmentWell<TypeTag>::
|
MultisegmentWell<TypeTag>::
|
||||||
@ -865,6 +870,15 @@ namespace Opm
|
|||||||
}
|
}
|
||||||
well_state_copy.bhp()[well_copy.index_of_well_] = bhp;
|
well_state_copy.bhp()[well_copy.index_of_well_] = bhp;
|
||||||
|
|
||||||
|
// initialized the well rates with the potentials i.e. the well rates based on bhp
|
||||||
|
const int np = number_of_phases_;
|
||||||
|
const double sign = well_copy.well_ecl_.isInjector()? 1.0:-1.0;
|
||||||
|
for (int phase = 0; phase < np; ++phase){
|
||||||
|
well_state_copy.wellRates()[well_copy.index_of_well_*np + phase] = sign*well_state_copy.wellPotentials()[well_copy.index_of_well_*np + phase];
|
||||||
|
}
|
||||||
|
// we also want to adjust the segment rates and pressure
|
||||||
|
well_copy.scaleSegmentRatesAndPressureWithWellRatesAndPressure(well_state_copy);
|
||||||
|
|
||||||
well_copy.calculateExplicitQuantities(ebosSimulator, well_state_copy, deferred_logger);
|
well_copy.calculateExplicitQuantities(ebosSimulator, well_state_copy, deferred_logger);
|
||||||
const double dt = ebosSimulator.timeStepSize();
|
const double dt = ebosSimulator.timeStepSize();
|
||||||
// iterate to get a solution at the given bhp.
|
// iterate to get a solution at the given bhp.
|
||||||
@ -873,7 +887,6 @@ namespace Opm
|
|||||||
|
|
||||||
// compute the potential and store in the flux vector.
|
// compute the potential and store in the flux vector.
|
||||||
well_flux.clear();
|
well_flux.clear();
|
||||||
const int np = number_of_phases_;
|
|
||||||
well_flux.resize(np, 0.0);
|
well_flux.resize(np, 0.0);
|
||||||
for (int compIdx = 0; compIdx < num_components_; ++compIdx) {
|
for (int compIdx = 0; compIdx < num_components_; ++compIdx) {
|
||||||
const EvalWell rate = well_copy.getQs(compIdx);
|
const EvalWell rate = well_copy.getQs(compIdx);
|
||||||
|
Loading…
Reference in New Issue
Block a user