mirror of
https://github.com/OPM/opm-simulators.git
synced 2024-12-02 05:49:09 -06:00
adding the several pressure drop values to WellState for MSW
segpress_ and segrates_ are renamed to help the name style.
This commit is contained in:
parent
c39c6b05eb
commit
251c09a288
@ -380,7 +380,7 @@ namespace Opm
|
||||
const Well::ProductionControls& prod_controls,
|
||||
Opm::DeferredLogger& deferred_logger);
|
||||
|
||||
void assemblePressureEq(const int seg) const;
|
||||
void assemblePressureEq(const int seg, WellState& well_state) const;
|
||||
|
||||
// hytrostatic pressure loss
|
||||
EvalWell getHydroPressureLoss(const int seg) const;
|
||||
@ -388,7 +388,7 @@ namespace Opm
|
||||
// frictinal pressure loss
|
||||
EvalWell getFrictionPressureLoss(const int seg) const;
|
||||
|
||||
void handleAccelerationPressureLoss(const int seg) const;
|
||||
void handleAccelerationPressureLoss(const int seg, WellState& well_state) const;
|
||||
|
||||
// handling the overshooting and undershooting of the fractions
|
||||
void processFractions(const int seg) const;
|
||||
@ -470,7 +470,7 @@ namespace Opm
|
||||
|
||||
double maxPerfPress(const Simulator& ebos_simulator) const;
|
||||
|
||||
void assembleSICDPressureEq(const int seg) const;
|
||||
void assembleSICDPressureEq(const int seg, WellState& well_state) const;
|
||||
|
||||
// TODO: when more ICD devices join, we should have a better interface to do this
|
||||
void calculateSICDFlowScalingFactors();
|
||||
@ -478,7 +478,7 @@ namespace Opm
|
||||
EvalWell pressureDropSpiralICD(const int seg) const;
|
||||
|
||||
// assemble the pressure equation for sub-critical valve (WSEGVALV)
|
||||
void assembleValvePressureEq(const int seg) const;
|
||||
void assembleValvePressureEq(const int seg, WellState& well_state) const;
|
||||
|
||||
EvalWell pressureDropValve(const int seg) const;
|
||||
};
|
||||
|
@ -1984,7 +1984,7 @@ namespace Opm
|
||||
template <typename TypeTag>
|
||||
void
|
||||
MultisegmentWell<TypeTag>::
|
||||
assemblePressureEq(const int seg) const
|
||||
assemblePressureEq(const int seg, WellState& well_state) const
|
||||
{
|
||||
assert(seg != 0); // not top segment
|
||||
|
||||
@ -1993,10 +1993,16 @@ namespace Opm
|
||||
|
||||
// we need to handle the pressure difference between the two segments
|
||||
// we only consider the hydrostatic pressure loss first
|
||||
pressure_equation -= getHydroPressureLoss(seg);
|
||||
// TODO: we might be able to add member variables to store these values, then we update well state
|
||||
// after converged
|
||||
const auto hydro_pressure_drop = getHydroPressureLoss(seg);
|
||||
well_state.segPressDropHydroStatic()[seg] = hydro_pressure_drop.value();
|
||||
pressure_equation -= hydro_pressure_drop;
|
||||
|
||||
if (frictionalPressureLossConsidered()) {
|
||||
pressure_equation -= getFrictionPressureLoss(seg);
|
||||
const auto friction_pressure_drop = getFrictionPressureLoss(seg);
|
||||
pressure_equation -= friction_pressure_drop;
|
||||
well_state.segPressDropFriction()[seg] = friction_pressure_drop.value();
|
||||
}
|
||||
|
||||
resWell_[seg][SPres] = pressure_equation.value();
|
||||
@ -2014,7 +2020,7 @@ namespace Opm
|
||||
}
|
||||
|
||||
if (accelerationalPressureLossConsidered()) {
|
||||
handleAccelerationPressureLoss(seg);
|
||||
handleAccelerationPressureLoss(seg, well_state);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2061,7 +2067,7 @@ namespace Opm
|
||||
template <typename TypeTag>
|
||||
void
|
||||
MultisegmentWell<TypeTag>::
|
||||
handleAccelerationPressureLoss(const int seg) const
|
||||
handleAccelerationPressureLoss(const int seg, WellState& well_state) const
|
||||
{
|
||||
// TODO: this pressure loss is not significant enough to be well tested yet.
|
||||
// handle the out velcocity head
|
||||
@ -2089,6 +2095,7 @@ namespace Opm
|
||||
const EvalWell inlet_density = segment_densities_[inlet];
|
||||
const EvalWell inlet_mass_rate = segment_mass_rates_[inlet];
|
||||
const EvalWell inlet_velocity_head = mswellhelpers::velocityHead(area, inlet_mass_rate, inlet_density);
|
||||
well_state.segPressDropAcceleration()[seg] = inlet_velocity_head.value();
|
||||
resWell_[seg][SPres] += inlet_velocity_head.value();
|
||||
for (int pv_idx = 0; pv_idx < numWellEq; ++pv_idx) {
|
||||
duneD_[seg][inlet][SPres][pv_idx] += inlet_velocity_head.derivative(pv_idx + numEq);
|
||||
@ -2537,15 +2544,19 @@ namespace Opm
|
||||
// TODO: maybe the following should go to the function assemblePressureEq()
|
||||
switch(segmentSet()[seg].segmentType()) {
|
||||
case Segment::SegmentType::SICD :
|
||||
assembleSICDPressureEq(seg);
|
||||
assembleSICDPressureEq(seg, well_state);
|
||||
break;
|
||||
case Segment::SegmentType::VALVE :
|
||||
assembleValvePressureEq(seg);
|
||||
assembleValvePressureEq(seg, well_state);
|
||||
break;
|
||||
default :
|
||||
assemblePressureEq(seg);
|
||||
assemblePressureEq(seg, well_state);
|
||||
}
|
||||
}
|
||||
|
||||
well_state.segPressDrop()[seg] = well_state.segPressDropHydroStatic()[seg] +
|
||||
well_state.segPressDropFriction()[seg] +
|
||||
well_state.segPressDropAcceleration()[seg];
|
||||
}
|
||||
}
|
||||
|
||||
@ -3064,7 +3075,7 @@ namespace Opm
|
||||
template<typename TypeTag>
|
||||
void
|
||||
MultisegmentWell<TypeTag>::
|
||||
assembleSICDPressureEq(const int seg) const
|
||||
assembleSICDPressureEq(const int seg, WellState& well_state) const
|
||||
{
|
||||
// TODO: upwinding needs to be taken care of
|
||||
// top segment can not be a spiral ICD device
|
||||
@ -3076,7 +3087,9 @@ namespace Opm
|
||||
|
||||
EvalWell pressure_equation = getSegmentPressure(seg);
|
||||
|
||||
pressure_equation = pressure_equation - pressureDropSpiralICD(seg);
|
||||
const auto sicd_pressure_drop = pressureDropSpiralICD(seg);
|
||||
pressure_equation = pressure_equation - sicd_pressure_drop;
|
||||
well_state.segPressDropFriction()[seg] = sicd_pressure_drop.value();
|
||||
|
||||
resWell_[seg][SPres] = pressure_equation.value();
|
||||
for (int pv_idx = 0; pv_idx < numWellEq; ++pv_idx) {
|
||||
@ -3100,7 +3113,7 @@ namespace Opm
|
||||
template<typename TypeTag>
|
||||
void
|
||||
MultisegmentWell<TypeTag>::
|
||||
assembleValvePressureEq(const int seg) const
|
||||
assembleValvePressureEq(const int seg, WellState& well_state) const
|
||||
{
|
||||
// TODO: upwinding needs to be taken care of
|
||||
// top segment can not be a spiral ICD device
|
||||
@ -3116,7 +3129,9 @@ namespace Opm
|
||||
|
||||
// const int seg_upwind = upwinding_segments_[seg];
|
||||
|
||||
pressure_equation = pressure_equation - pressureDropValve(seg);
|
||||
const auto valve_pressure_drop = pressureDropValve(seg);
|
||||
pressure_equation = pressure_equation - valve_pressure_drop;
|
||||
well_state.segPressDropFriction()[seg] = valve_pressure_drop.value();
|
||||
|
||||
resWell_[seg][SPres] = pressure_equation.value();
|
||||
for (int pv_idx = 0; pv_idx < numWellEq; ++pv_idx) {
|
||||
|
@ -279,8 +279,13 @@ namespace Opm
|
||||
top_segment_index_[w] = w;
|
||||
seg_number_[w] = 1; // Top segment is segment #1
|
||||
}
|
||||
segpress_ = bhp();
|
||||
segrates_ = wellRates();
|
||||
seg_press_ = bhp();
|
||||
seg_rates_ = wellRates();
|
||||
|
||||
seg_pressdrop_.assign(nw, 0.);
|
||||
seg_pressdrop_hydorstatic_.assign(nw, 0.);
|
||||
seg_pressdrop_friction_.assign(nw, 0.);
|
||||
seg_pressdrop_acceleration_.assign(nw, 0.);
|
||||
}
|
||||
}
|
||||
|
||||
@ -584,10 +589,10 @@ namespace Opm
|
||||
|
||||
top_segment_index_.clear();
|
||||
top_segment_index_.reserve(nw);
|
||||
segpress_.clear();
|
||||
segpress_.reserve(nw);
|
||||
segrates_.clear();
|
||||
segrates_.reserve(nw * numPhases());
|
||||
seg_press_.clear();
|
||||
seg_press_.reserve(nw);
|
||||
seg_rates_.clear();
|
||||
seg_rates_.reserve(nw * numPhases());
|
||||
seg_number_.clear();
|
||||
|
||||
nseg_ = 0;
|
||||
@ -601,10 +606,10 @@ namespace Opm
|
||||
if ( !well_ecl.isMultiSegment() ) { // not multi-segment well
|
||||
nseg_ += 1;
|
||||
seg_number_.push_back(1); // Assign single segment (top) as number 1.
|
||||
segpress_.push_back(bhp()[w]);
|
||||
seg_press_.push_back(bhp()[w]);
|
||||
const int np = numPhases();
|
||||
for (int p = 0; p < np; ++p) {
|
||||
segrates_.push_back(wellRates()[np * w + p]);
|
||||
seg_rates_.push_back(wellRates()[np * w + p]);
|
||||
}
|
||||
} else { // it is a multi-segment well
|
||||
const WellSegments& segment_set = well_ecl.getSegments();
|
||||
@ -642,7 +647,7 @@ namespace Opm
|
||||
}
|
||||
|
||||
|
||||
// for the segrates_, now it becomes a recursive solution procedure.
|
||||
// for the seg_rates_, now it becomes a recursive solution procedure.
|
||||
{
|
||||
const int np = numPhases();
|
||||
const int start_perf = connpos;
|
||||
@ -668,7 +673,7 @@ namespace Opm
|
||||
perfPhaseRates().begin() + np * start_perf_next_well); // the perforation rates for this well
|
||||
std::vector<double> segment_rates;
|
||||
calculateSegmentRates(segment_inlets, segment_perforations, perforation_rates, np, 0 /* top segment */, segment_rates);
|
||||
std::copy(segment_rates.begin(), segment_rates.end(), std::back_inserter(segrates_));
|
||||
std::copy(segment_rates.begin(), segment_rates.end(), std::back_inserter(seg_rates_));
|
||||
}
|
||||
|
||||
// for the segment pressure, the segment pressure is the same with the first perforation belongs to the segment
|
||||
@ -678,26 +683,32 @@ namespace Opm
|
||||
// improved during the solveWellEq process
|
||||
{
|
||||
// top segment is always the first one, and its pressure is the well bhp
|
||||
segpress_.push_back(bhp()[w]);
|
||||
seg_press_.push_back(bhp()[w]);
|
||||
const int top_segment = top_segment_index_[w];
|
||||
const int start_perf = connpos;
|
||||
for (int seg = 1; seg < well_nseg; ++seg) {
|
||||
if ( !segment_perforations[seg].empty() ) {
|
||||
const int first_perf = segment_perforations[seg][0];
|
||||
segpress_.push_back(perfPress()[start_perf + first_perf]);
|
||||
seg_press_.push_back(perfPress()[start_perf + first_perf]);
|
||||
} else {
|
||||
// segpress_.push_back(bhp); // may not be a good decision
|
||||
// seg_press_.push_back(bhp); // may not be a good decision
|
||||
// using the outlet segment pressure // it needs the ordering is correct
|
||||
const int outlet_seg = segment_set[seg].outletSegment();
|
||||
segpress_.push_back(segpress_[top_segment + segment_set.segmentNumberToIndex(outlet_seg)]);
|
||||
seg_press_.push_back(
|
||||
seg_press_[top_segment + segment_set.segmentNumberToIndex(outlet_seg)]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
connpos += num_perf_this_well;
|
||||
}
|
||||
assert(int(segpress_.size()) == nseg_);
|
||||
assert(int(segrates_.size()) == nseg_ * numPhases() );
|
||||
assert(int(seg_press_.size()) == nseg_);
|
||||
assert(int(seg_rates_.size()) == nseg_ * numPhases() );
|
||||
|
||||
seg_pressdrop_.assign(nseg_, 0.);
|
||||
seg_pressdrop_hydorstatic_.assign(nseg_, 0.);
|
||||
seg_pressdrop_friction_.assign(nseg_, 0.);
|
||||
seg_pressdrop_acceleration_.assign(nseg_, 0.);
|
||||
|
||||
if (prev_well_state && !prev_well_state->wellMap().empty()) {
|
||||
// copying MS well related
|
||||
@ -723,11 +734,11 @@ namespace Opm
|
||||
}
|
||||
|
||||
for (int i = 0; i < number_of_segment * np; ++i) {
|
||||
segrates_[new_top_segmnet_index * np + i] = prev_well_state->segRates()[old_top_segment_index * np + i];
|
||||
seg_rates_[new_top_segmnet_index * np + i] = prev_well_state->segRates()[old_top_segment_index * np + i];
|
||||
}
|
||||
|
||||
for (int i = 0; i < number_of_segment; ++i) {
|
||||
segpress_[new_top_segmnet_index + i] = prev_well_state->segPress()[old_top_segment_index + i];
|
||||
seg_press_[new_top_segmnet_index + i] = prev_well_state->segPress()[old_top_segment_index + i];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -810,22 +821,62 @@ namespace Opm
|
||||
|
||||
const std::vector<double>& segRates() const
|
||||
{
|
||||
return segrates_;
|
||||
return seg_rates_;
|
||||
}
|
||||
|
||||
std::vector<double>& segRates()
|
||||
{
|
||||
return segrates_;
|
||||
return seg_rates_;
|
||||
}
|
||||
|
||||
const std::vector<double>& segPress() const
|
||||
{
|
||||
return segpress_;
|
||||
return seg_press_;
|
||||
}
|
||||
|
||||
std::vector<double>& segPressDrop()
|
||||
{
|
||||
return seg_pressdrop_;
|
||||
}
|
||||
|
||||
const std::vector<double>& segPressDrop() const
|
||||
{
|
||||
return seg_pressdrop_;
|
||||
}
|
||||
|
||||
std::vector<double>& segPressDropFriction()
|
||||
{
|
||||
return seg_pressdrop_friction_;
|
||||
}
|
||||
|
||||
const std::vector<double>& segPressDropFriction() const
|
||||
{
|
||||
return seg_pressdrop_friction_;
|
||||
}
|
||||
|
||||
std::vector<double>& segPressDropHydroStatic()
|
||||
{
|
||||
return seg_pressdrop_hydorstatic_;
|
||||
}
|
||||
|
||||
const std::vector<double>& segPressDropHydroStatic() const
|
||||
{
|
||||
return seg_pressdrop_hydorstatic_;
|
||||
}
|
||||
|
||||
std::vector<double>& segPressDropAcceleration()
|
||||
{
|
||||
return seg_pressdrop_acceleration_;
|
||||
}
|
||||
|
||||
const std::vector<double>& segPressDropAcceleration() const
|
||||
{
|
||||
return seg_pressdrop_acceleration_;
|
||||
}
|
||||
|
||||
std::vector<double>& segPress()
|
||||
{
|
||||
return segpress_;
|
||||
return seg_press_;
|
||||
}
|
||||
|
||||
int numSegment() const
|
||||
@ -1026,8 +1077,17 @@ namespace Opm
|
||||
|
||||
// MS well related
|
||||
// for StandardWell, the number of segments will be one
|
||||
std::vector<double> segrates_;
|
||||
std::vector<double> segpress_;
|
||||
std::vector<double> seg_rates_;
|
||||
std::vector<double> seg_press_;
|
||||
// The following data are only recorded for output
|
||||
// pressure drop
|
||||
std::vector<double> seg_pressdrop_;
|
||||
// frictional pressure drop
|
||||
std::vector<double> seg_pressdrop_friction_;
|
||||
// hydrostatic pressure drop
|
||||
std::vector<double> seg_pressdrop_hydorstatic_;
|
||||
// accelerational pressure drop
|
||||
std::vector<double> seg_pressdrop_acceleration_;
|
||||
// the index of the top segments, which is used to locate the
|
||||
// multisegment well related information in WellState
|
||||
std::vector<int> top_segment_index_;
|
||||
@ -1063,6 +1123,10 @@ namespace Opm
|
||||
&this->segRates()[seg_dof * this->numPhases()];
|
||||
|
||||
seg_res.pressure = this->segPress()[seg_dof];
|
||||
seg_res.pressure_drop = this->segPressDrop()[seg_dof];
|
||||
seg_res.pressure_drop_hydrostatic = this->segPressDropHydroStatic()[seg_dof];
|
||||
seg_res.pressure_drop_friction = this->segPressDropFriction()[seg_dof];
|
||||
seg_res.pressure_drop_acceleration = this->segPressDropAcceleration()[seg_dof];
|
||||
|
||||
if (pu.phase_used[Water]) {
|
||||
seg_res.rates.set(data::Rates::opt::wat,
|
||||
|
Loading…
Reference in New Issue
Block a user