WellInterfaceGeneric: template Scalar type

This commit is contained in:
Arne Morten Kvarving 2024-02-19 14:34:38 +01:00
parent 226410cd44
commit 11b5ba3f18
29 changed files with 332 additions and 291 deletions

View File

@ -1334,14 +1334,14 @@ calculateEfficiencyFactors(const int reportStepIdx)
}
template<class Scalar>
WellInterfaceGeneric*
WellInterfaceGeneric<Scalar>*
BlackoilWellModelGeneric<Scalar>::
getGenWell(const std::string& well_name)
{
// finding the iterator of the well in wells_ecl
auto well = std::find_if(well_container_generic_.begin(),
well_container_generic_.end(),
[&well_name](const WellInterfaceGeneric* elem)->bool {
[&well_name](const WellInterfaceGeneric<Scalar>* elem)->bool {
return elem->name() == well_name;
});

View File

@ -64,7 +64,7 @@ namespace Opm {
struct SimulatorUpdate;
class SummaryConfig;
class VFPProperties;
class WellInterfaceGeneric;
template<class Scalar> class WellInterfaceGeneric;
template<class Scalar> class WellState;
} // namespace Opm
@ -84,7 +84,7 @@ class BlackoilWellModelGeneric
public:
// --------- Types ---------
using GLiftOptWells = std::map<std::string, std::unique_ptr<GasLiftSingleWellGeneric<Scalar>>>;
using GLiftProdWells = std::map<std::string, const WellInterfaceGeneric*>;
using GLiftProdWells = std::map<std::string, const WellInterfaceGeneric<Scalar>*>;
using GLiftWellStateMap = std::map<std::string, std::unique_ptr<GasLiftWellState<Scalar>>>;
BlackoilWellModelGeneric(Schedule& schedule,
@ -115,7 +115,7 @@ public:
const Schedule& schedule() const { return schedule_; }
const PhaseUsage& phaseUsage() const { return phase_usage_; }
const GroupState<Scalar>& groupState() const { return this->active_wgstate_.group_state; }
std::vector<const WellInterfaceGeneric*> genericWells() const
std::vector<const WellInterfaceGeneric<Scalar>*> genericWells() const
{ return {well_container_generic_.begin(), well_container_generic_.end()}; }
/*
@ -542,7 +542,7 @@ protected:
std::function<bool(const Well&)> not_on_process_{};
// a vector of all the wells.
std::vector<WellInterfaceGeneric*> well_container_generic_{};
std::vector<WellInterfaceGeneric<Scalar>*> well_container_generic_{};
std::vector<int> local_shut_wells_{};
@ -589,7 +589,7 @@ protected:
std::map<std::string, std::pair<std::string, std::string>> closed_offending_wells_;
private:
WellInterfaceGeneric* getGenWell(const std::string& well_name);
WellInterfaceGeneric<Scalar>* getGenWell(const std::string& well_name);
};

View File

@ -582,7 +582,7 @@ guideRateUpdateIsNeeded(const int reportStepIdx) const
const auto& genWells = wellModel_.genericWells();
auto need_update =
std::any_of(genWells.begin(), genWells.end(),
[](const WellInterfaceGeneric* well)
[](const WellInterfaceGeneric<Scalar>* well)
{
return well->changedToOpenThisStep();
});
@ -594,7 +594,7 @@ guideRateUpdateIsNeeded(const int reportStepIdx) const
+ ScheduleEvents::NEW_WELL;
need_update = std::any_of(genWells.begin(), genWells.end(),
[&events](const WellInterfaceGeneric* well)
[&events](const WellInterfaceGeneric<Scalar>* well)
{
return events.hasEvent(well->name(), effective_events_mask);
});

View File

@ -51,7 +51,7 @@ public:
const Parallel::Communication& comm,
bool glift_debug);
const WellInterfaceGeneric& getWell() const override { return well_; }
const WellInterfaceGeneric<Scalar>& getWell() const override { return well_; }
private:
std::optional<Scalar>

View File

@ -40,7 +40,7 @@ class GasLiftWell;
template<class Scalar> class GasLiftWellState;
class Schedule;
class SummaryState;
class WellInterfaceGeneric;
template<class Scalar> class WellInterfaceGeneric;
template<class Scalar> class WellState;
template<class Scalar> class GroupState;
@ -107,7 +107,7 @@ public:
std::unique_ptr<GasLiftWellState<Scalar>> runOptimize(const int iteration_idx);
virtual const WellInterfaceGeneric& getWell() const = 0;
virtual const WellInterfaceGeneric<Scalar>& getWell() const = 0;
protected:
GasLiftSingleWellGeneric(DeferredLogger& deferred_logger,

View File

@ -238,7 +238,7 @@ checkThpControl_() const
const Well::ProducerCMode& control_mode =
this->well_state_.well(well_index).production_cmode;
bool thp_control = control_mode == Well::ProducerCMode::THP;
const WellInterfaceGeneric &well = getWell();
const auto& well = getWell();
thp_control = thp_control || well.thpLimitViolatedButNotSwitched();
if (this->debug) {
if (!thp_control) {

View File

@ -1118,7 +1118,7 @@ computeDelta(const std::string& well_name)
const GradInfo& gi = this->parent.dec_grads_.at(well_name);
GasLiftWellState<Scalar>& state = *(this->parent.well_state_map_.at(well_name).get());
GasLiftSingleWell& gs_well = *(this->parent.stage1_wells_.at(well_name).get());
const WellInterfaceGeneric& well = gs_well.getWell();
const WellInterfaceGeneric<Scalar>& well = gs_well.getWell();
// only get deltas for wells owned by this rank
if (this->parent.well_state_.wellIsOwned(well.indexOfWell(), well_name)) {
const auto& well_ecl = well.wellEcl();

View File

@ -38,7 +38,7 @@ template<class Scalar> class GasLiftWellState;
class Group;
template<class Scalar> class GroupState;
class Schedule;
class WellInterfaceGeneric;
template<class Scalar> class WellInterfaceGeneric;
template<class Scalar> class WellState;
template<class Scalar>
@ -46,7 +46,7 @@ class GasLiftStage2 : public GasLiftCommon<Scalar>
{
using GasLiftSingleWell = GasLiftSingleWellGeneric<Scalar>;
using GLiftOptWells = std::map<std::string,std::unique_ptr<GasLiftSingleWell>>;
using GLiftProdWells = std::map<std::string,const WellInterfaceGeneric*>;
using GLiftProdWells = std::map<std::string,const WellInterfaceGeneric<Scalar>*>;
using GLiftWellStateMap = std::map<std::string,std::unique_ptr<GasLiftWellState<Scalar>>>;
using GradPair = std::pair<std::string, Scalar>;
using GradPairItr = typename std::vector<GradPair>::iterator;

View File

@ -311,7 +311,7 @@ extractCPRPressureMatrix(PressureMatrix& jacobian,
const BVector& weights,
const int pressureVarIndex,
const bool /*use_well_weights*/,
const WellInterfaceGeneric& well,
const WellInterfaceGeneric<Scalar>& well,
const int seg_pressure_var_ind,
const WellState<Scalar>& well_state) const
{
@ -395,7 +395,7 @@ template void MultisegmentWellEquations<double,numWellEq,numEq>:: \
const MultisegmentWellEquations<double,numWellEq,numEq>::BVector&, \
const int, \
const bool, \
const WellInterfaceGeneric&, \
const WellInterfaceGeneric<double>&, \
const int, \
const WellState<double>&) const;

View File

@ -41,7 +41,7 @@ template<class Scalar> class MultisegmentWellGeneric;
#if COMPILE_BDA_BRIDGE
class WellContributions;
#endif
class WellInterfaceGeneric;
template<class Scalar> class WellInterfaceGeneric;
template<class Scalar> class WellState;
template<class Scalar, int numWellEq, int numEq>
@ -118,7 +118,7 @@ public:
const BVector& weights,
const int pressureVarIndex,
const bool /*use_well_weights*/,
const WellInterfaceGeneric& well,
const WellInterfaceGeneric<Scalar>& well,
const int seg_pressure_var_ind,
const WellState<Scalar>& well_state) const;

View File

@ -34,18 +34,15 @@
#include <opm/simulators/wells/WellInterfaceGeneric.hpp>
#include <opm/simulators/wells/WellState.hpp>
#include <cassert>
#include <cmath>
#include <stdexcept>
#include <fmt/format.h>
namespace Opm
{
namespace Opm {
template<typename Scalar>
MultisegmentWellGeneric<Scalar>::
MultisegmentWellGeneric(WellInterfaceGeneric& baseif)
MultisegmentWellGeneric(WellInterfaceGeneric<Scalar>& baseif)
: baseif_(baseif)
{
}

View File

@ -32,7 +32,7 @@ namespace Opm
class DeferredLogger;
class SummaryState;
class WellInterfaceGeneric;
template<class Scalar> class WellInterfaceGeneric;
enum class WellSegmentCompPressureDrop;
class WellSegments;
template<class Scalar> class WellState;
@ -52,7 +52,7 @@ public:
int numberOfSegments() const;
protected:
MultisegmentWellGeneric(WellInterfaceGeneric& baseif);
MultisegmentWellGeneric(WellInterfaceGeneric<Scalar>& baseif);
// scale the segment rates and pressure based on well rates and bhp
void scaleSegmentRatesWithWellRates(const std::vector<std::vector<int>>& segment_inlets,
@ -75,7 +75,7 @@ protected:
const double density,
const std::vector<double>& seg_dp) const;
const WellInterfaceGeneric& baseif_;
const WellInterfaceGeneric<Scalar>& baseif_;
};
}

View File

@ -45,7 +45,6 @@
#include <fmt/format.h>
#include <algorithm>
#include <array>
#include <cmath>
#include <cstddef>
@ -61,7 +60,7 @@ namespace Opm
template<class FluidSystem, class Indices>
MultisegmentWellSegments<FluidSystem,Indices>::
MultisegmentWellSegments(const int numSegments,
WellInterfaceGeneric& well)
WellInterfaceGeneric<Scalar>& well)
: perforations_(numSegments)
, perforation_depth_diffs_(well.numPerfs(), 0.0)
, inlets_(well.wellEcl().getSegments().size())

