mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
MultisegmentWell: move updatePrimaryVariablesNewton to MultisegmentWellPrimaryVariables
This commit is contained in:
@@ -171,55 +171,6 @@ getWellConvergence(const WellState& well_state,
|
|||||||
return report;
|
return report;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename FluidSystem, typename Indices, typename Scalar>
|
|
||||||
void
|
|
||||||
MultisegmentWellEval<FluidSystem,Indices,Scalar>::
|
|
||||||
updatePrimaryVariablesNewton(const BVectorWell& dwells,
|
|
||||||
const double relaxation_factor,
|
|
||||||
const double dFLimit,
|
|
||||||
const double max_pressure_change)
|
|
||||||
{
|
|
||||||
const std::vector<std::array<double, numWellEq> > old_primary_variables = primary_variables_.value_;
|
|
||||||
|
|
||||||
for (int seg = 0; seg < this->numberOfSegments(); ++seg) {
|
|
||||||
if (has_wfrac_variable) {
|
|
||||||
const int sign = dwells[seg][WFrac] > 0. ? 1 : -1;
|
|
||||||
const double dx_limited = sign * std::min(std::abs(dwells[seg][WFrac]) * relaxation_factor, dFLimit);
|
|
||||||
primary_variables_.value_[seg][WFrac] = old_primary_variables[seg][WFrac] - dx_limited;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (has_gfrac_variable) {
|
|
||||||
const int sign = dwells[seg][GFrac] > 0. ? 1 : -1;
|
|
||||||
const double dx_limited = sign * std::min(std::abs(dwells[seg][GFrac]) * relaxation_factor, dFLimit);
|
|
||||||
primary_variables_.value_[seg][GFrac] = old_primary_variables[seg][GFrac] - dx_limited;
|
|
||||||
}
|
|
||||||
|
|
||||||
// handling the overshooting or undershooting of the fractions
|
|
||||||
primary_variables_.processFractions(seg);
|
|
||||||
|
|
||||||
// update the segment pressure
|
|
||||||
{
|
|
||||||
const int sign = dwells[seg][SPres] > 0.? 1 : -1;
|
|
||||||
const double dx_limited = sign * std::min(std::abs(dwells[seg][SPres]) * relaxation_factor, max_pressure_change);
|
|
||||||
primary_variables_.value_[seg][SPres] = std::max( old_primary_variables[seg][SPres] - dx_limited, 1e5);
|
|
||||||
}
|
|
||||||
|
|
||||||
// update the total rate // TODO: should we have a limitation of the total rate change?
|
|
||||||
{
|
|
||||||
primary_variables_.value_[seg][WQTotal] = old_primary_variables[seg][WQTotal] - relaxation_factor * dwells[seg][WQTotal];
|
|
||||||
|
|
||||||
// make sure that no injector produce and no producer inject
|
|
||||||
if (seg == 0) {
|
|
||||||
if (baseif_.isInjector()) {
|
|
||||||
primary_variables_.value_[seg][WQTotal] = std::max( primary_variables_.value_[seg][WQTotal], 0.0);
|
|
||||||
} else {
|
|
||||||
primary_variables_.value_[seg][WQTotal] = std::min( primary_variables_.value_[seg][WQTotal], 0.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename FluidSystem, typename Indices, typename Scalar>
|
template<typename FluidSystem, typename Indices, typename Scalar>
|
||||||
typename MultisegmentWellEval<FluidSystem,Indices,Scalar>::EvalWell
|
typename MultisegmentWellEval<FluidSystem,Indices,Scalar>::EvalWell
|
||||||
MultisegmentWellEval<FluidSystem,Indices,Scalar>::
|
MultisegmentWellEval<FluidSystem,Indices,Scalar>::
|
||||||
|
|||||||
@@ -133,12 +133,6 @@ protected:
|
|||||||
|
|
||||||
void updateUpwindingSegments();
|
void updateUpwindingSegments();
|
||||||
|
|
||||||
// updating the well_state based on well solution dwells
|
|
||||||
void updatePrimaryVariablesNewton(const BVectorWell& dwells,
|
|
||||||
const double relaxation_factor,
|
|
||||||
const double DFLimit,
|
|
||||||
const double max_pressure_change);
|
|
||||||
|
|
||||||
void computeSegmentFluidProperties(const EvalWell& temperature,
|
void computeSegmentFluidProperties(const EvalWell& temperature,
|
||||||
const EvalWell& saltConcentration,
|
const EvalWell& saltConcentration,
|
||||||
int pvt_region_index,
|
int pvt_region_index,
|
||||||
|
|||||||
@@ -142,6 +142,54 @@ update(const WellState& well_state)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class FluidSystem, class Indices, class Scalar>
|
||||||
|
void MultisegmentWellPrimaryVariables<FluidSystem,Indices,Scalar>::
|
||||||
|
updateNewton(const BVectorWell& dwells,
|
||||||
|
const double relaxation_factor,
|
||||||
|
const double dFLimit,
|
||||||
|
const double max_pressure_change)
|
||||||
|
{
|
||||||
|
const std::vector<std::array<double, numWellEq>> old_primary_variables = value_;
|
||||||
|
|
||||||
|
for (size_t seg = 0; seg < value_.size(); ++seg) {
|
||||||
|
if (has_wfrac_variable) {
|
||||||
|
const int sign = dwells[seg][WFrac] > 0. ? 1 : -1;
|
||||||
|
const double dx_limited = sign * std::min(std::abs(dwells[seg][WFrac]) * relaxation_factor, dFLimit);
|
||||||
|
value_[seg][WFrac] = old_primary_variables[seg][WFrac] - dx_limited;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_gfrac_variable) {
|
||||||
|
const int sign = dwells[seg][GFrac] > 0. ? 1 : -1;
|
||||||
|
const double dx_limited = sign * std::min(std::abs(dwells[seg][GFrac]) * relaxation_factor, dFLimit);
|
||||||
|
value_[seg][GFrac] = old_primary_variables[seg][GFrac] - dx_limited;
|
||||||
|
}
|
||||||
|
|
||||||
|
// handling the overshooting or undershooting of the fractions
|
||||||
|
this->processFractions(seg);
|
||||||
|
|
||||||
|
// update the segment pressure
|
||||||
|
{
|
||||||
|
const int sign = dwells[seg][SPres] > 0.? 1 : -1;
|
||||||
|
const double dx_limited = sign * std::min(std::abs(dwells[seg][SPres]) * relaxation_factor, max_pressure_change);
|
||||||
|
value_[seg][SPres] = std::max(old_primary_variables[seg][SPres] - dx_limited, 1e5);
|
||||||
|
}
|
||||||
|
|
||||||
|
// update the total rate // TODO: should we have a limitation of the total rate change?
|
||||||
|
{
|
||||||
|
value_[seg][WQTotal] = old_primary_variables[seg][WQTotal] - relaxation_factor * dwells[seg][WQTotal];
|
||||||
|
|
||||||
|
// make sure that no injector produce and no producer inject
|
||||||
|
if (seg == 0) {
|
||||||
|
if (well_.isInjector()) {
|
||||||
|
value_[seg][WQTotal] = std::max(value_[seg][WQTotal], 0.0);
|
||||||
|
} else {
|
||||||
|
value_[seg][WQTotal] = std::min(value_[seg][WQTotal], 0.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template<class FluidSystem, class Indices, class Scalar>
|
template<class FluidSystem, class Indices, class Scalar>
|
||||||
void MultisegmentWellPrimaryVariables<FluidSystem,Indices,Scalar>::
|
void MultisegmentWellPrimaryVariables<FluidSystem,Indices,Scalar>::
|
||||||
processFractions(const int seg)
|
processFractions(const int seg)
|
||||||
|
|||||||
@@ -24,6 +24,8 @@
|
|||||||
|
|
||||||
#include <opm/material/densead/Evaluation.hpp>
|
#include <opm/material/densead/Evaluation.hpp>
|
||||||
|
|
||||||
|
#include <opm/simulators/wells/MultisegmentWellEquations.hpp>
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -70,6 +72,9 @@ public:
|
|||||||
|
|
||||||
using EvalWell = DenseAd::Evaluation<double, /*size=*/Indices::numEq + numWellEq>;
|
using EvalWell = DenseAd::Evaluation<double, /*size=*/Indices::numEq + numWellEq>;
|
||||||
|
|
||||||
|
using Equations = MultisegmentWellEquations<Scalar,numWellEq,Indices::numEq>;
|
||||||
|
using BVectorWell = typename Equations::BVectorWell;
|
||||||
|
|
||||||
MultisegmentWellPrimaryVariables(const WellInterfaceIndices<FluidSystem,Indices,Scalar>& well)
|
MultisegmentWellPrimaryVariables(const WellInterfaceIndices<FluidSystem,Indices,Scalar>& well)
|
||||||
: well_(well)
|
: well_(well)
|
||||||
{}
|
{}
|
||||||
@@ -83,6 +88,12 @@ public:
|
|||||||
//! \brief Copy values from well state.
|
//! \brief Copy values from well state.
|
||||||
void update(const WellState& well_state);
|
void update(const WellState& well_state);
|
||||||
|
|
||||||
|
//! \brief Update values from newton update vector.
|
||||||
|
void updateNewton(const BVectorWell& dwells,
|
||||||
|
const double relaxation_factor,
|
||||||
|
const double DFLimit,
|
||||||
|
const double max_pressure_change);
|
||||||
|
|
||||||
// the values for the primary varibles
|
// the values for the primary varibles
|
||||||
// based on different solutioin strategies, the wells can have different primary variables
|
// based on different solutioin strategies, the wells can have different primary variables
|
||||||
std::vector<std::array<double, numWellEq> > value_;
|
std::vector<std::array<double, numWellEq> > value_;
|
||||||
@@ -90,10 +101,10 @@ public:
|
|||||||
// the Evaluation for the well primary variables, which contain derivativles and are used in AD calculation
|
// the Evaluation for the well primary variables, which contain derivativles and are used in AD calculation
|
||||||
std::vector<std::array<EvalWell, numWellEq> > evaluation_;
|
std::vector<std::array<EvalWell, numWellEq> > evaluation_;
|
||||||
|
|
||||||
|
private:
|
||||||
//! \brief Handle non-reasonable fractions due to numerical overshoot.
|
//! \brief Handle non-reasonable fractions due to numerical overshoot.
|
||||||
void processFractions(const int seg);
|
void processFractions(const int seg);
|
||||||
|
|
||||||
private:
|
|
||||||
const WellInterfaceIndices<FluidSystem,Indices,Scalar>& well_; //!< Reference to well interface
|
const WellInterfaceIndices<FluidSystem,Indices,Scalar>& well_; //!< Reference to well interface
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -616,7 +616,7 @@ namespace Opm
|
|||||||
|
|
||||||
const double dFLimit = this->param_.dwell_fraction_max_;
|
const double dFLimit = this->param_.dwell_fraction_max_;
|
||||||
const double max_pressure_change = this->param_.max_pressure_change_ms_wells_;
|
const double max_pressure_change = this->param_.max_pressure_change_ms_wells_;
|
||||||
this->MSWEval::updatePrimaryVariablesNewton(dwells,
|
this->primary_variables_.updateNewton(dwells,
|
||||||
relaxation_factor,
|
relaxation_factor,
|
||||||
dFLimit,
|
dFLimit,
|
||||||
max_pressure_change);
|
max_pressure_change);
|
||||||
|
|||||||
Reference in New Issue
Block a user