MultisegmentWell: move getSegmentRateUpwinding to MultisegmentWellPrimaryVariables

This commit is contained in:
Arne Morten Kvarving 2022-12-19 09:52:48 +01:00
parent 8e9b004cfc
commit f99ecd15ac
5 changed files with 60 additions and 48 deletions

View File

@ -171,47 +171,6 @@ getWellConvergence(const WellState& well_state,
return report;
}
template<typename FluidSystem, typename Indices, typename Scalar>
typename MultisegmentWellEval<FluidSystem,Indices,Scalar>::EvalWell
MultisegmentWellEval<FluidSystem,Indices,Scalar>::
getSegmentRateUpwinding(const int seg,
const size_t comp_idx) const
{
const int seg_upwind = upwinding_segments_[seg];
// the result will contain the derivative with respect to WQTotal in segment seg,
// and the derivatives with respect to WFrac GFrac in segment seg_upwind.
// the derivative with respect to SPres should be zero.
if (seg == 0 && baseif_.isInjector()) {
const Well& well = baseif_.wellEcl();
auto phase = well.getInjectionProperties().injectorType;
if (FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx)
&& Indices::canonicalToActiveComponentIndex(FluidSystem::waterCompIdx) == comp_idx
&& phase == InjectorType::WATER)
return primary_variables_.evaluation_[seg][WQTotal] / baseif_.scalingFactor(baseif_.ebosCompIdxToFlowCompIdx(comp_idx));
if (FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx)
&& Indices::canonicalToActiveComponentIndex(FluidSystem::oilCompIdx) == comp_idx
&& phase == InjectorType::OIL)
return primary_variables_.evaluation_[seg][WQTotal] / baseif_.scalingFactor(baseif_.ebosCompIdxToFlowCompIdx(comp_idx));
if (FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx)
&& Indices::canonicalToActiveComponentIndex(FluidSystem::gasCompIdx) == comp_idx
&& phase == InjectorType::GAS)
return primary_variables_.evaluation_[seg][WQTotal] / baseif_.scalingFactor(baseif_.ebosCompIdxToFlowCompIdx(comp_idx));
return 0.0;
}
const EvalWell segment_rate = primary_variables_.evaluation_[seg][WQTotal] *
primary_variables_.volumeFractionScaled(seg_upwind, comp_idx);
assert(segment_rate.derivative(SPres + Indices::numEq) == 0.);
return segment_rate;
}
template<typename FluidSystem, typename Indices, typename Scalar>
typename MultisegmentWellEval<FluidSystem,Indices,Scalar>::EvalWell
MultisegmentWellEval<FluidSystem,Indices,Scalar>::
@ -392,7 +351,10 @@ computeSegmentFluidProperties(const EvalWell& temperature,
// calculate the mass rates
segment_mass_rates_[seg] = 0.;
for (int comp_idx = 0; comp_idx < baseif_.numComponents(); ++comp_idx) {
const EvalWell rate = getSegmentRateUpwinding(seg, comp_idx);
const int upwind_seg = upwinding_segments_[seg];
const EvalWell rate = primary_variables_.getSegmentRateUpwinding(seg,
upwind_seg,
comp_idx);
this->segment_mass_rates_[seg] += rate * surf_dens[comp_idx];
}
}

View File

