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>
|
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>::
|
||||||
|
@ -134,8 +134,6 @@ protected:
|
|||||||
// handling the overshooting and undershooting of the fractions
|
// handling the overshooting and undershooting of the fractions
|
||||||
void processFractions(const int seg);
|
void processFractions(const int seg);
|
||||||
|
|
||||||
void updatePrimaryVariables(const WellState& well_state);
|
|
||||||
|
|
||||||
void updateUpwindingSegments();
|
void updateUpwindingSegments();
|
||||||
|
|
||||||
// updating the well_state based on well solution dwells
|
// updating the well_state based on well solution dwells
|
||||||
|
@ -29,6 +29,11 @@
|
|||||||
#include <opm/models/blackoil/blackoilonephaseindices.hh>
|
#include <opm/models/blackoil/blackoilonephaseindices.hh>
|
||||||
#include <opm/models/blackoil/blackoiltwophaseindices.hh>
|
#include <opm/models/blackoil/blackoiltwophaseindices.hh>
|
||||||
|
|
||||||
|
#include <opm/simulators/wells/WellInterfaceIndices.hpp>
|
||||||
|
#include <opm/simulators/wells/WellState.hpp>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
namespace Opm {
|
namespace Opm {
|
||||||
|
|
||||||
template<class FluidSystem, class Indices, class Scalar>
|
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(...) \
|
#define INSTANCE(...) \
|
||||||
template class MultisegmentWellPrimaryVariables<BlackOilFluidSystem<double,BlackOilDefaultIndexTraits>,__VA_ARGS__,double>;
|
template class MultisegmentWellPrimaryVariables<BlackOilFluidSystem<double,BlackOilDefaultIndexTraits>,__VA_ARGS__,double>;
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@ namespace Opm
|
|||||||
{
|
{
|
||||||
|
|
||||||
template<class FluidSystem, class Indices, class Scalar> class WellInterfaceIndices;
|
template<class FluidSystem, class Indices, class Scalar> class WellInterfaceIndices;
|
||||||
|
class WellState;
|
||||||
|
|
||||||
template<class FluidSystem, class Indices, class Scalar>
|
template<class FluidSystem, class Indices, class Scalar>
|
||||||
class MultisegmentWellPrimaryVariables
|
class MultisegmentWellPrimaryVariables
|
||||||
@ -79,6 +80,9 @@ public:
|
|||||||
//! \brief Initialize evaluations from values.
|
//! \brief Initialize evaluations from values.
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
|
//! \brief Copy values from well state.
|
||||||
|
void update(const WellState& well_state);
|
||||||
|
|
||||||
// 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_;
|
||||||
|
@ -142,7 +142,7 @@ namespace Opm
|
|||||||
MultisegmentWell<TypeTag>::
|
MultisegmentWell<TypeTag>::
|
||||||
updatePrimaryVariables(const WellState& well_state, DeferredLogger& /* deferred_logger */)
|
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