View File

@ -33,7 +33,7 @@ namespace Opm {
struct PhaseUsage;
template<class Scalar> class SegmentState;
class UnitSystem;
class WellInterfaceGeneric;
template<class Scalar> class WellInterfaceGeneric;
class SummaryState;
} // namespace Opm
@ -49,7 +49,7 @@ class MultisegmentWellSegments
public:
MultisegmentWellSegments(const int numSegments,
WellInterfaceGeneric& well);
WellInterfaceGeneric<Scalar>& well);
void computeFluidProperties(const EvalWell& temperature,
const EvalWell& saltConcentration,
@ -172,7 +172,7 @@ private:
std::vector<std::vector<EvalWell>> phase_fractions_;
std::vector<std::vector<EvalWell>> phase_viscosities_;
WellInterfaceGeneric& well_;
WellInterfaceGeneric<Scalar>& well_;
void copyPhaseDensities(const unsigned phaseIdx,
const std::size_t stride,

View File

@ -287,7 +287,7 @@ namespace Opm
DeferredLogger& deferred_logger)
{
const auto [compute_potential, bhp_controlled_well] =
this->WellInterfaceGeneric::computeWellPotentials(well_potentials, well_state);
this->WellInterfaceGeneric<Scalar>::computeWellPotentials(well_potentials, well_state);
if (!compute_potential) {
return;

View File

@ -291,7 +291,7 @@ extractCPRPressureMatrix(PressureMatrix& jacobian,
const BVector& weights,
const int pressureVarIndex,
const bool use_well_weights,
const WellInterfaceGeneric& well,
const WellInterfaceGeneric<Scalar>& well,
const int bhp_var_index,
const WellState<Scalar>& well_state) const
{
@ -413,7 +413,7 @@ template void StandardWellEquations<double,N>:: \
const typename StandardWellEquations<double,N>::BVector&, \
const int, \
const bool, \
const WellInterfaceGeneric&, \
const WellInterfaceGeneric<double>&, \
const int, \
const WellState<double>&) const;

View File

@ -39,7 +39,7 @@ template<class Scalar, int numEq> class StandardWellEquationAccess;
#if COMPILE_BDA_BRIDGE
class WellContributions;
#endif
class WellInterfaceGeneric;
template<class Scalar> class WellInterfaceGeneric;
template<class Scalar> class WellState;
template<class Scalar, int numEq>
@ -115,7 +115,7 @@ public:
const BVector& weights,
const int pressureVarIndex,
const bool use_well_weights,
const WellInterfaceGeneric& well,
const WellInterfaceGeneric<Scalar>& well,
const int bhp_var_index,
const WellState<Scalar>& well_state) const;

View File

@ -1706,7 +1706,7 @@ namespace Opm
DeferredLogger& deferred_logger) // const
{
const auto [compute_potential, bhp_controlled_well] =
this->WellInterfaceGeneric::computeWellPotentials(well_potentials, well_state);
this->WellInterfaceGeneric<Scalar>::computeWellPotentials(well_potentials, well_state);
if (!compute_potential) {
return;

View File

@ -35,14 +35,14 @@ namespace Opm
class DeferredLogger;
class SummaryState;
class Well;
class WellInterfaceGeneric;
template<class Scalar> class WellInterfaceGeneric;
template<class Scalar> class WellState;
//! \brief Class for computing BHP limits.
class WellBhpThpCalculator {
public:
//! \brief Constructor sets reference to well.
WellBhpThpCalculator(const WellInterfaceGeneric& well) : well_(well) {}
WellBhpThpCalculator(const WellInterfaceGeneric<double>& well) : well_(well) {}
//! \brief Checks if well has THP constraints.
bool wellHasTHPConstraints(const SummaryState& summaryState) const;
@ -168,7 +168,7 @@ private:
const double dp,
DeferredLogger& deferred_logger) const;
const WellInterfaceGeneric& well_; //!< Reference to well interface
const WellInterfaceGeneric<double>& well_; //!< Reference to well interface
};
}

View File

@ -39,7 +39,7 @@ using RegionId = int;
class Rates;
template<class Scalar> class SingleWellState;
class SummaryState;
class WellInterfaceGeneric;
template<class Scalar> class WellInterfaceGeneric;
enum class WellInjectorCMode;
enum class WellProducerCMode;
@ -47,7 +47,7 @@ enum class WellProducerCMode;
class WellConstraints {
public:
//! \brief Constructor sets reference to well.
WellConstraints(const WellInterfaceGeneric& well) : well_(well) {}
WellConstraints(const WellInterfaceGeneric<double>& well) : well_(well) {}
using RateConvFunc = std::function<void(const RegionId, const int,
const std::vector<double>&,
@ -78,7 +78,7 @@ private:
DeferredLogger& deferred_logger,
const std::optional<Well::ProductionControls>& prod_controls = std::nullopt) const;
const WellInterfaceGeneric& well_; //!< Reference to well interface
const WellInterfaceGeneric<double>& well_; //!< Reference to well interface
};
}

