mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
MultisegmentWell: move updatePrimaryVariables to MultisegmentWellPrimaryVariables
This commit is contained in:
parent
e1fccd47dc
commit
5212e9c100
@ -290,91 +290,6 @@ updatePrimaryVariablesNewton(const BVectorWell& dwells,
|
||||
}
|
||||
}
|
||||
|
||||
template<typename FluidSystem, typename Indices, typename Scalar>
|
||||
void
|
||||
MultisegmentWellEval<FluidSystem,Indices,Scalar>::
|
||||
updatePrimaryVariables(const WellState& well_state)
|
||||
{
|
||||
static constexpr int Water = BlackoilPhases::Aqua;
|
||||
static constexpr int Gas = BlackoilPhases::Vapour;
|
||||
|
||||
// TODO: to test using rate conversion coefficients to see if it will be better than
|
||||
// this default one
|
||||
if (!baseif_.isOperableAndSolvable() && !baseif_.wellIsStopped()) return;
|
||||
|
||||
const Well& well = baseif_.wellEcl();
|
||||
|
||||
// the index of the top segment in the WellState
|
||||
const auto& ws = well_state.well(baseif_.indexOfWell());
|
||||
const auto& segments = ws.segments;
|
||||
// maybe a throw for parallel running?
|
||||
assert(int(segments.size()) == this->numberOfSegments());
|
||||
const auto& segment_rates = segments.rates;
|
||||
const auto& segment_pressure = segments.pressure;
|
||||
const PhaseUsage& pu = baseif_.phaseUsage();
|
||||
|
||||
for (int seg = 0; seg < this->numberOfSegments(); ++seg) {
|
||||
// calculate the total rate for each segment
|
||||
double total_seg_rate = 0.0;
|
||||
// the segment pressure
|
||||
primary_variables_.value_[seg][SPres] = segment_pressure[seg];
|
||||
// TODO: under what kind of circustances, the following will be wrong?
|
||||
// the definition of g makes the gas phase is always the last phase
|
||||
for (int p = 0; p < baseif_.numPhases(); p++) {
|
||||
total_seg_rate += baseif_.scalingFactor(p) * segment_rates[baseif_.numPhases() * seg + p];
|
||||
}
|
||||
|
||||
if (seg == 0) {
|
||||
if (baseif_.isInjector()) {
|
||||
total_seg_rate = std::max(total_seg_rate, 0.);
|
||||
} else {
|
||||
total_seg_rate = std::min(total_seg_rate, 0.);
|
||||
}
|
||||
}
|
||||
primary_variables_.value_[seg][WQTotal] = total_seg_rate;
|
||||
if (std::abs(total_seg_rate) > 0.) {
|
||||
if (has_wfrac_variable) {
|
||||
const int water_pos = pu.phase_pos[Water];
|
||||
primary_variables_.value_[seg][WFrac] = baseif_.scalingFactor(water_pos) * segment_rates[baseif_.numPhases() * seg + water_pos] / total_seg_rate;
|
||||
}
|
||||
if (has_gfrac_variable) {
|
||||
const int gas_pos = pu.phase_pos[Gas];
|
||||
primary_variables_.value_[seg][GFrac] = baseif_.scalingFactor(gas_pos) * segment_rates[baseif_.numPhases() * seg + gas_pos] / total_seg_rate;
|
||||
}
|
||||
} else { // total_seg_rate == 0
|
||||
if (baseif_.isInjector()) {
|
||||
// only single phase injection handled
|
||||
auto phase = well.getInjectionProperties().injectorType;
|
||||
|
||||
if (has_wfrac_variable) {
|
||||
if (phase == InjectorType::WATER) {
|
||||
primary_variables_.value_[seg][WFrac] = 1.0;
|
||||
} else {
|
||||
primary_variables_.value_[seg][WFrac] = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
if (has_gfrac_variable) {
|
||||
if (phase == InjectorType::GAS) {
|
||||
primary_variables_.value_[seg][GFrac] = 1.0;
|
||||
} else {
|
||||
primary_variables_.value_[seg][GFrac] = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (baseif_.isProducer()) { // producers
|
||||
if (has_wfrac_variable) {
|
||||
primary_variables_.value_[seg][WFrac] = 1.0 / baseif_.numPhases();
|
||||
}
|
||||
|
||||
if (has_gfrac_variable) {
|
||||
primary_variables_.value_[seg][GFrac] = 1.0 / baseif_.numPhases();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename FluidSystem, typename Indices, typename Scalar>
|
||||
typename MultisegmentWellEval<FluidSystem,Indices,Scalar>::EvalWell
|
||||
MultisegmentWellEval<FluidSystem,Indices,Scalar>::
|
||||
|
@ -134,8 +134,6 @@ protected:
|
||||
// handling the overshooting and undershooting of the fractions
|
||||
void processFractions(const int seg);
|
||||
|
||||
void updatePrimaryVariables(const WellState& well_state);
|
||||
|
||||
void updateUpwindingSegments();
|
||||
|
||||
// updating the well_state based on well solution dwells
|
||||
|
@ -29,6 +29,11 @@
|
||||
#include <opm/models/blackoil/blackoilonephaseindices.hh>
|
||||
#include <opm/models/blackoil/blackoiltwophaseindices.hh>
|
||||
|
||||
#include <opm/simulators/wells/WellInterfaceIndices.hpp>
|
||||
#include <opm/simulators/wells/WellState.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
template<class FluidSystem, class Indices, class Scalar>
|
||||
@ -52,6 +57,91 @@ init()
|
||||
}
|
||||
}
|
||||
|
||||
template<class FluidSystem, class Indices, class Scalar>
|
||||
void MultisegmentWellPrimaryVariables<FluidSystem,Indices,Scalar>::
|
||||
update(const WellState& well_state)
|
||||
{
|
||||
static constexpr int Water = BlackoilPhases::Aqua;
|
||||
static constexpr int Gas = BlackoilPhases::Vapour;
|
||||
|
||||
// TODO: to test using rate conversion coefficients to see if it will be better than
|
||||
// this default one
|
||||
if (!well_.isOperableAndSolvable() && !well_.wellIsStopped())
|
||||
return;
|
||||
|
||||
const Well& well = well_.wellEcl();
|
||||
|
||||
// the index of the top segment in the WellState
|
||||
const auto& ws = well_state.well(well_.indexOfWell());
|
||||
const auto& segments = ws.segments;
|
||||
// maybe a throw for parallel running?
|
||||
assert(segments.size() == value_.size());
|
||||
const auto& segment_rates = segments.rates;
|
||||
const auto& segment_pressure = segments.pressure;
|
||||
const PhaseUsage& pu = well_.phaseUsage();
|
||||
|
||||
for (size_t seg = 0; seg < value_.size(); ++seg) {
|
||||
// calculate the total rate for each segment
|
||||
double total_seg_rate = 0.0;
|
||||
// the segment pressure
|
||||
value_[seg][SPres] = segment_pressure[seg];
|
||||
// TODO: under what kind of circustances, the following will be wrong?
|
||||
// the definition of g makes the gas phase is always the last phase
|
||||
for (int p = 0; p < well_.numPhases(); p++) {
|
||||
total_seg_rate += well_.scalingFactor(p) * segment_rates[well_.numPhases() * seg + p];
|
||||
}
|
||||
|
||||
if (seg == 0) {
|
||||
if (well_.isInjector()) {
|
||||
total_seg_rate = std::max(total_seg_rate, 0.);
|
||||
} else {
|
||||
total_seg_rate = std::min(total_seg_rate, 0.);
|
||||
}
|
||||
}
|
||||
value_[seg][WQTotal] = total_seg_rate;
|
||||
if (std::abs(total_seg_rate) > 0.) {
|
||||
if (has_wfrac_variable) {
|
||||
const int water_pos = pu.phase_pos[Water];
|
||||
value_[seg][WFrac] = well_.scalingFactor(water_pos) * segment_rates[well_.numPhases() * seg + water_pos] / total_seg_rate;
|
||||
}
|
||||
if (has_gfrac_variable) {
|
||||
const int gas_pos = pu.phase_pos[Gas];
|
||||
value_[seg][GFrac] = well_.scalingFactor(gas_pos) * segment_rates[well_.numPhases() * seg + gas_pos] / total_seg_rate;
|
||||
}
|
||||
} else { // total_seg_rate == 0
|
||||
if (well_.isInjector()) {
|
||||
// only single phase injection handled
|
||||
auto phase = well.getInjectionProperties().injectorType;
|
||||
|
||||
if (has_wfrac_variable) {
|
||||
if (phase == InjectorType::WATER) {
|
||||
value_[seg][WFrac] = 1.0;
|
||||
} else {
|
||||
value_[seg][WFrac] = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
if (has_gfrac_variable) {
|
||||
if (phase == InjectorType::GAS) {
|
||||
value_[seg][GFrac] = 1.0;
|
||||
} else {
|
||||
value_[seg][GFrac] = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (well_.isProducer()) { // producers
|
||||
if (has_wfrac_variable) {
|
||||
value_[seg][WFrac] = 1.0 / well_.numPhases();
|
||||
}
|
||||
|
||||
if (has_gfrac_variable) {
|
||||
value_[seg][GFrac] = 1.0 / well_.numPhases();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define INSTANCE(...) \
|
||||
template class MultisegmentWellPrimaryVariables<BlackOilFluidSystem<double,BlackOilDefaultIndexTraits>,__VA_ARGS__,double>;
|
||||
|
||||
|
@ -31,6 +31,7 @@ namespace Opm
|
||||
{
|
||||
|
||||
template<class FluidSystem, class Indices, class Scalar> class WellInterfaceIndices;
|
||||
class WellState;
|
||||
|
||||
template<class FluidSystem, class Indices, class Scalar>
|
||||
class MultisegmentWellPrimaryVariables
|
||||
@ -79,6 +80,9 @@ public:
|
||||
//! \brief Initialize evaluations from values.
|
||||
void init();
|
||||
|
||||
//! \brief Copy values from well state.
|
||||
void update(const WellState& well_state);
|
||||
|
||||
// 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_;
|
||||
|
@ -142,7 +142,7 @@ namespace Opm
|
||||
MultisegmentWell<TypeTag>::
|
||||
updatePrimaryVariables(const WellState& well_state, DeferredLogger& /* deferred_logger */)
|
||||
{
|
||||
this->MSWEval::updatePrimaryVariables(well_state);
|
||||
this->primary_variables_.update(well_state);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user