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> template<class Scalar>
WellInterfaceGeneric* WellInterfaceGeneric<Scalar>*
BlackoilWellModelGeneric<Scalar>:: BlackoilWellModelGeneric<Scalar>::
getGenWell(const std::string& well_name) getGenWell(const std::string& well_name)
{ {
// finding the iterator of the well in wells_ecl // finding the iterator of the well in wells_ecl
auto well = std::find_if(well_container_generic_.begin(), auto well = std::find_if(well_container_generic_.begin(),
well_container_generic_.end(), well_container_generic_.end(),
[&well_name](const WellInterfaceGeneric* elem)->bool { [&well_name](const WellInterfaceGeneric<Scalar>* elem)->bool {
return elem->name() == well_name; return elem->name() == well_name;
}); });

View File

@@ -64,7 +64,7 @@ namespace Opm {
struct SimulatorUpdate; struct SimulatorUpdate;
class SummaryConfig; class SummaryConfig;
class VFPProperties; class VFPProperties;
class WellInterfaceGeneric; template<class Scalar> class WellInterfaceGeneric;
template<class Scalar> class WellState; template<class Scalar> class WellState;
} // namespace Opm } // namespace Opm
@@ -84,7 +84,7 @@ class BlackoilWellModelGeneric
public: public:
// --------- Types --------- // --------- Types ---------
using GLiftOptWells = std::map<std::string, std::unique_ptr<GasLiftSingleWellGeneric<Scalar>>>; 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>>>; using GLiftWellStateMap = std::map<std::string, std::unique_ptr<GasLiftWellState<Scalar>>>;
BlackoilWellModelGeneric(Schedule& schedule, BlackoilWellModelGeneric(Schedule& schedule,
@@ -115,7 +115,7 @@ public:
const Schedule& schedule() const { return schedule_; } const Schedule& schedule() const { return schedule_; }
const PhaseUsage& phaseUsage() const { return phase_usage_; } const PhaseUsage& phaseUsage() const { return phase_usage_; }
const GroupState<Scalar>& groupState() const { return this->active_wgstate_.group_state; } 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()}; } { return {well_container_generic_.begin(), well_container_generic_.end()}; }
/* /*
@@ -542,7 +542,7 @@ protected:
std::function<bool(const Well&)> not_on_process_{}; std::function<bool(const Well&)> not_on_process_{};
// a vector of all the wells. // 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_{}; std::vector<int> local_shut_wells_{};
@@ -589,7 +589,7 @@ protected:
std::map<std::string, std::pair<std::string, std::string>> closed_offending_wells_; std::map<std::string, std::pair<std::string, std::string>> closed_offending_wells_;
private: 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(); const auto& genWells = wellModel_.genericWells();
auto need_update = auto need_update =
std::any_of(genWells.begin(), genWells.end(), std::any_of(genWells.begin(), genWells.end(),
[](const WellInterfaceGeneric* well) [](const WellInterfaceGeneric<Scalar>* well)
{ {
return well->changedToOpenThisStep(); return well->changedToOpenThisStep();
}); });
@@ -594,7 +594,7 @@ guideRateUpdateIsNeeded(const int reportStepIdx) const
+ ScheduleEvents::NEW_WELL; + ScheduleEvents::NEW_WELL;
need_update = std::any_of(genWells.begin(), genWells.end(), 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); return events.hasEvent(well->name(), effective_events_mask);
}); });

View File

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

View File

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

View File

@@ -238,7 +238,7 @@ checkThpControl_() const
const Well::ProducerCMode& control_mode = const Well::ProducerCMode& control_mode =
this->well_state_.well(well_index).production_cmode; this->well_state_.well(well_index).production_cmode;
bool thp_control = control_mode == Well::ProducerCMode::THP; bool thp_control = control_mode == Well::ProducerCMode::THP;
const WellInterfaceGeneric &well = getWell(); const auto& well = getWell();
thp_control = thp_control || well.thpLimitViolatedButNotSwitched(); thp_control = thp_control || well.thpLimitViolatedButNotSwitched();
if (this->debug) { if (this->debug) {
if (!thp_control) { 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); const GradInfo& gi = this->parent.dec_grads_.at(well_name);
GasLiftWellState<Scalar>& state = *(this->parent.well_state_map_.at(well_name).get()); GasLiftWellState<Scalar>& state = *(this->parent.well_state_map_.at(well_name).get());
GasLiftSingleWell& gs_well = *(this->parent.stage1_wells_.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 // only get deltas for wells owned by this rank
if (this->parent.well_state_.wellIsOwned(well.indexOfWell(), well_name)) { if (this->parent.well_state_.wellIsOwned(well.indexOfWell(), well_name)) {
const auto& well_ecl = well.wellEcl(); const auto& well_ecl = well.wellEcl();

View File

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

View File

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

View File

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

View File

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

View File

@@ -32,7 +32,7 @@ namespace Opm
class DeferredLogger; class DeferredLogger;
class SummaryState; class SummaryState;
class WellInterfaceGeneric; template<class Scalar> class WellInterfaceGeneric;
enum class WellSegmentCompPressureDrop; enum class WellSegmentCompPressureDrop;
class WellSegments; class WellSegments;
template<class Scalar> class WellState; template<class Scalar> class WellState;
@@ -52,7 +52,7 @@ public:
int numberOfSegments() const; int numberOfSegments() const;
protected: protected:
MultisegmentWellGeneric(WellInterfaceGeneric& baseif); MultisegmentWellGeneric(WellInterfaceGeneric<Scalar>& baseif);
// scale the segment rates and pressure based on well rates and bhp // scale the segment rates and pressure based on well rates and bhp
void scaleSegmentRatesWithWellRates(const std::vector<std::vector<int>>& segment_inlets, void scaleSegmentRatesWithWellRates(const std::vector<std::vector<int>>& segment_inlets,
@@ -75,7 +75,7 @@ protected:
const double density, const double density,
const std::vector<double>& seg_dp) const; 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 <fmt/format.h>
#include <algorithm>
#include <array> #include <array>
#include <cmath> #include <cmath>
#include <cstddef> #include <cstddef>
@@ -61,7 +60,7 @@ namespace Opm
template<class FluidSystem, class Indices> template<class FluidSystem, class Indices>
MultisegmentWellSegments<FluidSystem,Indices>:: MultisegmentWellSegments<FluidSystem,Indices>::
MultisegmentWellSegments(const int numSegments, MultisegmentWellSegments(const int numSegments,
WellInterfaceGeneric& well) WellInterfaceGeneric<Scalar>& well)
: perforations_(numSegments) : perforations_(numSegments)
, perforation_depth_diffs_(well.numPerfs(), 0.0) , perforation_depth_diffs_(well.numPerfs(), 0.0)
, inlets_(well.wellEcl().getSegments().size()) , inlets_(well.wellEcl().getSegments().size())

View File

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

View File

@@ -287,7 +287,7 @@ namespace Opm
DeferredLogger& deferred_logger) DeferredLogger& deferred_logger)
{ {
const auto [compute_potential, bhp_controlled_well] = 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) { if (!compute_potential) {
return; return;

View File

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

View File

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

View File

@@ -1706,7 +1706,7 @@ namespace Opm
DeferredLogger& deferred_logger) // const DeferredLogger& deferred_logger) // const
{ {
const auto [compute_potential, bhp_controlled_well] = 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) { if (!compute_potential) {
return; return;

View File

@@ -35,14 +35,14 @@ namespace Opm
class DeferredLogger; class DeferredLogger;
class SummaryState; class SummaryState;
class Well; class Well;
class WellInterfaceGeneric; template<class Scalar> class WellInterfaceGeneric;
template<class Scalar> class WellState; template<class Scalar> class WellState;
//! \brief Class for computing BHP limits. //! \brief Class for computing BHP limits.
class WellBhpThpCalculator { class WellBhpThpCalculator {
public: public:
//! \brief Constructor sets reference to well. //! \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. //! \brief Checks if well has THP constraints.
bool wellHasTHPConstraints(const SummaryState& summaryState) const; bool wellHasTHPConstraints(const SummaryState& summaryState) const;
@@ -168,7 +168,7 @@ private:
const double dp, const double dp,
DeferredLogger& deferred_logger) const; 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; class Rates;
template<class Scalar> class SingleWellState; template<class Scalar> class SingleWellState;
class SummaryState; class SummaryState;
class WellInterfaceGeneric; template<class Scalar> class WellInterfaceGeneric;
enum class WellInjectorCMode; enum class WellInjectorCMode;
enum class WellProducerCMode; enum class WellProducerCMode;
@@ -47,7 +47,7 @@ enum class WellProducerCMode;
class WellConstraints { class WellConstraints {
public: public:
//! \brief Constructor sets reference to well. //! \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, using RateConvFunc = std::function<void(const RegionId, const int,
const std::vector<double>&, const std::vector<double>&,
@@ -78,7 +78,7 @@ private:
DeferredLogger& deferred_logger, DeferredLogger& deferred_logger,
const std::optional<Well::ProductionControls>& prod_controls = std::nullopt) const; 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 ConvergenceReport;
class DeferredLogger; class DeferredLogger;
class WellInterfaceGeneric; template<class Scalar> class WellInterfaceGeneric;
template<class Scalar> class WellState; template<class Scalar> class WellState;
class WellConvergence class WellConvergence
{ {
public: public:
WellConvergence(const WellInterfaceGeneric& well) WellConvergence(const WellInterfaceGeneric<double>& well)
: well_(well) : well_(well)
{} {}
@@ -62,7 +62,7 @@ public:
ConvergenceReport& report) const; ConvergenceReport& report) const;
private: private:
const WellInterfaceGeneric& well_; const WellInterfaceGeneric<double>& well_;
}; };
} }

View File

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

View File

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

View File

@@ -40,16 +40,19 @@ enum class InjectorType;
using RegionId = int; using RegionId = int;
class Schedule; class Schedule;
class SummaryState; class SummaryState;
class WellInterfaceGeneric; template<class Scalar> class WellInterfaceGeneric;
template<class Scalar> class WellState; template<class Scalar> class WellState;
//! \brief Class for computing well group constraints. //! \brief Class for computing well group constraints.
class WellGroupConstraints { class WellGroupConstraints {
public: public:
//! \brief Constructor sets reference to well. //! \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, bool checkGroupConstraints(WellState<double>& well_state,
const GroupState<double>& group_state, const GroupState<double>& group_state,
@@ -79,7 +82,7 @@ private:
const RateConvFunc& rateConverter, const RateConvFunc& rateConverter,
DeferredLogger& deferred_logger) const; 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; using RegionId = int;
class Schedule; class Schedule;
class SummaryState; class SummaryState;
class WellInterfaceGeneric; template<class Scalar> class WellInterfaceGeneric;
template<class Scalar> class WellState; template<class Scalar> class WellState;
//! \brief Class for computing well group controls. //! \brief Class for computing well group controls.
class WellGroupControls { class WellGroupControls {
public: public:
//! \brief Constructor sets reference to well. //! \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>&)>; 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; DeferredLogger& deferred_logger) const;
private: 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 Scalar> class WellState;
template<class FluidSystem> template<class FluidSystem>
class WellInterfaceFluidSystem : public WellInterfaceGeneric { class WellInterfaceFluidSystem : public WellInterfaceGeneric<double> {
protected: protected:
using RateConverterType = RateConverter:: using RateConverterType = RateConverter::
SurfaceToReservoirVoidage<FluidSystem, std::vector<int>>; SurfaceToReservoirVoidage<FluidSystem, std::vector<int>>;

View File

@@ -49,17 +49,18 @@
#include <cstddef> #include <cstddef>
#include <stdexcept> #include <stdexcept>
namespace Opm namespace Opm {
{
WellInterfaceGeneric::WellInterfaceGeneric(const Well& well, template<class Scalar>
const ParallelWellInfo& pw_info, WellInterfaceGeneric<Scalar>::
const int time_step, WellInterfaceGeneric(const Well& well,
const int pvtRegionIdx, const ParallelWellInfo& pw_info,
const int num_components, const int time_step,
const int num_phases, const int pvtRegionIdx,
const int index_of_well, const int num_components,
const std::vector<PerforationData>& perf_data) const int num_phases,
const int index_of_well,
const std::vector<PerforationData>& perf_data)
: well_ecl_(well) : well_ecl_(well)
, parallel_well_info_(pw_info) , parallel_well_info_(pw_info)
, current_step_(time_step) , 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 // 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 // for the gas rate to the methods in VFPProdProperties.cpp, we can extend
// the VFP calculations to the two-phase oil-water case. // 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(); const auto& pu = this->phaseUsage();
if (pu.num_phases == 2) { 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_; return *perf_data_;
} }
const std::string& WellInterfaceGeneric::name() const template<class Scalar>
const std::string&
WellInterfaceGeneric<Scalar>::name() const
{ {
return well_ecl_.name(); return well_ecl_.name();
} }
bool WellInterfaceGeneric::isInjector() const template<class Scalar>
bool WellInterfaceGeneric<Scalar>::isInjector() const
{ {
return well_ecl_.isInjector(); return well_ecl_.isInjector();
} }
bool WellInterfaceGeneric::isProducer() const template<class Scalar>
bool WellInterfaceGeneric<Scalar>::isProducer() const
{ {
return well_ecl_.isProducer(); return well_ecl_.isProducer();
} }
int WellInterfaceGeneric::indexOfWell() const template<class Scalar>
int WellInterfaceGeneric<Scalar>::indexOfWell() const
{ {
return index_of_well_; return index_of_well_;
} }
bool WellInterfaceGeneric::getAllowCrossFlow() const template<class Scalar>
bool WellInterfaceGeneric<Scalar>::getAllowCrossFlow() const
{ {
return well_ecl_.getAllowCrossFlow(); return well_ecl_.getAllowCrossFlow();
} }
const Well& WellInterfaceGeneric::wellEcl() const template<class Scalar>
const Well& WellInterfaceGeneric<Scalar>::wellEcl() const
{ {
return well_ecl_; return well_ecl_;
} }
Well& WellInterfaceGeneric::wellEcl() template<class Scalar>
Well& WellInterfaceGeneric<Scalar>::wellEcl()
{ {
return well_ecl_; return well_ecl_;
} }
const PhaseUsage& WellInterfaceGeneric::phaseUsage() const template<class Scalar>
const PhaseUsage& WellInterfaceGeneric<Scalar>::phaseUsage() const
{ {
assert(phase_usage_ != nullptr); assert(phase_usage_ != nullptr);
return *phase_usage_; return *phase_usage_;
} }
double WellInterfaceGeneric::wsolvent() const template<class Scalar>
Scalar WellInterfaceGeneric<Scalar>::wsolvent() const
{ {
return wsolvent_; return wsolvent_;
} }
double WellInterfaceGeneric::rsRvInj() const template<class Scalar>
Scalar WellInterfaceGeneric<Scalar>::rsRvInj() const
{ {
return well_ecl_.getInjectionProperties().rsRvInj; 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 // prev_inj_multiplier_ will stay unchanged during the time step
// while inj_multiplier_ might be updated during the time step // while inj_multiplier_ might be updated during the time step
this->prev_inj_multiplier_ = max_inj_mult; this->prev_inj_multiplier_ = max_inj_mult;
// initializing the inj_multipler_ to be 1.0 // 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()) { if (inj_multipliers.size() != this->inj_multiplier_.size()) {
OPM_DEFLOG_THROW(std::runtime_error, OPM_DEFLOG_THROW(std::runtime_error,
@@ -217,15 +238,15 @@ void WellInterfaceGeneric::updateInjMult(std::vector<double>& inj_multipliers, D
inj_multipliers = this->inj_multiplier_; inj_multipliers = this->inj_multiplier_;
} }
template<class Scalar>
Scalar WellInterfaceGeneric<Scalar>::
double WellInterfaceGeneric::getInjMult(const int perf, getInjMult(const int perf,
const double bhp, const Scalar bhp,
const double perf_pres) const const Scalar perf_pres) const
{ {
assert(!this->isProducer()); assert(!this->isProducer());
double multiplier = 1.; Scalar multiplier = 1.;
const auto perf_ecl_index = this->perforationData()[perf].ecl_index; const auto perf_ecl_index = this->perforationData()[perf].ecl_index;
const bool is_wrev = this->well_ecl_.getInjMultMode() == Well::InjMultMode::WREV; const bool is_wrev = this->well_ecl_.getInjMultMode() == Well::InjMultMode::WREV;
@@ -236,7 +257,7 @@ double WellInterfaceGeneric::getInjMult(const int perf,
if (active_injmult) { if (active_injmult) {
const auto& injmult= is_wrev ? this->well_ecl_.getWellInjMult() const auto& injmult= is_wrev ? this->well_ecl_.getWellInjMult()
: this->well_ecl_.getConnections()[perf_ecl_index].injmult(); : 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 frac_press = injmult.fracture_pressure;
const auto gradient = injmult.multiplier_gradient; const auto gradient = injmult.multiplier_gradient;
@@ -255,10 +276,9 @@ double WellInterfaceGeneric::getInjMult(const int perf,
return multiplier; return multiplier;
} }
template<class Scalar>
bool WellInterfaceGeneric<Scalar>::
wellHasTHPConstraints(const SummaryState& summaryState) const
bool WellInterfaceGeneric::wellHasTHPConstraints(const SummaryState& summaryState) const
{ {
// only wells under prediction mode can have THP constraint // only wells under prediction mode can have THP constraint
if (!this->wellEcl().predictionMode()) { if (!this->wellEcl().predictionMode()) {
@@ -272,11 +292,13 @@ bool WellInterfaceGeneric::wellHasTHPConstraints(const SummaryState& summaryStat
return WellBhpThpCalculator(*this).wellHasTHPConstraints(summaryState); return WellBhpThpCalculator(*this).wellHasTHPConstraints(summaryState);
} }
void WellInterfaceGeneric::updateWellTestState(const SingleWellState<double>& ws, template<class Scalar>
const double& simulationTime, void WellInterfaceGeneric<Scalar>::
const bool& writeMessageToOPMLog, updateWellTestState(const SingleWellState<Scalar>& ws,
WellTestState& wellTestState, const double& simulationTime,
DeferredLogger& deferred_logger) const const bool& writeMessageToOPMLog,
WellTestState& wellTestState,
DeferredLogger& deferred_logger) const
{ {
// updating well test state based on Economic limits for operable wells // updating well test state based on Economic limits for operable wells
if (this->isOperableAndSolvable()) { if (this->isOperableAndSolvable()) {
@@ -289,7 +311,9 @@ void WellInterfaceGeneric::updateWellTestState(const SingleWellState<double>& ws
// TODO: well can be shut/closed due to other reasons // 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_) { if (dynamic_thp_limit_) {
return *dynamic_thp_limit_; return *dynamic_thp_limit_;
@@ -298,12 +322,14 @@ double WellInterfaceGeneric::getTHPConstraint(const SummaryState& summaryState)
return WellBhpThpCalculator(*this).getTHPConstraint(summaryState); return WellBhpThpCalculator(*this).getTHPConstraint(summaryState);
} }
bool WellInterfaceGeneric::underPredictionMode() const template<class Scalar>
bool WellInterfaceGeneric<Scalar>::underPredictionMode() const
{ {
return well_ecl_.predictionMode(); return well_ecl_.predictionMode();
} }
void WellInterfaceGeneric::initCompletions() template<class Scalar>
void WellInterfaceGeneric<Scalar>::initCompletions()
{ {
assert(completions_.empty() ); assert(completions_.empty() );
@@ -330,7 +356,9 @@ void WellInterfaceGeneric::initCompletions()
assert(my_next_perf == perf_data_->end()); 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(); const auto& connections = well_ecl_.getConnections();
int perfIdx = 0; 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; vfp_properties_ = vfp_properties_arg;
} }
void WellInterfaceGeneric::setPrevSurfaceRates(WellState<double>& well_state, template<class Scalar>
const WellState<double>& prev_well_state) const void WellInterfaceGeneric<Scalar>::
{ setPrevSurfaceRates(WellState<Scalar>& well_state,
auto& ws = well_state.well(this->index_of_well_); const WellState<Scalar>& prev_well_state) const
auto& ws_prev = prev_well_state.well(this->index_of_well_); {
// The logic here is a bit fragile: auto& ws = well_state.well(this->index_of_well_);
// We need non-zero prev_surface_rates for the purpose of providing explicit fractions auto& ws_prev = prev_well_state.well(this->index_of_well_);
// (if needed) for vfp interpolation. // The logic here is a bit fragile:
// We assume that current surface rates either are initialized from previous step // We need non-zero prev_surface_rates for the purpose of providing explicit fractions
// or (if newly opened) from updateWellStateRates. This is fine unless well was // (if needed) for vfp interpolation.
// stopped in previous step in which case it's rates will be zero. In this case, // We assume that current surface rates either are initialized from previous step
// we select the previous rates of the previous well state (and hope for the best). // or (if newly opened) from updateWellStateRates. This is fine unless well was
const bool zero_rates = std::all_of(ws.surface_rates.begin(), ws.surface_rates.end(), // stopped in previous step in which case it's rates will be zero. In this case,
[](double rate) { // we select the previous rates of the previous well state (and hope for the best).
return rate == 0.; // TODO: should we use a threshhold for comparison? 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) { if (zero_rates) {
ws.prev_surface_rates = ws_prev.prev_surface_rates; ws.prev_surface_rates = ws_prev.prev_surface_rates;
} else { } else {
ws.prev_surface_rates = ws.surface_rates; 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; 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; well_efficiency_factor_ = efficiency_factor;
} }
void WellInterfaceGeneric::setRepRadiusPerfLength() template<class Scalar>
void WellInterfaceGeneric<Scalar>::setRepRadiusPerfLength()
{ {
const int nperf = number_of_perforations_; const int nperf = number_of_perforations_;
@@ -411,10 +448,10 @@ void WellInterfaceGeneric::setRepRadiusPerfLength()
assert(my_next_perf->ecl_index == c); assert(my_next_perf->ecl_index == c);
const auto& connection = connections[c]; const auto& connection = connections[c];
if (connection.state() == Connection::State::OPEN) { if (connection.state() == Connection::State::OPEN) {
double radius = connection.rw(); Scalar radius = connection.rw();
double re = connection.re(); // area equivalent radius of the grid block Scalar re = connection.re(); // area equivalent radius of the grid block
double perf_length = connection.connectionLength(); // the length of the well perforation Scalar perf_length = connection.connectionLength(); // the length of the well perforation
const double repR = std::sqrt(re * radius); const Scalar repR = std::sqrt(re * radius);
perf_rep_radius_.push_back(repR); perf_rep_radius_.push_back(repR);
perf_length_.push_back(perf_length); perf_length_.push_back(perf_length);
bore_diameters_.push_back(2. * radius); bore_diameters_.push_back(2. * radius);
@@ -426,30 +463,39 @@ void WellInterfaceGeneric::setRepRadiusPerfLength()
assert(num_active_connections == nperf); assert(num_active_connections == nperf);
} }
void WellInterfaceGeneric::setWsolvent(const double wsolvent) template<class Scalar>
void WellInterfaceGeneric<Scalar>::
setWsolvent(const Scalar wsolvent)
{ {
wsolvent_ = 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; 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_; 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; 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. // 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. // 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(); return operability_status_.isOperableAndSolvable();
} }
bool WellInterfaceGeneric::useVfpExplicit() const template<class Scalar>
bool WellInterfaceGeneric<Scalar>::useVfpExplicit() const
{ {
const auto& wvfpexp = well_ecl_.getWVFPEXP(); const auto& wvfpexp = well_ecl_.getWVFPEXP();
return (wvfpexp.explicit_lookup() || operability_status_.use_vfpexplicit); 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; 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. // no alq for injectors.
if (isInjector()) if (isInjector())
@@ -514,8 +565,10 @@ double WellInterfaceGeneric::getALQ(const WellState<double>& well_state) const
return well_state.getALQ(name()); return well_state.getALQ(name());
} }
void WellInterfaceGeneric::reportWellSwitching(const SingleWellState<double> &ws, template<class Scalar>
DeferredLogger& deferred_logger) const void WellInterfaceGeneric<Scalar>::
reportWellSwitching(const SingleWellState<Scalar> &ws,
DeferredLogger& deferred_logger) const
{ {
if (well_control_log_.empty()) if (well_control_log_.empty())
return; 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_); const auto& ws = well_state.well(this->index_of_well_);
if (this->isInjector()) { if (this->isInjector()) {
@@ -548,10 +603,10 @@ bool WellInterfaceGeneric::isPressureControlled(const WellState<double>& well_st
} }
} }
template<class Scalar>
bool WellInterfaceGeneric<Scalar>::
bool WellInterfaceGeneric::wellUnderZeroRateTarget(const SummaryState& summary_state, wellUnderZeroRateTarget(const SummaryState& summary_state,
const WellState<double>& well_state) const const WellState<Scalar>& well_state) const
{ {
if (this->isProducer()) { // producers if (this->isProducer()) { // producers
const auto prod_controls = this->well_ecl_.productionControls(summary_state); 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, template<class Scalar>
const WellState<double>& well_state) const bool WellInterfaceGeneric<Scalar>::
stopppedOrZeroRateTarget(const SummaryState& summary_state,
const WellState<Scalar>& well_state) const
{ {
return (this->wellIsStopped() || this->wellUnderZeroRateTarget(summary_state, well_state)); return (this->wellIsStopped() || this->wellUnderZeroRateTarget(summary_state, well_state));
} }
void WellInterfaceGeneric::resetWellOperability() template<class Scalar>
void WellInterfaceGeneric<Scalar>::resetWellOperability()
{ {
this->operability_status_.resetOperability(); this->operability_status_.resetOperability();
} }
double WellInterfaceGeneric::wmicrobes_() const template<class Scalar>
Scalar WellInterfaceGeneric<Scalar>::wmicrobes_() const
{ {
auto injectorType = this->well_ecl_.injectorType(); auto injectorType = this->well_ecl_.injectorType();
if (injectorType == InjectorType::WATER) { if (injectorType == InjectorType::WATER) {
WellMICPProperties microbes = this->well_ecl_.getMICPProperties(); 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; return microbial_injection_concentration;
} else { } else {
// Not a water injection well => no microbes. // 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(); 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(); 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(); auto injectorType = this->well_ecl_.injectorType();
if (injectorType == InjectorType::WATER) { if (injectorType == InjectorType::WATER) {
WellMICPProperties oxygen = this->well_ecl_.getMICPProperties(); 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; return oxygen_injection_concentration;
} else { } else {
// Not a water injection well => no oxygen. // 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(); auto injectorType = this->well_ecl_.injectorType();
if (injectorType == InjectorType::WATER) { if (injectorType == InjectorType::WATER) {
WellPolymerProperties polymer = this->well_ecl_.getPolymerProperties(); 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; return polymer_injection_concentration;
} else { } else {
// Not a water injection well => no polymer. // 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(); auto injectorType = this->well_ecl_.injectorType();
if (injectorType == InjectorType::WATER) { if (injectorType == InjectorType::WATER) {
WellMICPProperties urea = this->well_ecl_.getMICPProperties(); 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; return urea_injection_concentration;
} else { } else {
// Not a water injection well => no urea. // 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; 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; 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; return this->well_ecl_.getPolymerProperties().m_plymwinjtable;
} }
std::pair<bool,bool> WellInterfaceGeneric:: template<class Scalar>
computeWellPotentials(std::vector<double>& well_potentials, std::pair<bool,bool> WellInterfaceGeneric<Scalar>::
const WellState<double>& well_state) computeWellPotentials(std::vector<Scalar>& well_potentials,
const WellState<Scalar>& well_state)
{ {
const int np = this->number_of_phases_; const int np = this->number_of_phases_;
well_potentials.resize(np, 0.0); well_potentials.resize(np, 0.0);
@@ -711,8 +779,8 @@ computeWellPotentials(std::vector<double>& well_potentials,
if (!this->changed_to_open_this_step_ && if (!this->changed_to_open_this_step_ &&
(thp_controlled_well || bhp_controlled_well)) { (thp_controlled_well || bhp_controlled_well)) {
double total_rate = 0.0; Scalar total_rate = 0.0;
const double sign = this->isInjector() ? 1.0 : -1.0; const Scalar sign = this->isInjector() ? 1.0 : -1.0;
for (int phase = 0; phase < np; ++phase){ for (int phase = 0; phase < np; ++phase){
total_rate += sign * ws.surface_rates[phase]; total_rate += sign * ws.surface_rates[phase];
} }
@@ -730,13 +798,14 @@ computeWellPotentials(std::vector<double>& well_potentials,
return {compute_potential, bhp_controlled_well}; return {compute_potential, bhp_controlled_well};
} }
void WellInterfaceGeneric:: template<class Scalar>
checkNegativeWellPotentials(std::vector<double>& well_potentials, void WellInterfaceGeneric<Scalar>::
checkNegativeWellPotentials(std::vector<Scalar>& well_potentials,
const bool checkOperability, const bool checkOperability,
DeferredLogger& deferred_logger) DeferredLogger& deferred_logger)
{ {
const double sign = this->isInjector() ? 1.0 : -1.0; const Scalar sign = this->isInjector() ? 1.0 : -1.0;
double total_potential = 0.0; Scalar total_potential = 0.0;
for (int phase = 0; phase < this->number_of_phases_; ++phase) { for (int phase = 0; phase < this->number_of_phases_; ++phase) {
well_potentials[phase] *= sign; well_potentials[phase] *= sign;
total_potential += well_potentials[phase]; 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, prepareForPotentialCalculations(const SummaryState& summary_state,
WellState<double>& well_state, WellState<Scalar>& well_state,
Well::InjectionControls& inj_controls, Well::InjectionControls& inj_controls,
Well::ProductionControls& prod_controls) const Well::ProductionControls& prod_controls) const
{ {
@@ -793,4 +863,6 @@ prepareForPotentialCalculations(const SummaryState& summary_state,
} }
} }
template class WellInterfaceGeneric<double>;
} // namespace Opm } // namespace Opm

View File

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

View File

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