View File

@ -30,13 +30,13 @@ namespace Opm
class ConvergenceReport;
class DeferredLogger;
class WellInterfaceGeneric;
template<class Scalar> class WellInterfaceGeneric;
template<class Scalar> class WellState;
class WellConvergence
{
public:
WellConvergence(const WellInterfaceGeneric& well)
WellConvergence(const WellInterfaceGeneric<double>& well)
: well_(well)
{}
@ -62,7 +62,7 @@ public:
ConvergenceReport& report) const;
private:
const WellInterfaceGeneric& well_;
const WellInterfaceGeneric<double>& well_;
};
}

View File

@ -36,7 +36,7 @@ namespace Opm {
template<class Scalar>
void WellFilterCake<Scalar>::
updateFiltrationParticleVolume(const WellInterfaceGeneric& well,
updateFiltrationParticleVolume(const WellInterfaceGeneric<Scalar>& well,
const double dt,
const Scalar conc,
const std::size_t water_index,
@ -78,7 +78,7 @@ updateFiltrationParticleVolume(const WellInterfaceGeneric& well,
template<class Scalar>
void WellFilterCake<Scalar>::
updateInjFCMult(const WellInterfaceGeneric& well,
updateInjFCMult(const WellInterfaceGeneric<Scalar>& well,
WellState<Scalar>& well_state,
DeferredLogger& deferred_logger)
{

View File

@ -26,7 +26,7 @@
namespace Opm {
class DeferredLogger;
class WellInterfaceGeneric;
template<class Scalar> class WellInterfaceGeneric;
template<class Scalar> class WellState;
//! \brief Class for well calculations related to filter cakes.
@ -35,14 +35,14 @@ class WellFilterCake {
public:
//! \brief Update the water injection volume.
//! \details Used for calculation related to cake filtration due to injection activity.
void updateFiltrationParticleVolume(const WellInterfaceGeneric& well,
void updateFiltrationParticleVolume(const WellInterfaceGeneric<Scalar>& well,
const double dt,
const Scalar conc,
const std::size_t water_index,
WellState<Scalar>& well_state);
//! \brief Update the multiplier for well transmissbility due to cake filtration.
void updateInjFCMult(const WellInterfaceGeneric& well,
void updateInjFCMult(const WellInterfaceGeneric<Scalar>& well,
WellState<Scalar>& well_state,
DeferredLogger& deferred_logger);

View File

@ -40,16 +40,19 @@ enum class InjectorType;
using RegionId = int;
class Schedule;
class SummaryState;
class WellInterfaceGeneric;
template<class Scalar> class WellInterfaceGeneric;
template<class Scalar> class WellState;
//! \brief Class for computing well group constraints.
class WellGroupConstraints {
public:
//! \brief Constructor sets reference to well.
WellGroupConstraints(const WellInterfaceGeneric& well) : well_(well) {}
WellGroupConstraints(const WellInterfaceGeneric<double>& well) : well_(well) {}
using RateConvFunc = std::function<void(const RegionId, const int, const std::optional<std::string>&, std::vector<double>&)>;
using RateConvFunc = std::function<void(const RegionId,
const int,
const std::optional<std::string>&,
std::vector<double>&)>;
bool checkGroupConstraints(WellState<double>& well_state,
const GroupState<double>& group_state,
@ -79,7 +82,7 @@ private:
const RateConvFunc& rateConverter,
DeferredLogger& deferred_logger) const;
const WellInterfaceGeneric& well_; //!< Reference to well interface
const WellInterfaceGeneric<double>& well_; //!< Reference to well interface
};
}

View File

@ -39,14 +39,14 @@ enum class InjectorType;
using RegionId = int;
class Schedule;
class SummaryState;
class WellInterfaceGeneric;
template<class Scalar> class WellInterfaceGeneric;
template<class Scalar> class WellState;
//! \brief Class for computing well group controls.
class WellGroupControls {
public:
//! \brief Constructor sets reference to well.
WellGroupControls(const WellInterfaceGeneric& well) : well_(well) {}
WellGroupControls(const WellInterfaceGeneric<double>& well) : well_(well) {}
using RateConvFunc = std::function<void(const RegionId, const int, const std::optional<std::string>&, std::vector<double>&)>;
@ -98,7 +98,7 @@ public:
DeferredLogger& deferred_logger) const;
private:
const WellInterfaceGeneric& well_; //!< Reference to well interface
const WellInterfaceGeneric<double>& well_; //!< Reference to well interface
};
}

View File

@ -44,7 +44,7 @@ template<class Scalar> class SingleWellState;
template<class Scalar> class WellState;
template<class FluidSystem>
class WellInterfaceFluidSystem : public WellInterfaceGeneric {
class WellInterfaceFluidSystem : public WellInterfaceGeneric<double> {
protected:
using RateConverterType = RateConverter::
SurfaceToReservoirVoidage<FluidSystem, std::vector<int>>;

View File

@ -49,17 +49,18 @@
#include <cstddef>
#include <stdexcept>
namespace Opm
{
namespace Opm {
WellInterfaceGeneric::WellInterfaceGeneric(const Well& well,
const ParallelWellInfo& pw_info,
const int time_step,
const int pvtRegionIdx,
const int num_components,
const int num_phases,
const int index_of_well,
const std::vector<PerforationData>& perf_data)
template<class Scalar>
WellInterfaceGeneric<Scalar>::
WellInterfaceGeneric(const Well& well,
const ParallelWellInfo& pw_info,
const int time_step,
const int pvtRegionIdx,
const int num_components,
const int num_phases,
const int index_of_well,
const std::vector<PerforationData>& perf_data)
: well_ecl_(well)
, parallel_well_info_(pw_info)
, current_step_(time_step)
@ -121,7 +122,9 @@ WellInterfaceGeneric::WellInterfaceGeneric(const Well& well,
// value in VFPPROD record 5 (GFR values) and supplying a dummy input value
// for the gas rate to the methods in VFPProdProperties.cpp, we can extend
// the VFP calculations to the two-phase oil-water case.
void WellInterfaceGeneric::adaptRatesForVFP(std::vector<double>& rates) const
template<class Scalar>
void WellInterfaceGeneric<Scalar>::
adaptRatesForVFP(std::vector<Scalar>& rates) const
{
const auto& pu = this->phaseUsage();
if (pu.num_phases == 2) {
@ -139,73 +142,91 @@ void WellInterfaceGeneric::adaptRatesForVFP(std::vector<double>& rates) const
}
}
const std::vector<PerforationData>& WellInterfaceGeneric::perforationData() const
template<class Scalar>
const std::vector<PerforationData>&
WellInterfaceGeneric<Scalar>::perforationData() const
{
return *perf_data_;
}
const std::string& WellInterfaceGeneric::name() const
template<class Scalar>
const std::string&
WellInterfaceGeneric<Scalar>::name() const
{
return well_ecl_.name();
}
bool WellInterfaceGeneric::isInjector() const
template<class Scalar>
bool WellInterfaceGeneric<Scalar>::isInjector() const
{
return well_ecl_.isInjector();
}
bool WellInterfaceGeneric::isProducer() const
template<class Scalar>
bool WellInterfaceGeneric<Scalar>::isProducer() const
{
return well_ecl_.isProducer();
}
int WellInterfaceGeneric::indexOfWell() const
template<class Scalar>
int WellInterfaceGeneric<Scalar>::indexOfWell() const
{
return index_of_well_;
}
bool WellInterfaceGeneric::getAllowCrossFlow() const
template<class Scalar>
bool WellInterfaceGeneric<Scalar>::getAllowCrossFlow() const
{
return well_ecl_.getAllowCrossFlow();
}
const Well& WellInterfaceGeneric::wellEcl() const
template<class Scalar>
const Well& WellInterfaceGeneric<Scalar>::wellEcl() const
{
return well_ecl_;
}
Well& WellInterfaceGeneric::wellEcl()
template<class Scalar>
Well& WellInterfaceGeneric<Scalar>::wellEcl()
{
return well_ecl_;
}
const PhaseUsage& WellInterfaceGeneric::phaseUsage() const
template<class Scalar>
const PhaseUsage& WellInterfaceGeneric<Scalar>::phaseUsage() const
{
assert(phase_usage_ != nullptr);
return *phase_usage_;
}
double WellInterfaceGeneric::wsolvent() const
template<class Scalar>
Scalar WellInterfaceGeneric<Scalar>::wsolvent() const
{
return wsolvent_;
}
double WellInterfaceGeneric::rsRvInj() const
template<class Scalar>
Scalar WellInterfaceGeneric<Scalar>::rsRvInj() const
{
return well_ecl_.getInjectionProperties().rsRvInj;
}
void WellInterfaceGeneric::initInjMult(const std::vector<double>& max_inj_mult)
template<class Scalar>
void WellInterfaceGeneric<Scalar>::
initInjMult(const std::vector<Scalar>& max_inj_mult)
{
// prev_inj_multiplier_ will stay unchanged during the time step
// while inj_multiplier_ might be updated during the time step
this->prev_inj_multiplier_ = max_inj_mult;
// initializing the inj_multipler_ to be 1.0
this->inj_multiplier_ = std::vector<double>(max_inj_mult.size(), 1.);
this->inj_multiplier_ = std::vector<Scalar>(max_inj_mult.size(), 1.);
}
void WellInterfaceGeneric::updateInjMult(std::vector<double>& inj_multipliers, DeferredLogger& deferred_logger) const
template<class Scalar>
void WellInterfaceGeneric<Scalar>::
updateInjMult(std::vector<Scalar>& inj_multipliers,
DeferredLogger& deferred_logger) const
{
if (inj_multipliers.size() != this->inj_multiplier_.size()) {
OPM_DEFLOG_THROW(std::runtime_error,
@ -217,15 +238,15 @@ void WellInterfaceGeneric::updateInjMult(std::vector<double>& inj_multipliers, D
inj_multipliers = this->inj_multiplier_;
}
double WellInterfaceGeneric::getInjMult(const int perf,
const double bhp,
const double perf_pres) const
template<class Scalar>
Scalar WellInterfaceGeneric<Scalar>::
getInjMult(const int perf,
const Scalar bhp,
const Scalar perf_pres) const
{
assert(!this->isProducer());
double multiplier = 1.;
Scalar multiplier = 1.;
const auto perf_ecl_index = this->perforationData()[perf].ecl_index;
const bool is_wrev = this->well_ecl_.getInjMultMode() == Well::InjMultMode::WREV;
@ -236,7 +257,7 @@ double WellInterfaceGeneric::getInjMult(const int perf,
if (active_injmult) {
const auto& injmult= is_wrev ? this->well_ecl_.getWellInjMult()
: this->well_ecl_.getConnections()[perf_ecl_index].injmult();
const double pres = is_wrev ? bhp : perf_pres;
const Scalar pres = is_wrev ? bhp : perf_pres;
const auto frac_press = injmult.fracture_pressure;
const auto gradient = injmult.multiplier_gradient;
@ -255,10 +276,9 @@ double WellInterfaceGeneric::getInjMult(const int perf,
return multiplier;
}
bool WellInterfaceGeneric::wellHasTHPConstraints(const SummaryState& summaryState) const
template<class Scalar>
bool WellInterfaceGeneric<Scalar>::
wellHasTHPConstraints(const SummaryState& summaryState) const
{
// only wells under prediction mode can have THP constraint
if (!this->wellEcl().predictionMode()) {
@ -272,11 +292,13 @@ bool WellInterfaceGeneric::wellHasTHPConstraints(const SummaryState& summaryStat
return WellBhpThpCalculator(*this).wellHasTHPConstraints(summaryState);
}
void WellInterfaceGeneric::updateWellTestState(const SingleWellState<double>& ws,
const double& simulationTime,
const bool& writeMessageToOPMLog,
WellTestState& wellTestState,
DeferredLogger& deferred_logger) const
template<class Scalar>
void WellInterfaceGeneric<Scalar>::
updateWellTestState(const SingleWellState<Scalar>& ws,
const double& simulationTime,
const bool& writeMessageToOPMLog,
WellTestState& wellTestState,
DeferredLogger& deferred_logger) const
{
// updating well test state based on Economic limits for operable wells
if (this->isOperableAndSolvable()) {
@ -289,7 +311,9 @@ void WellInterfaceGeneric::updateWellTestState(const SingleWellState<double>& ws
// TODO: well can be shut/closed due to other reasons
}
double WellInterfaceGeneric::getTHPConstraint(const SummaryState& summaryState) const
template<class Scalar>
Scalar WellInterfaceGeneric<Scalar>::
getTHPConstraint(const SummaryState& summaryState) const
{
if (dynamic_thp_limit_) {
return *dynamic_thp_limit_;
@ -298,12 +322,14 @@ double WellInterfaceGeneric::getTHPConstraint(const SummaryState& summaryState)
return WellBhpThpCalculator(*this).getTHPConstraint(summaryState);
}
bool WellInterfaceGeneric::underPredictionMode() const
template<class Scalar>
bool WellInterfaceGeneric<Scalar>::underPredictionMode() const
{
return well_ecl_.predictionMode();
}
void WellInterfaceGeneric::initCompletions()
template<class Scalar>
void WellInterfaceGeneric<Scalar>::initCompletions()
{
assert(completions_.empty() );
@ -330,7 +356,9 @@ void WellInterfaceGeneric::initCompletions()
assert(my_next_perf == perf_data_->end());
}
void WellInterfaceGeneric::closeCompletions(const WellTestState& wellTestState)
template<class Scalar>
void WellInterfaceGeneric<Scalar>::
closeCompletions(const WellTestState& wellTestState)
{
const auto& connections = well_ecl_.getConnections();
int perfIdx = 0;
@ -344,46 +372,55 @@ void WellInterfaceGeneric::closeCompletions(const WellTestState& wellTestState)
}
}
void WellInterfaceGeneric::setVFPProperties(const VFPProperties* vfp_properties_arg)
template<class Scalar>
void WellInterfaceGeneric<Scalar>::
setVFPProperties(const VFPProperties* vfp_properties_arg)
{
vfp_properties_ = vfp_properties_arg;
}
void WellInterfaceGeneric::setPrevSurfaceRates(WellState<double>& well_state,
const WellState<double>& prev_well_state) const
{
auto& ws = well_state.well(this->index_of_well_);
auto& ws_prev = prev_well_state.well(this->index_of_well_);
// The logic here is a bit fragile:
// We need non-zero prev_surface_rates for the purpose of providing explicit fractions
// (if needed) for vfp interpolation.
// We assume that current surface rates either are initialized from previous step
// or (if newly opened) from updateWellStateRates. This is fine unless well was
// stopped in previous step in which case it's rates will be zero. In this case,
// we select the previous rates of the previous well state (and hope for the best).
const bool zero_rates = std::all_of(ws.surface_rates.begin(), ws.surface_rates.end(),
[](double rate) {
return rate == 0.; // TODO: should we use a threshhold for comparison?
} );
template<class Scalar>
void WellInterfaceGeneric<Scalar>::
setPrevSurfaceRates(WellState<Scalar>& well_state,
const WellState<Scalar>& prev_well_state) const
{
auto& ws = well_state.well(this->index_of_well_);
auto& ws_prev = prev_well_state.well(this->index_of_well_);
// The logic here is a bit fragile:
// We need non-zero prev_surface_rates for the purpose of providing explicit fractions
// (if needed) for vfp interpolation.
// We assume that current surface rates either are initialized from previous step
// or (if newly opened) from updateWellStateRates. This is fine unless well was
// stopped in previous step in which case it's rates will be zero. In this case,
// we select the previous rates of the previous well state (and hope for the best).
const bool zero_rates = std::all_of(ws.surface_rates.begin(), ws.surface_rates.end(),
[](Scalar rate) {
return rate == 0.; // TODO: should we use a threshhold for comparison?
} );
if (zero_rates) {
ws.prev_surface_rates = ws_prev.prev_surface_rates;
} else {
ws.prev_surface_rates = ws.surface_rates;
}
if (zero_rates) {
ws.prev_surface_rates = ws_prev.prev_surface_rates;
} else {
ws.prev_surface_rates = ws.surface_rates;
}
}
void WellInterfaceGeneric::setGuideRate(const GuideRate* guide_rate_arg)
template<class Scalar>
void WellInterfaceGeneric<Scalar>::
setGuideRate(const GuideRate* guide_rate_arg)
{
guide_rate_ = guide_rate_arg;
}
void WellInterfaceGeneric::setWellEfficiencyFactor(const double efficiency_factor)
template<class Scalar>
void WellInterfaceGeneric<Scalar>::
setWellEfficiencyFactor(const Scalar efficiency_factor)
{
well_efficiency_factor_ = efficiency_factor;
}
void WellInterfaceGeneric::setRepRadiusPerfLength()
template<class Scalar>
void WellInterfaceGeneric<Scalar>::setRepRadiusPerfLength()
{
const int nperf = number_of_perforations_;
@ -411,10 +448,10 @@ void WellInterfaceGeneric::setRepRadiusPerfLength()
assert(my_next_perf->ecl_index == c);
const auto& connection = connections[c];
if (connection.state() == Connection::State::OPEN) {
double radius = connection.rw();
double re = connection.re(); // area equivalent radius of the grid block
double perf_length = connection.connectionLength(); // the length of the well perforation
const double repR = std::sqrt(re * radius);
Scalar radius = connection.rw();
Scalar re = connection.re(); // area equivalent radius of the grid block
Scalar perf_length = connection.connectionLength(); // the length of the well perforation
const Scalar repR = std::sqrt(re * radius);
perf_rep_radius_.push_back(repR);
perf_length_.push_back(perf_length);
bore_diameters_.push_back(2. * radius);
@ -426,30 +463,39 @@ void WellInterfaceGeneric::setRepRadiusPerfLength()
assert(num_active_connections == nperf);
}
void WellInterfaceGeneric::setWsolvent(const double wsolvent)
template<class Scalar>
void WellInterfaceGeneric<Scalar>::
setWsolvent(const Scalar wsolvent)
{
wsolvent_ = wsolvent;
}
void WellInterfaceGeneric::setDynamicThpLimit(const double thp_limit)
template<class Scalar>
void WellInterfaceGeneric<Scalar>::
setDynamicThpLimit(const Scalar thp_limit)
{
dynamic_thp_limit_ = thp_limit;
}
std::optional<double> WellInterfaceGeneric::getDynamicThpLimit() const
template<class Scalar>
std::optional<Scalar>
WellInterfaceGeneric<Scalar>::getDynamicThpLimit() const
{
return dynamic_thp_limit_;
}
void WellInterfaceGeneric::updatePerforatedCell(std::vector<bool>& is_cell_perforated)
template<class Scalar>
void WellInterfaceGeneric<Scalar>::
updatePerforatedCell(std::vector<bool>& is_cell_perforated)
{
for (int perf_idx = 0; perf_idx<number_of_perforations_; ++perf_idx) {
for (int perf_idx = 0; perf_idx < number_of_perforations_; ++perf_idx) {
is_cell_perforated[well_cells_[perf_idx]] = true;
}
}
bool WellInterfaceGeneric::isVFPActive(DeferredLogger& deferred_logger) const
template<class Scalar>
bool WellInterfaceGeneric<Scalar>::
isVFPActive(DeferredLogger& deferred_logger) const
{
// since the well_controls only handles the VFP number when THP constraint/target is there.
// we need to get the table number through the parser, in case THP constraint/target is not there.
@ -489,23 +535,28 @@ bool WellInterfaceGeneric::isVFPActive(DeferredLogger& deferred_logger) const
}
}
bool WellInterfaceGeneric::isOperableAndSolvable() const
template<class Scalar>
bool WellInterfaceGeneric<Scalar>::isOperableAndSolvable() const
{
return operability_status_.isOperableAndSolvable();
}
bool WellInterfaceGeneric::useVfpExplicit() const
template<class Scalar>
bool WellInterfaceGeneric<Scalar>::useVfpExplicit() const
{
const auto& wvfpexp = well_ecl_.getWVFPEXP();
return (wvfpexp.explicit_lookup() || operability_status_.use_vfpexplicit);
}
bool WellInterfaceGeneric::thpLimitViolatedButNotSwitched() const
template<class Scalar>
bool WellInterfaceGeneric<Scalar>::thpLimitViolatedButNotSwitched() const
{
return operability_status_.thp_limit_violated_but_not_switched;
}
double WellInterfaceGeneric::getALQ(const WellState<double>& well_state) const
template<class Scalar>
Scalar WellInterfaceGeneric<Scalar>::
getALQ(const WellState<Scalar>& well_state) const
{
// no alq for injectors.
if (isInjector())
@ -514,8 +565,10 @@ double WellInterfaceGeneric::getALQ(const WellState<double>& well_state) const
return well_state.getALQ(name());
}
void WellInterfaceGeneric::reportWellSwitching(const SingleWellState<double> &ws,
DeferredLogger& deferred_logger) const
template<class Scalar>
void WellInterfaceGeneric<Scalar>::
reportWellSwitching(const SingleWellState<Scalar> &ws,
DeferredLogger& deferred_logger) const
{
if (well_control_log_.empty())
return;
@ -534,7 +587,9 @@ void WellInterfaceGeneric::reportWellSwitching(const SingleWellState<double> &ws
}
}
bool WellInterfaceGeneric::isPressureControlled(const WellState<double>& well_state) const
template<class Scalar>
bool WellInterfaceGeneric<Scalar>::
isPressureControlled(const WellState<Scalar>& well_state) const
{
const auto& ws = well_state.well(this->index_of_well_);
if (this->isInjector()) {
@ -548,10 +603,10 @@ bool WellInterfaceGeneric::isPressureControlled(const WellState<double>& well_st
}
}
bool WellInterfaceGeneric::wellUnderZeroRateTarget(const SummaryState& summary_state,
const WellState<double>& well_state) const
template<class Scalar>
bool WellInterfaceGeneric<Scalar>::
wellUnderZeroRateTarget(const SummaryState& summary_state,
const WellState<Scalar>& well_state) const
{
if (this->isProducer()) { // producers
const auto prod_controls = this->well_ecl_.productionControls(summary_state);
@ -564,25 +619,29 @@ bool WellInterfaceGeneric::wellUnderZeroRateTarget(const SummaryState& summary_s
}
}
bool WellInterfaceGeneric::stopppedOrZeroRateTarget(const SummaryState& summary_state,
const WellState<double>& well_state) const
template<class Scalar>
bool WellInterfaceGeneric<Scalar>::
stopppedOrZeroRateTarget(const SummaryState& summary_state,
const WellState<Scalar>& well_state) const
{
return (this->wellIsStopped() || this->wellUnderZeroRateTarget(summary_state, well_state));
}
void WellInterfaceGeneric::resetWellOperability()
template<class Scalar>
void WellInterfaceGeneric<Scalar>::resetWellOperability()
{
this->operability_status_.resetOperability();
}
double WellInterfaceGeneric::wmicrobes_() const
template<class Scalar>
Scalar WellInterfaceGeneric<Scalar>::wmicrobes_() const
{
auto injectorType = this->well_ecl_.injectorType();
if (injectorType == InjectorType::WATER) {
WellMICPProperties microbes = this->well_ecl_.getMICPProperties();
const double microbial_injection_concentration = microbes.m_microbialConcentration;
const Scalar microbial_injection_concentration = microbes.m_microbialConcentration;
return microbial_injection_concentration;
} else {
// Not a water injection well => no microbes.
@ -590,7 +649,8 @@ double WellInterfaceGeneric::wmicrobes_() const
}
}
double WellInterfaceGeneric::wfoam_() const
template<class Scalar>
Scalar WellInterfaceGeneric<Scalar>::wfoam_() const
{
auto injectorType = this->well_ecl_.injectorType();
@ -603,7 +663,8 @@ double WellInterfaceGeneric::wfoam_() const
}
}
double WellInterfaceGeneric::wsalt_() const
template<class Scalar>
Scalar WellInterfaceGeneric<Scalar>::wsalt_() const
{
auto injectorType = this->well_ecl_.injectorType();
@ -616,13 +677,14 @@ double WellInterfaceGeneric::wsalt_() const
}
}
double WellInterfaceGeneric::woxygen_() const
template<class Scalar>
Scalar WellInterfaceGeneric<Scalar>::woxygen_() const
{
auto injectorType = this->well_ecl_.injectorType();
if (injectorType == InjectorType::WATER) {
WellMICPProperties oxygen = this->well_ecl_.getMICPProperties();
const double oxygen_injection_concentration = oxygen.m_oxygenConcentration;
const Scalar oxygen_injection_concentration = oxygen.m_oxygenConcentration;
return oxygen_injection_concentration;
} else {
// Not a water injection well => no oxygen.
@ -630,13 +692,14 @@ double WellInterfaceGeneric::woxygen_() const
}
}
double WellInterfaceGeneric::wpolymer_() const
template<class Scalar>
Scalar WellInterfaceGeneric<Scalar>::wpolymer_() const
{
auto injectorType = this->well_ecl_.injectorType();
if (injectorType == InjectorType::WATER) {
WellPolymerProperties polymer = this->well_ecl_.getPolymerProperties();
const double polymer_injection_concentration = polymer.m_polymerConcentration;
const Scalar polymer_injection_concentration = polymer.m_polymerConcentration;
return polymer_injection_concentration;
} else {
// Not a water injection well => no polymer.
@ -644,13 +707,14 @@ double WellInterfaceGeneric::wpolymer_() const
}
}
double WellInterfaceGeneric::wurea_() const
template<class Scalar>
Scalar WellInterfaceGeneric<Scalar>::wurea_() const
{
auto injectorType = this->well_ecl_.injectorType();
if (injectorType == InjectorType::WATER) {
WellMICPProperties urea = this->well_ecl_.getMICPProperties();
const double urea_injection_concentration = urea.m_ureaConcentration / 10.; //Dividing by scaling factor 10
const Scalar urea_injection_concentration = urea.m_ureaConcentration / 10.; //Dividing by scaling factor 10
return urea_injection_concentration;
} else {
// Not a water injection well => no urea.
@ -658,24 +722,28 @@ double WellInterfaceGeneric::wurea_() const
}
}
int WellInterfaceGeneric::polymerTable_() const
template<class Scalar>
int WellInterfaceGeneric<Scalar>::polymerTable_() const
{
return this->well_ecl_.getPolymerProperties().m_skprpolytable;
}
int WellInterfaceGeneric::polymerWaterTable_() const
template<class Scalar>
int WellInterfaceGeneric<Scalar>::polymerWaterTable_() const
{
return this->well_ecl_.getPolymerProperties().m_skprwattable;
}
int WellInterfaceGeneric::polymerInjTable_() const
template<class Scalar>
int WellInterfaceGeneric<Scalar>::polymerInjTable_() const
{
return this->well_ecl_.getPolymerProperties().m_plymwinjtable;
}
std::pair<bool,bool> WellInterfaceGeneric::
computeWellPotentials(std::vector<double>& well_potentials,
const WellState<double>& well_state)
template<class Scalar>
std::pair<bool,bool> WellInterfaceGeneric<Scalar>::
computeWellPotentials(std::vector<Scalar>& well_potentials,
const WellState<Scalar>& well_state)
{
const int np = this->number_of_phases_;
well_potentials.resize(np, 0.0);
@ -711,8 +779,8 @@ computeWellPotentials(std::vector<double>& well_potentials,
if (!this->changed_to_open_this_step_ &&
(thp_controlled_well || bhp_controlled_well)) {
double total_rate = 0.0;
const double sign = this->isInjector() ? 1.0 : -1.0;
Scalar total_rate = 0.0;
const Scalar sign = this->isInjector() ? 1.0 : -1.0;
for (int phase = 0; phase < np; ++phase){
total_rate += sign * ws.surface_rates[phase];
}
@ -730,13 +798,14 @@ computeWellPotentials(std::vector<double>& well_potentials,
return {compute_potential, bhp_controlled_well};
}
void WellInterfaceGeneric::
checkNegativeWellPotentials(std::vector<double>& well_potentials,
template<class Scalar>
void WellInterfaceGeneric<Scalar>::
checkNegativeWellPotentials(std::vector<Scalar>& well_potentials,
const bool checkOperability,
DeferredLogger& deferred_logger)
{
const double sign = this->isInjector() ? 1.0 : -1.0;
double total_potential = 0.0;
const Scalar sign = this->isInjector() ? 1.0 : -1.0;
Scalar total_potential = 0.0;
for (int phase = 0; phase < this->number_of_phases_; ++phase) {
well_potentials[phase] *= sign;
total_potential += well_potentials[phase];
@ -750,9 +819,10 @@ checkNegativeWellPotentials(std::vector<double>& well_potentials,
}
}
void WellInterfaceGeneric::
template<class Scalar>
void WellInterfaceGeneric<Scalar>::
prepareForPotentialCalculations(const SummaryState& summary_state,
WellState<double>& well_state,
WellState<Scalar>& well_state,
Well::InjectionControls& inj_controls,
Well::ProductionControls& prod_controls) const
{
@ -793,4 +863,6 @@ prepareForPotentialCalculations(const SummaryState& summary_state,
}
}
template class WellInterfaceGeneric<double>;
} // namespace Opm

View File

@ -47,6 +47,7 @@ template<class Scalar> class SingleWellState;
class Group;
class Schedule;
template<class Scalar>
class WellInterfaceGeneric {
public:
WellInterfaceGeneric(const Well& well,
@ -76,7 +77,7 @@ public:
/// Index of well in the wells struct and wellState
int indexOfWell() const;
void adaptRatesForVFP(std::vector<double>& rates) const;
void adaptRatesForVFP(std::vector<Scalar>& rates) const;
const Well& wellEcl() const;
Well& wellEcl();
@ -94,127 +95,91 @@ public:
void closeCompletions(const WellTestState& wellTestState);
void setVFPProperties(const VFPProperties* vfp_properties_arg);
void setPrevSurfaceRates(WellState<double>& well_state,
const WellState<double>& prev_well_state) const;
void setPrevSurfaceRates(WellState<Scalar>& well_state,
const WellState<Scalar>& prev_well_state) const;
void setGuideRate(const GuideRate* guide_rate_arg);
void setWellEfficiencyFactor(const double efficiency_factor);
void setWellEfficiencyFactor(const Scalar efficiency_factor);
void setRepRadiusPerfLength();
void setWsolvent(const double wsolvent);
void setDynamicThpLimit(const double thp_limit);
std::optional<double> getDynamicThpLimit() const;
void setWsolvent(const Scalar wsolvent);
void setDynamicThpLimit(const Scalar thp_limit);
std::optional<Scalar> getDynamicThpLimit() const;
void updatePerforatedCell(std::vector<bool>& is_cell_perforated);
/// Returns true if the well has one or more THP limits/constraints.
bool wellHasTHPConstraints(const SummaryState& summaryState) const;
void stopWell() {
this->wellStatus_ = Well::Status::STOP;
}
void stopWell() { this->wellStatus_ = Well::Status::STOP; }
void openWell() { this->wellStatus_ = Well::Status::OPEN; }
void openWell() {
this->wellStatus_ = Well::Status::OPEN;
}
bool wellIsStopped() const { return this->wellStatus_ == Well::Status::STOP; }
bool wellIsStopped() const {
return this->wellStatus_ == Well::Status::STOP;
}
int currentStep() const { return this->current_step_; }
int currentStep() const {
return this->current_step_;
}
int pvtRegionIdx() const { return pvtRegionIdx_; }
int pvtRegionIdx() const {
return pvtRegionIdx_;
}
const GuideRate* guideRate() const { return guide_rate_; }
const GuideRate* guideRate() const {
return guide_rate_;
}
int numComponents() const { return num_components_; }
int numComponents() const {
return num_components_;
}
int numPhases() const { return number_of_phases_; }
int numPhases() const {
return number_of_phases_;
}
int numPerfs() const { return number_of_perforations_; }
int numPerfs() const {
return number_of_perforations_;
}
Scalar refDepth() const { return ref_depth_; }
double refDepth() const {
return ref_depth_;
}
Scalar gravity() const { return gravity_; }
double gravity() const {
return gravity_;
}
const VFPProperties* vfpProperties() const { return vfp_properties_; }
const VFPProperties* vfpProperties() const {
return vfp_properties_;
}
const ParallelWellInfo& parallelWellInfo() const { return parallel_well_info_; }
const ParallelWellInfo& parallelWellInfo() const {
return parallel_well_info_;
}
const std::vector<Scalar>& perfDepth() const { return perf_depth_; }
const std::vector<double>& perfDepth() const {
return perf_depth_;
}
std::vector<Scalar>& perfDepth() { return perf_depth_; }
std::vector<double>& perfDepth() {
return perf_depth_;
}
const std::vector<Scalar>& wellIndex() const { return well_index_; }
const std::vector<double>& wellIndex() const {
return well_index_;
}
const std::map<int,std::vector<int>>& getCompletions() const { return completions_; }
const std::map<int,std::vector<int>>& getCompletions() const {
return completions_;
}
double getTHPConstraint(const SummaryState& summaryState) const;
double getALQ(const WellState<double>& well_state) const;
double wsolvent() const;
double rsRvInj() const;
Scalar getTHPConstraint(const SummaryState& summaryState) const;
Scalar getALQ(const WellState<Scalar>& well_state) const;
Scalar wsolvent() const;
Scalar rsRvInj() const;
// at the beginning of the time step, we check what inj_multiplier from the previous running
void initInjMult(const std::vector<double>& max_inj_mult);
void initInjMult(const std::vector<Scalar>& max_inj_mult);
// update the InjMult information at the end of the time step, so it can be used for later.
void updateInjMult(std::vector<double>& inj_multipliers, DeferredLogger& deferred_logger) const;
void updateInjMult(std::vector<Scalar>& inj_multipliers,
DeferredLogger& deferred_logger) const;
// Note:: for multisegment wells, bhp is actually segment pressure in practice based on observation
// it might change in the future
double getInjMult(const int perf, const double bhp, const double perf_pres) const;
Scalar getInjMult(const int perf, const Scalar bhp, const Scalar perf_pres) const;
// whether a well is specified with a non-zero and valid VFP table number
bool isVFPActive(DeferredLogger& deferred_logger) const;
void reportWellSwitching(const SingleWellState<double>& ws, DeferredLogger& deferred_logger) const;
void reportWellSwitching(const SingleWellState<Scalar>& ws,
DeferredLogger& deferred_logger) const;
bool changedToOpenThisStep() const {
return this->changed_to_open_this_step_;
}
bool changedToOpenThisStep() const { return this->changed_to_open_this_step_; }
void updateWellTestState(const SingleWellState<double>& ws,
void updateWellTestState(const SingleWellState<Scalar>& ws,
const double& simulationTime,
const bool& writeMessageToOPMLog,
WellTestState& wellTestState,
DeferredLogger& deferred_logger) const;
bool isPressureControlled(const WellState<double>& well_state) const;
bool isPressureControlled(const WellState<Scalar>& well_state) const;
bool stopppedOrZeroRateTarget(const SummaryState& summary_state,
const WellState<double>& well_state) const;
const WellState<Scalar>& well_state) const;
double wellEfficiencyFactor() const
{ return well_efficiency_factor_; }
Scalar wellEfficiencyFactor() const { return well_efficiency_factor_; }
//! \brief Update filter cake multipliers.
void updateFilterCakeMultipliers(const std::vector<double>& inj_fc_multiplier)
void updateFilterCakeMultipliers(const std::vector<Scalar>& inj_fc_multiplier)
{
inj_fc_multiplier_ = inj_fc_multiplier;
}
@ -224,36 +189,38 @@ public:
protected:
bool getAllowCrossFlow() const;
double wmicrobes_() const;
double wfoam_() const;
double woxygen_() const;
double wpolymer_() const;
double wsalt_() const;
double wurea_() const;
Scalar wmicrobes_() const;
Scalar wfoam_() const;
Scalar woxygen_() const;
Scalar wpolymer_() const;
Scalar wsalt_() const;
Scalar wurea_() const;
int polymerTable_() const;
int polymerInjTable_() const;
int polymerWaterTable_() const;
bool wellUnderZeroRateTarget(const SummaryState& summary_state,
const WellState<double>& well_state) const;
const WellState<Scalar>& well_state) const;
std::pair<bool,bool>
computeWellPotentials(std::vector<double>& well_potentials,
const WellState<double>& well_state);
computeWellPotentials(std::vector<Scalar>& well_potentials,
const WellState<Scalar>& well_state);
void checkNegativeWellPotentials(std::vector<double>& well_potentials,
void checkNegativeWellPotentials(std::vector<Scalar>& well_potentials,
const bool checkOperability,
DeferredLogger& deferred_logger);
void prepareForPotentialCalculations(const SummaryState& summary_state,
WellState<double>& well_state,
WellState<Scalar>& well_state,
Well::InjectionControls& inj_controls,
Well::ProductionControls& prod_controls) const;
// definition of the struct OperabilityStatus
struct OperabilityStatus {
bool isOperableAndSolvable() const {
struct OperabilityStatus
{
bool isOperableAndSolvable() const
{
if (!operable_under_only_bhp_limit || !solvable || has_negative_potentials) {
return false;
} else {
@ -261,15 +228,18 @@ protected:
}
}
bool isOperableUnderBHPLimit() const {
bool isOperableUnderBHPLimit() const
{
return operable_under_only_bhp_limit && obey_thp_limit_under_bhp_limit;
}
bool isOperableUnderTHPLimit() const {
bool isOperableUnderTHPLimit() const
{
return can_obtain_bhp_with_thp_limit && obey_bhp_limit_with_thp_limit;
}
void resetOperability() {
void resetOperability()
{
operable_under_only_bhp_limit = true;
obey_thp_limit_under_bhp_limit = true;
can_obtain_bhp_with_thp_limit = true;
@ -322,29 +292,29 @@ protected:
// Q = IPR_A - BHP * IPR_B
// TODO: it minght need to go to WellInterface, let us implement it in StandardWell first
// it is only updated and used for producers for now
mutable std::vector<double> ipr_a_;
mutable std::vector<double> ipr_b_;
mutable std::vector<Scalar> ipr_a_;
mutable std::vector<Scalar> ipr_b_;
// cell index for each well perforation
std::vector<int> well_cells_;
// well index for each perforation
std::vector<double> well_index_;
std::vector<Scalar> well_index_;
// number of the perforations for this well
int number_of_perforations_;
// depth for each perforation
std::vector<double> perf_depth_;
std::vector<Scalar> perf_depth_;
// representative radius of the perforations, used in shear calculation
std::vector<double> perf_rep_radius_;
std::vector<Scalar> perf_rep_radius_;
// length of the perforations, use in shear calculation
std::vector<double> perf_length_;
std::vector<Scalar> perf_length_;
// well bore diameter
std::vector<double> bore_diameters_;
std::vector<Scalar> bore_diameters_;
/*
* completions_ contains the mapping from completion id to connection indices
@ -364,7 +334,7 @@ protected:
std::map<int, std::vector<int>> completions_;
// reference depth for the BHP
double ref_depth_;
Scalar ref_depth_;
// saturation table nubmer for each well perforation
std::vector<int> saturation_table_number_;
@ -373,25 +343,25 @@ protected:
const PhaseUsage* phase_usage_;
double gravity_;
double wsolvent_;
std::optional<double> dynamic_thp_limit_;
Scalar gravity_;
Scalar wsolvent_;
std::optional<Scalar> dynamic_thp_limit_;
// recording the multiplier calculate from the keyword WINJMULT during the time step
mutable std::vector<double> inj_multiplier_;
mutable std::vector<Scalar> inj_multiplier_;
// the injection multiplier from the previous running, it is mostly used for CIRR mode
// which intends to keep the fracturing open
std::vector<double> prev_inj_multiplier_;
std::vector<Scalar> prev_inj_multiplier_;
// the multiplier due to injection filtration cake
std::vector<double> inj_fc_multiplier_;
std::vector<Scalar> inj_fc_multiplier_;
double well_efficiency_factor_;
Scalar well_efficiency_factor_;
const VFPProperties* vfp_properties_;
const GuideRate* guide_rate_;
std::vector< std::string> well_control_log_;
std::vector<std::string> well_control_log_;
bool changed_to_open_this_step_ = true;
};

View File

@ -34,14 +34,14 @@ class DeferredLogger;
struct PhaseUsage;
template<class Scalar> class SingleWellState;
class WellEconProductionLimits;
class WellInterfaceGeneric;
template<class Scalar> class WellInterfaceGeneric;
class WellTestState;
//! \brief Class for performing well tests.
class WellTest {
public:
//! \brief Constructor sets reference to well.
WellTest(const WellInterfaceGeneric& well) : well_(well) {}
WellTest(const WellInterfaceGeneric<double>& well) : well_(well) {}
void updateWellTestStateEconomic(const SingleWellState<double>& ws,
const double simulation_time,
@ -95,7 +95,7 @@ private:
DeferredLogger& deferred_logger) const;
const WellInterfaceGeneric& well_; //!< Reference to well interface
const WellInterfaceGeneric<double>& well_; //!< Reference to well interface
};
}