@ -145,8 +145,6 @@ protected:
EvalWell getSegmentWQTotal(const int seg) const;
EvalWell getSegmentPressure(const int seg) const;
EvalWell getSegmentRate(const int seg, const int comp_idx) const;
EvalWell getSegmentRateUpwinding(const int seg,
const size_t comp_idx) const;
EvalWell getSegmentSurfaceVolume(const EvalWell& temperature,
const EvalWell& saltConcentration,
const int pvt_region_index,

View File

@ -321,6 +321,46 @@ surfaceVolumeFraction(const int seg,
return this->volumeFractionScaled(seg, comp_idx) / sum_volume_fraction_scaled;
}
template<class FluidSystem, class Indices, class Scalar>
typename MultisegmentWellPrimaryVariables<FluidSystem,Indices,Scalar>::EvalWell
MultisegmentWellPrimaryVariables<FluidSystem,Indices,Scalar>::
getSegmentRateUpwinding(const int seg,
const int seg_upwind,
const size_t comp_idx) const
{
// the result will contain the derivative with respect to WQTotal in segment seg,
// and the derivatives with respect to WFrac GFrac in segment seg_upwind.
// the derivative with respect to SPres should be zero.
if (seg == 0 && well_.isInjector()) {
const Well& well = well_.wellEcl();
auto phase = well.getInjectionProperties().injectorType;
if (FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx)
&& Indices::canonicalToActiveComponentIndex(FluidSystem::waterCompIdx) == comp_idx
&& phase == InjectorType::WATER)
return evaluation_[seg][WQTotal] / well_.scalingFactor(well_.ebosCompIdxToFlowCompIdx(comp_idx));
if (FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx)
&& Indices::canonicalToActiveComponentIndex(FluidSystem::oilCompIdx) == comp_idx
&& phase == InjectorType::OIL)
return evaluation_[seg][WQTotal] / well_.scalingFactor(well_.ebosCompIdxToFlowCompIdx(comp_idx));
if (FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx)
&& Indices::canonicalToActiveComponentIndex(FluidSystem::gasCompIdx) == comp_idx
&& phase == InjectorType::GAS)
return evaluation_[seg][WQTotal] / well_.scalingFactor(well_.ebosCompIdxToFlowCompIdx(comp_idx));
return 0.0;
}
const EvalWell segment_rate = evaluation_[seg][WQTotal] *
this->volumeFractionScaled(seg_upwind, comp_idx);
assert(segment_rate.derivative(SPres + Indices::numEq) == 0.);
return segment_rate;
}
#define INSTANCE(...) \
template class MultisegmentWellPrimaryVariables<BlackOilFluidSystem<double,BlackOilDefaultIndexTraits>,__VA_ARGS__,double>;

View File

@ -104,6 +104,11 @@ public:
EvalWell surfaceVolumeFraction(const int seg,
const int compIdx) const;
//! \brief Returns upwinding rate for a component in a segment.
EvalWell getSegmentRateUpwinding(const int seg,
const int seg_upwind,
const size_t comp_idx) const;
// the values for the primary varibles
// based on different solutioin strategies, the wells can have different primary variables
std::vector<std::array<double, numWellEq> > value_;

View File

@ -1573,7 +1573,10 @@ namespace Opm
{
const int seg_upwind = this->upwinding_segments_[seg];
for (int comp_idx = 0; comp_idx < this->num_components_; ++comp_idx) {
const EvalWell segment_rate = this->getSegmentRateUpwinding(seg, comp_idx) *
const EvalWell segment_rate =
this->primary_variables_.getSegmentRateUpwinding(seg,
seg_upwind,
comp_idx) *
this->well_efficiency_factor_;
MultisegmentWellAssemble<FluidSystem,Indices,Scalar>(*this).
assembleOutflowTerm(seg, seg_upwind, comp_idx, segment_rate, this->linSys_);
@ -1583,9 +1586,13 @@ namespace Opm
// considering the contributions from the inlet segments
{
for (const int inlet : this->segment_inlets_[seg]) {
for (int comp_idx = 0; comp_idx < this->num_components_; ++comp_idx) {
const EvalWell inlet_rate = this->getSegmentRateUpwinding(inlet, comp_idx) * this->well_efficiency_factor_;
const int inlet_upwind = this->upwinding_segments_[inlet];
for (int comp_idx = 0; comp_idx < this->num_components_; ++comp_idx) {
const EvalWell inlet_rate =
this->primary_variables_.getSegmentRateUpwinding(inlet,
inlet_upwind,
comp_idx) *
this->well_efficiency_factor_;
MultisegmentWellAssemble<FluidSystem,Indices,Scalar>(*this).
assembleInflowTerm(seg, inlet, inlet_upwind, comp_idx, inlet_rate, this->linSys_);
}