Merge pull request #5299 from akva2/blackoilwellmodel_template_scalar

BlackoilWellModel: template Scalar type
This commit is contained in:
Arne Morten Kvarving 2024-04-23 11:55:41 +02:00 committed by GitHub
commit 20949ea950
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 580 additions and 534 deletions

View File

@ -116,7 +116,7 @@ ActionHandler::ActionHandler(EclipseState& ecl_state,
Schedule& schedule, Schedule& schedule,
Action::State& actionState, Action::State& actionState,
SummaryState& summaryState, SummaryState& summaryState,
BlackoilWellModelGeneric& wellModel, BlackoilWellModelGeneric<double>& wellModel,
Parallel::Communication comm) Parallel::Communication comm)
: ecl_state_(ecl_state) : ecl_state_(ecl_state)
, schedule_(schedule) , schedule_(schedule)

View File

@ -38,7 +38,7 @@ class ActionX;
class State; class State;
} }
class BlackoilWellModelGeneric; template<class Scalar> class BlackoilWellModelGeneric;
class EclipseState; class EclipseState;
class Schedule; class Schedule;
struct SimulatorUpdate; struct SimulatorUpdate;
@ -56,7 +56,7 @@ public:
Schedule& schedule, Schedule& schedule,
Action::State& actionState, Action::State& actionState,
SummaryState& summaryState, SummaryState& summaryState,
BlackoilWellModelGeneric& wellModel, BlackoilWellModelGeneric<double>& wellModel,
Parallel::Communication comm); Parallel::Communication comm);
void applyActions(int reportStep, void applyActions(int reportStep,
@ -88,7 +88,7 @@ public:
Schedule& schedule_; Schedule& schedule_;
Action::State& actionState_; Action::State& actionState_;
SummaryState& summaryState_; SummaryState& summaryState_;
BlackoilWellModelGeneric& wellModel_; BlackoilWellModelGeneric<double>& wellModel_;
Parallel::Communication comm_; Parallel::Communication comm_;
}; };

View File

@ -92,7 +92,8 @@ namespace Opm {
/// Class for handling the blackoil well model. /// Class for handling the blackoil well model.
template<typename TypeTag> template<typename TypeTag>
class BlackoilWellModel : public BaseAuxiliaryModule<TypeTag> class BlackoilWellModel : public BaseAuxiliaryModule<TypeTag>
, public BlackoilWellModelGeneric , public BlackoilWellModelGeneric<GetPropType<TypeTag,
Properties::Scalar>>
{ {
public: public:
// --------- Types --------- // --------- Types ---------
@ -109,10 +110,10 @@ namespace Opm {
using GlobalEqVector = GetPropType<TypeTag, Properties::GlobalEqVector>; using GlobalEqVector = GetPropType<TypeTag, Properties::GlobalEqVector>;
using SparseMatrixAdapter = GetPropType<TypeTag, Properties::SparseMatrixAdapter>; using SparseMatrixAdapter = GetPropType<TypeTag, Properties::SparseMatrixAdapter>;
using GasLiftSingleWell = typename WellInterface<TypeTag>::GasLiftSingleWell; using GasLiftSingleWell = typename WellInterface<TypeTag>::GasLiftSingleWell;
using GLiftOptWells = typename BlackoilWellModelGeneric::GLiftOptWells; using GLiftOptWells = typename BlackoilWellModelGeneric<Scalar>::GLiftOptWells;
using GLiftProdWells = typename BlackoilWellModelGeneric::GLiftProdWells; using GLiftProdWells = typename BlackoilWellModelGeneric<Scalar>::GLiftProdWells;
using GLiftWellStateMap = using GLiftWellStateMap =
typename BlackoilWellModelGeneric::GLiftWellStateMap; typename BlackoilWellModelGeneric<Scalar>::GLiftWellStateMap;
using GLiftEclWells = typename GasLiftGroupInfo::GLiftEclWells; using GLiftEclWells = typename GasLiftGroupInfo::GLiftEclWells;
using GLiftSyncGroups = typename GasLiftSingleWellGeneric::GLiftSyncGroups; using GLiftSyncGroups = typename GasLiftSingleWellGeneric::GLiftSyncGroups;
constexpr static std::size_t pressureVarIndex = GetPropType<TypeTag, Properties::Indices>::pressureSwitchIdx; constexpr static std::size_t pressureVarIndex = GetPropType<TypeTag, Properties::Indices>::pressureSwitchIdx;
@ -234,7 +235,7 @@ namespace Opm {
using WellInterfacePtr = std::shared_ptr<WellInterface<TypeTag> >; using WellInterfacePtr = std::shared_ptr<WellInterface<TypeTag> >;
using BlackoilWellModelGeneric::initFromRestartFile; using BlackoilWellModelGeneric<Scalar>::initFromRestartFile;
void initFromRestartFile(const RestartValue& restartValues) void initFromRestartFile(const RestartValue& restartValues)
{ {
initFromRestartFile(restartValues, initFromRestartFile(restartValues,
@ -243,7 +244,7 @@ namespace Opm {
param_.use_multisegment_well_); param_.use_multisegment_well_);
} }
using BlackoilWellModelGeneric::prepareDeserialize; using BlackoilWellModelGeneric<Scalar>::prepareDeserialize;
void prepareDeserialize(const int report_step) void prepareDeserialize(const int report_step)
{ {
prepareDeserialize(report_step, grid().size(0), prepareDeserialize(report_step, grid().size(0),
@ -332,7 +333,7 @@ namespace Opm {
WellInterfacePtr getWell(const std::string& well_name) const; WellInterfacePtr getWell(const std::string& well_name) const;
bool hasWell(const std::string& well_name) const; bool hasWell(const std::string& well_name) const;
using PressureMatrix = Dune::BCRSMatrix<Opm::MatrixBlock<double, 1, 1>>; using PressureMatrix = Dune::BCRSMatrix<Opm::MatrixBlock<Scalar, 1, 1>>;
void addWellPressureEquations(PressureMatrix& jacobian, const BVector& weights,const bool use_well_weights) const; void addWellPressureEquations(PressureMatrix& jacobian, const BVector& weights,const bool use_well_weights) const;
@ -354,8 +355,8 @@ namespace Opm {
void updateWellControlsDomain(DeferredLogger& deferred_logger, const Domain& domain); void updateWellControlsDomain(DeferredLogger& deferred_logger, const Domain& domain);
void logPrimaryVars() const; void logPrimaryVars() const;
std::vector<double> getPrimaryVarsDomain(const Domain& domain) const; std::vector<Scalar> getPrimaryVarsDomain(const Domain& domain) const;
void setPrimaryVarsDomain(const Domain& domain, const std::vector<double>& vars); void setPrimaryVarsDomain(const Domain& domain, const std::vector<Scalar>& vars);
void setupDomains(const std::vector<Domain>& domains); void setupDomains(const std::vector<Domain>& domains);
@ -388,8 +389,8 @@ namespace Opm {
std::size_t global_num_cells_{}; std::size_t global_num_cells_{};
// the number of the cells in the local grid // the number of the cells in the local grid
std::size_t local_num_cells_{}; std::size_t local_num_cells_{};
double gravity_{}; Scalar gravity_{};
std::vector<double> depth_{}; std::vector<Scalar> depth_{};
bool alternative_well_rate_init_{}; bool alternative_well_rate_init_{};
std::unique_ptr<RateConverterType> rateConverter_{}; std::unique_ptr<RateConverterType> rateConverter_{};
@ -494,7 +495,7 @@ namespace Opm {
ExceptionType::ExcEnum& exc_type, ExceptionType::ExcEnum& exc_type,
DeferredLogger& deferred_logger) override; DeferredLogger& deferred_logger) override;
const std::vector<double>& wellPerfEfficiencyFactors() const; const std::vector<Scalar>& wellPerfEfficiencyFactors() const;
void calculateProductivityIndexValuesShutWells(const int reportStepIdx, DeferredLogger& deferred_logger) override; void calculateProductivityIndexValuesShutWells(const int reportStepIdx, DeferredLogger& deferred_logger) override;
void calculateProductivityIndexValues(DeferredLogger& deferred_logger) override; void calculateProductivityIndexValues(DeferredLogger& deferred_logger) override;
@ -538,12 +539,12 @@ namespace Opm {
void calcRates(const int fipnum, void calcRates(const int fipnum,
const int pvtreg, const int pvtreg,
const std::vector<double>& production_rates, const std::vector<Scalar>& production_rates,
std::vector<double>& resv_coeff) override; std::vector<Scalar>& resv_coeff) override;
void calcInjRates(const int fipnum, void calcInjRates(const int fipnum,
const int pvtreg, const int pvtreg,
std::vector<double>& resv_coeff) override; std::vector<Scalar>& resv_coeff) override;
void computeWellTemperature(); void computeWellTemperature();

View File

@ -37,7 +37,8 @@
namespace Opm { namespace Opm {
bool BlackoilWellModelConstraints:: template<class Scalar>
bool BlackoilWellModelConstraints<Scalar>::
hasTHPConstraints() const hasTHPConstraints() const
{ {
int local_result = false; int local_result = false;
@ -49,8 +50,9 @@ hasTHPConstraints() const
return wellModel_.comm().max(local_result); return wellModel_.comm().max(local_result);
} }
std::pair<Group::InjectionCMode, double> template<class Scalar>
BlackoilWellModelConstraints:: std::pair<Group::InjectionCMode, Scalar>
BlackoilWellModelConstraints<Scalar>::
checkGroupInjectionConstraints(const Group& group, checkGroupInjectionConstraints(const Group& group,
const int reportStepIdx, const int reportStepIdx,
const Phase& phase) const const Phase& phase) const
@ -73,8 +75,8 @@ checkGroupInjectionConstraints(const Group& group,
{ {
if (currentControl != Group::InjectionCMode::RATE) if (currentControl != Group::InjectionCMode::RATE)
{ {
double current_rate = 0.0; Scalar current_rate = 0.0;
current_rate += WellGroupHelpers<double>::sumWellSurfaceRates(group, current_rate += WellGroupHelpers<Scalar>::sumWellSurfaceRates(group,
wellModel_.schedule(), wellModel_.schedule(),
well_state, well_state,
reportStepIdx, reportStepIdx,
@ -85,13 +87,13 @@ checkGroupInjectionConstraints(const Group& group,
current_rate = wellModel_.comm().sum(current_rate); current_rate = wellModel_.comm().sum(current_rate);
const auto& controls = group.injectionControls(phase, wellModel_.summaryState()); const auto& controls = group.injectionControls(phase, wellModel_.summaryState());
double target = controls.surface_max_rate; Scalar target = controls.surface_max_rate;
if (group.has_gpmaint_control(phase, Group::InjectionCMode::RATE)) if (group.has_gpmaint_control(phase, Group::InjectionCMode::RATE))
target = wellModel_.groupState().gpmaint_target(group.name()); target = wellModel_.groupState().gpmaint_target(group.name());
if (target < current_rate) { if (target < current_rate) {
double scale = 1.0; Scalar scale = 1.0;
if (current_rate > 1e-12) if (current_rate > 1e-12)
scale = target / current_rate; scale = target / current_rate;
return std::make_pair(Group::InjectionCMode::RATE, scale); return std::make_pair(Group::InjectionCMode::RATE, scale);
@ -102,8 +104,8 @@ checkGroupInjectionConstraints(const Group& group,
{ {
if (currentControl != Group::InjectionCMode::RESV) if (currentControl != Group::InjectionCMode::RESV)
{ {
double current_rate = 0.0; Scalar current_rate = 0.0;
current_rate += WellGroupHelpers<double>::sumWellResRates(group, current_rate += WellGroupHelpers<Scalar>::sumWellResRates(group,
wellModel_.schedule(), wellModel_.schedule(),
well_state, well_state,
reportStepIdx, reportStepIdx,
@ -113,13 +115,13 @@ checkGroupInjectionConstraints(const Group& group,
current_rate = wellModel_.comm().sum(current_rate); current_rate = wellModel_.comm().sum(current_rate);
const auto& controls = group.injectionControls(phase, wellModel_.summaryState()); const auto& controls = group.injectionControls(phase, wellModel_.summaryState());
double target = controls.resv_max_rate; Scalar target = controls.resv_max_rate;
if (group.has_gpmaint_control(phase, Group::InjectionCMode::RESV)) if (group.has_gpmaint_control(phase, Group::InjectionCMode::RESV))
target = wellModel_.groupState().gpmaint_target(group.name()); target = wellModel_.groupState().gpmaint_target(group.name());
if (target < current_rate) { if (target < current_rate) {
double scale = 1.0; Scalar scale = 1.0;
if (current_rate > 1e-12) if (current_rate > 1e-12)
scale = target / current_rate; scale = target / current_rate;
return std::make_pair(Group::InjectionCMode::RESV, scale); return std::make_pair(Group::InjectionCMode::RESV, scale);
@ -130,10 +132,10 @@ checkGroupInjectionConstraints(const Group& group,
{ {
if (currentControl != Group::InjectionCMode::REIN) if (currentControl != Group::InjectionCMode::REIN)
{ {
double production_Rate = 0.0; Scalar production_Rate = 0.0;
const auto& controls = group.injectionControls(phase, wellModel_.summaryState()); const auto& controls = group.injectionControls(phase, wellModel_.summaryState());
const Group& groupRein = wellModel_.schedule().getGroup(controls.reinj_group, reportStepIdx); const Group& groupRein = wellModel_.schedule().getGroup(controls.reinj_group, reportStepIdx);
production_Rate += WellGroupHelpers<double>::sumWellSurfaceRates(groupRein, production_Rate += WellGroupHelpers<Scalar>::sumWellSurfaceRates(groupRein,
wellModel_.schedule(), wellModel_.schedule(),
well_state, well_state,
reportStepIdx, reportStepIdx,
@ -143,8 +145,8 @@ checkGroupInjectionConstraints(const Group& group,
// sum over all nodes // sum over all nodes
production_Rate = wellModel_.comm().sum(production_Rate); production_Rate = wellModel_.comm().sum(production_Rate);
double current_rate = 0.0; Scalar current_rate = 0.0;
current_rate += WellGroupHelpers<double>::sumWellSurfaceRates(group, current_rate += WellGroupHelpers<Scalar>::sumWellSurfaceRates(group,
wellModel_.schedule(), wellModel_.schedule(),
well_state, well_state,
reportStepIdx, reportStepIdx,
@ -155,7 +157,7 @@ checkGroupInjectionConstraints(const Group& group,
current_rate = wellModel_.comm().sum(current_rate); current_rate = wellModel_.comm().sum(current_rate);
if (controls.target_reinj_fraction*production_Rate < current_rate) { if (controls.target_reinj_fraction*production_Rate < current_rate) {
double scale = 1.0; Scalar scale = 1.0;
if (current_rate > 1e-12) if (current_rate > 1e-12)
scale = controls.target_reinj_fraction*production_Rate / current_rate; scale = controls.target_reinj_fraction*production_Rate / current_rate;
return std::make_pair(Group::InjectionCMode::REIN, scale); return std::make_pair(Group::InjectionCMode::REIN, scale);
@ -166,22 +168,22 @@ checkGroupInjectionConstraints(const Group& group,
{ {
if (currentControl != Group::InjectionCMode::VREP) if (currentControl != Group::InjectionCMode::VREP)
{ {
double voidage_rate = 0.0; Scalar voidage_rate = 0.0;
const auto& controls = group.injectionControls(phase, wellModel_.summaryState()); const auto& controls = group.injectionControls(phase, wellModel_.summaryState());
const Group& groupVoidage = wellModel_.schedule().getGroup(controls.voidage_group, reportStepIdx); const Group& groupVoidage = wellModel_.schedule().getGroup(controls.voidage_group, reportStepIdx);
voidage_rate += WellGroupHelpers<double>::sumWellResRates(groupVoidage, voidage_rate += WellGroupHelpers<Scalar>::sumWellResRates(groupVoidage,
wellModel_.schedule(), wellModel_.schedule(),
well_state, well_state,
reportStepIdx, reportStepIdx,
pu.phase_pos[BlackoilPhases::Aqua], pu.phase_pos[BlackoilPhases::Aqua],
false); false);
voidage_rate += WellGroupHelpers<double>::sumWellResRates(groupVoidage, voidage_rate += WellGroupHelpers<Scalar>::sumWellResRates(groupVoidage,
wellModel_.schedule(), wellModel_.schedule(),
well_state, well_state,
reportStepIdx, reportStepIdx,
pu.phase_pos[BlackoilPhases::Liquid], pu.phase_pos[BlackoilPhases::Liquid],
false); false);
voidage_rate += WellGroupHelpers<double>::sumWellResRates(groupVoidage, voidage_rate += WellGroupHelpers<Scalar>::sumWellResRates(groupVoidage,
wellModel_.schedule(), wellModel_.schedule(),
well_state, reportStepIdx, well_state, reportStepIdx,
pu.phase_pos[BlackoilPhases::Vapour], pu.phase_pos[BlackoilPhases::Vapour],
@ -190,20 +192,20 @@ checkGroupInjectionConstraints(const Group& group,
// sum over all nodes // sum over all nodes
voidage_rate = wellModel_.comm().sum(voidage_rate); voidage_rate = wellModel_.comm().sum(voidage_rate);
double total_rate = 0.0; Scalar total_rate = 0.0;
total_rate += WellGroupHelpers<double>::sumWellResRates(group, total_rate += WellGroupHelpers<Scalar>::sumWellResRates(group,
wellModel_.schedule(), wellModel_.schedule(),
well_state, well_state,
reportStepIdx, reportStepIdx,
pu.phase_pos[BlackoilPhases::Aqua], pu.phase_pos[BlackoilPhases::Aqua],
true); true);
total_rate += WellGroupHelpers<double>::sumWellResRates(group, total_rate += WellGroupHelpers<Scalar>::sumWellResRates(group,
wellModel_.schedule(), wellModel_.schedule(),
well_state, well_state,
reportStepIdx, reportStepIdx,
pu.phase_pos[BlackoilPhases::Liquid], pu.phase_pos[BlackoilPhases::Liquid],
true); true);
total_rate += WellGroupHelpers<double>::sumWellResRates(group, total_rate += WellGroupHelpers<Scalar>::sumWellResRates(group,
wellModel_.schedule(), wellModel_.schedule(),
well_state, well_state,
reportStepIdx, reportStepIdx,
@ -214,7 +216,7 @@ checkGroupInjectionConstraints(const Group& group,
total_rate = wellModel_.comm().sum(total_rate); total_rate = wellModel_.comm().sum(total_rate);
if (controls.target_void_fraction*voidage_rate < total_rate) { if (controls.target_void_fraction*voidage_rate < total_rate) {
double scale = 1.0; Scalar scale = 1.0;
if (total_rate > 1e-12) if (total_rate > 1e-12)
scale = controls.target_void_fraction*voidage_rate / total_rate; scale = controls.target_void_fraction*voidage_rate / total_rate;
return std::make_pair(Group::InjectionCMode::VREP, scale); return std::make_pair(Group::InjectionCMode::VREP, scale);
@ -224,8 +226,9 @@ checkGroupInjectionConstraints(const Group& group,
return std::make_pair(Group::InjectionCMode::NONE, 1.0); return std::make_pair(Group::InjectionCMode::NONE, 1.0);
} }
std::pair<Group::ProductionCMode, double> template<class Scalar>
BlackoilWellModelConstraints:: std::pair<Group::ProductionCMode, Scalar>
BlackoilWellModelConstraints<Scalar>::
checkGroupProductionConstraints(const Group& group, checkGroupProductionConstraints(const Group& group,
const int reportStepIdx, const int reportStepIdx,
DeferredLogger& deferred_logger) const DeferredLogger& deferred_logger) const
@ -240,8 +243,8 @@ checkGroupProductionConstraints(const Group& group,
{ {
if (currentControl != Group::ProductionCMode::ORAT) if (currentControl != Group::ProductionCMode::ORAT)
{ {
double current_rate = 0.0; Scalar current_rate = 0.0;
current_rate += WellGroupHelpers<double>::sumWellSurfaceRates(group, current_rate += WellGroupHelpers<Scalar>::sumWellSurfaceRates(group,
wellModel_.schedule(), wellModel_.schedule(),
well_state, well_state,
reportStepIdx, reportStepIdx,
@ -252,7 +255,7 @@ checkGroupProductionConstraints(const Group& group,
current_rate = wellModel_.comm().sum(current_rate); current_rate = wellModel_.comm().sum(current_rate);
if (controls.oil_target < current_rate ) { if (controls.oil_target < current_rate ) {
double scale = 1.0; Scalar scale = 1.0;
if (current_rate > 1e-12) if (current_rate > 1e-12)
scale = controls.oil_target / current_rate; scale = controls.oil_target / current_rate;
return std::make_pair(Group::ProductionCMode::ORAT, scale); return std::make_pair(Group::ProductionCMode::ORAT, scale);
@ -264,8 +267,8 @@ checkGroupProductionConstraints(const Group& group,
{ {
if (currentControl != Group::ProductionCMode::WRAT) if (currentControl != Group::ProductionCMode::WRAT)
{ {
double current_rate = 0.0; Scalar current_rate = 0.0;
current_rate += WellGroupHelpers<double>::sumWellSurfaceRates(group, current_rate += WellGroupHelpers<Scalar>::sumWellSurfaceRates(group,
wellModel_.schedule(), wellModel_.schedule(),
well_state, well_state,
reportStepIdx, reportStepIdx,
@ -276,7 +279,7 @@ checkGroupProductionConstraints(const Group& group,
current_rate = wellModel_.comm().sum(current_rate); current_rate = wellModel_.comm().sum(current_rate);
if (controls.water_target < current_rate ) { if (controls.water_target < current_rate ) {
double scale = 1.0; Scalar scale = 1.0;
if (current_rate > 1e-12) if (current_rate > 1e-12)
scale = controls.water_target / current_rate; scale = controls.water_target / current_rate;
return std::make_pair(Group::ProductionCMode::WRAT, scale); return std::make_pair(Group::ProductionCMode::WRAT, scale);
@ -287,8 +290,8 @@ checkGroupProductionConstraints(const Group& group,
{ {
if (currentControl != Group::ProductionCMode::GRAT) if (currentControl != Group::ProductionCMode::GRAT)
{ {
double current_rate = 0.0; Scalar current_rate = 0.0;
current_rate += WellGroupHelpers<double>::sumWellSurfaceRates(group, current_rate += WellGroupHelpers<Scalar>::sumWellSurfaceRates(group,
wellModel_.schedule(), wellModel_.schedule(),
well_state, well_state,
reportStepIdx, reportStepIdx,
@ -298,7 +301,7 @@ checkGroupProductionConstraints(const Group& group,
// sum over all nodes // sum over all nodes
current_rate = wellModel_.comm().sum(current_rate); current_rate = wellModel_.comm().sum(current_rate);
if (controls.gas_target < current_rate ) { if (controls.gas_target < current_rate ) {
double scale = 1.0; Scalar scale = 1.0;
if (current_rate > 1e-12) if (current_rate > 1e-12)
scale = controls.gas_target / current_rate; scale = controls.gas_target / current_rate;
return std::make_pair(Group::ProductionCMode::GRAT, scale); return std::make_pair(Group::ProductionCMode::GRAT, scale);
@ -309,14 +312,14 @@ checkGroupProductionConstraints(const Group& group,
{ {
if (currentControl != Group::ProductionCMode::LRAT) if (currentControl != Group::ProductionCMode::LRAT)
{ {
double current_rate = 0.0; Scalar current_rate = 0.0;
current_rate += WellGroupHelpers<double>::sumWellSurfaceRates(group, current_rate += WellGroupHelpers<Scalar>::sumWellSurfaceRates(group,
wellModel_.schedule(), wellModel_.schedule(),
well_state, well_state,
reportStepIdx, reportStepIdx,
pu.phase_pos[BlackoilPhases::Liquid], pu.phase_pos[BlackoilPhases::Liquid],
false); false);
current_rate += WellGroupHelpers<double>::sumWellSurfaceRates(group, current_rate += WellGroupHelpers<Scalar>::sumWellSurfaceRates(group,
wellModel_.schedule(), wellModel_.schedule(),
well_state, well_state,
reportStepIdx, reportStepIdx,
@ -328,7 +331,7 @@ checkGroupProductionConstraints(const Group& group,
bool skip = false; bool skip = false;
if (controls.liquid_target == controls.oil_target) { if (controls.liquid_target == controls.oil_target) {
double current_water_rate = WellGroupHelpers<double>::sumWellSurfaceRates(group, Scalar current_water_rate = WellGroupHelpers<Scalar>::sumWellSurfaceRates(group,
wellModel_.schedule(), wellModel_.schedule(),
well_state, well_state,
reportStepIdx, reportStepIdx,
@ -342,7 +345,7 @@ checkGroupProductionConstraints(const Group& group,
} }
if (!skip && controls.liquid_target < current_rate ) { if (!skip && controls.liquid_target < current_rate ) {
double scale = 1.0; Scalar scale = 1.0;
if (current_rate > 1e-12) if (current_rate > 1e-12)
scale = controls.liquid_target / current_rate; scale = controls.liquid_target / current_rate;
return std::make_pair(Group::ProductionCMode::LRAT, scale); return std::make_pair(Group::ProductionCMode::LRAT, scale);
@ -358,20 +361,20 @@ checkGroupProductionConstraints(const Group& group,
{ {
if (currentControl != Group::ProductionCMode::RESV) if (currentControl != Group::ProductionCMode::RESV)
{ {
double current_rate = 0.0; Scalar current_rate = 0.0;
current_rate += WellGroupHelpers<double>::sumWellResRates(group, current_rate += WellGroupHelpers<Scalar>::sumWellResRates(group,
wellModel_.schedule(), wellModel_.schedule(),
well_state, well_state,
reportStepIdx, reportStepIdx,
pu.phase_pos[BlackoilPhases::Aqua], pu.phase_pos[BlackoilPhases::Aqua],
false); false);
current_rate += WellGroupHelpers<double>::sumWellResRates(group, current_rate += WellGroupHelpers<Scalar>::sumWellResRates(group,
wellModel_.schedule(), wellModel_.schedule(),
well_state, well_state,
reportStepIdx, reportStepIdx,
pu.phase_pos[BlackoilPhases::Liquid], pu.phase_pos[BlackoilPhases::Liquid],
false); false);
current_rate += WellGroupHelpers<double>::sumWellResRates(group, current_rate += WellGroupHelpers<Scalar>::sumWellResRates(group,
wellModel_.schedule(), wellModel_.schedule(),
well_state, well_state,
reportStepIdx, reportStepIdx,
@ -381,12 +384,12 @@ checkGroupProductionConstraints(const Group& group,
// sum over all nodes // sum over all nodes
current_rate = wellModel_.comm().sum(current_rate); current_rate = wellModel_.comm().sum(current_rate);
double target = controls.resv_target; Scalar target = controls.resv_target;
if (group.has_gpmaint_control(Group::ProductionCMode::RESV)) if (group.has_gpmaint_control(Group::ProductionCMode::RESV))
target = wellModel_.groupState().gpmaint_target(group.name()); target = wellModel_.groupState().gpmaint_target(group.name());
if ( target < current_rate ) { if ( target < current_rate ) {
double scale = 1.0; Scalar scale = 1.0;
if (current_rate > 1e-12) if (current_rate > 1e-12)
scale = target / current_rate; scale = target / current_rate;
return std::make_pair(Group::ProductionCMode::RESV, scale); return std::make_pair(Group::ProductionCMode::RESV, scale);
@ -397,10 +400,11 @@ checkGroupProductionConstraints(const Group& group,
{ {
OPM_DEFLOG_THROW(std::runtime_error, "Group " + group.name() + "PRBL control for production groups not implemented", deferred_logger); OPM_DEFLOG_THROW(std::runtime_error, "Group " + group.name() + "PRBL control for production groups not implemented", deferred_logger);
} }
return std::make_pair(Group::ProductionCMode::NONE, 1.0); return std::make_pair(Group::ProductionCMode::NONE, Scalar(1.0));
} }
bool BlackoilWellModelConstraints:: template<class Scalar>
bool BlackoilWellModelConstraints<Scalar>::
checkGroupConstraints(const Group& group, checkGroupConstraints(const Group& group,
const int reportStepIdx, const int reportStepIdx,
DeferredLogger& deferred_logger) const DeferredLogger& deferred_logger) const
@ -437,11 +441,12 @@ checkGroupConstraints(const Group& group,
return violated; return violated;
} }
void BlackoilWellModelConstraints:: template<class Scalar>
void BlackoilWellModelConstraints<Scalar>::
actionOnBrokenConstraints(const Group& group, actionOnBrokenConstraints(const Group& group,
const Group::InjectionCMode& newControl, const Group::InjectionCMode& newControl,
const Phase& controlPhase, const Phase& controlPhase,
GroupState<double>& group_state, GroupState<Scalar>& group_state,
DeferredLogger& deferred_logger) const DeferredLogger& deferred_logger) const
{ {
auto oldControl = wellModel_.groupState().injection_control(group.name(), controlPhase); auto oldControl = wellModel_.groupState().injection_control(group.name(), controlPhase);
@ -459,14 +464,15 @@ actionOnBrokenConstraints(const Group& group,
} }
} }
bool BlackoilWellModelConstraints:: template<class Scalar>
bool BlackoilWellModelConstraints<Scalar>::
actionOnBrokenConstraints(const Group& group, actionOnBrokenConstraints(const Group& group,
const int reportStepIdx, const int reportStepIdx,
const Group::GroupLimitAction group_limit_action, const Group::GroupLimitAction group_limit_action,
const Group::ProductionCMode& newControl, const Group::ProductionCMode& newControl,
const WellState<double>& well_state, const WellState<Scalar>& well_state,
std::optional<std::string>& worst_offending_well, std::optional<std::string>& worst_offending_well,
GroupState<double>& group_state, GroupState<Scalar>& group_state,
DeferredLogger& deferred_logger) const DeferredLogger& deferred_logger) const
{ {
@ -475,7 +481,7 @@ actionOnBrokenConstraints(const Group& group,
wellModel_.groupState().production_control(group.name()); wellModel_.groupState().production_control(group.name());
std::string ss; std::string ss;
switch(group_limit_action.allRates) { switch (group_limit_action.allRates) {
case Group::ExceedAction::NONE: { case Group::ExceedAction::NONE: {
if (oldControl != newControl && oldControl != Group::ProductionCMode::NONE) { if (oldControl != newControl && oldControl != Group::ProductionCMode::NONE) {
if ((group_limit_action.water == Group::ExceedAction::RATE && if ((group_limit_action.water == Group::ExceedAction::RATE &&
@ -517,7 +523,7 @@ actionOnBrokenConstraints(const Group& group,
} }
case Group::ExceedAction::WELL: { case Group::ExceedAction::WELL: {
std::tie(worst_offending_well, std::ignore) = std::tie(worst_offending_well, std::ignore) =
WellGroupHelpers<double>::worstOffendingWell(group, wellModel_.schedule(), reportStepIdx, WellGroupHelpers<Scalar>::worstOffendingWell(group, wellModel_.schedule(), reportStepIdx,
newControl, wellModel_.phaseUsage(), newControl, wellModel_.phaseUsage(),
wellModel_.comm(), well_state, deferred_logger); wellModel_.comm(), well_state, deferred_logger);
break; break;
@ -551,14 +557,15 @@ actionOnBrokenConstraints(const Group& group,
return changed; return changed;
} }
bool BlackoilWellModelConstraints:: template<class Scalar>
bool BlackoilWellModelConstraints<Scalar>::
updateGroupIndividualControl(const Group& group, updateGroupIndividualControl(const Group& group,
const int reportStepIdx, const int reportStepIdx,
std::map<std::pair<std::string,Opm::Phase>,std::string>& switched_inj, std::map<std::pair<std::string,Phase>,std::string>& switched_inj,
std::map<std::string, std::string>& switched_prod, std::map<std::string, std::string>& switched_prod,
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,
GroupState<double>& group_state, GroupState<Scalar>& group_state,
WellState<double>& well_state, WellState<Scalar>& well_state,
DeferredLogger& deferred_logger) const DeferredLogger& deferred_logger) const
{ {
bool changed = false; bool changed = false;
@ -578,7 +585,7 @@ updateGroupIndividualControl(const Group& group,
Group::InjectionCMode2String(changed_this.first)); Group::InjectionCMode2String(changed_this.first));
this->actionOnBrokenConstraints(group, changed_this.first, phase, this->actionOnBrokenConstraints(group, changed_this.first, phase,
group_state, deferred_logger); group_state, deferred_logger);
WellGroupHelpers<double>::updateWellRatesFromGroupTargetScale(changed_this.second, WellGroupHelpers<Scalar>::updateWellRatesFromGroupTargetScale(changed_this.second,
group, group,
wellModel_.schedule(), wellModel_.schedule(),
reportStepIdx, reportStepIdx,
@ -607,7 +614,7 @@ updateGroupIndividualControl(const Group& group,
if(changed) { if(changed) {
switched_prod.insert_or_assign(group.name(), switched_prod.insert_or_assign(group.name(),
Group::ProductionCMode2String(changed_this.first)); Group::ProductionCMode2String(changed_this.first));
WellGroupHelpers<double>::updateWellRatesFromGroupTargetScale(changed_this.second, WellGroupHelpers<Scalar>::updateWellRatesFromGroupTargetScale(changed_this.second,
group, group,
wellModel_.schedule(), wellModel_.schedule(),
reportStepIdx, reportStepIdx,
@ -624,4 +631,6 @@ updateGroupIndividualControl(const Group& group,
return changed; return changed;
} }
template class BlackoilWellModelConstraints<double>;
} }

View File

@ -29,18 +29,19 @@
namespace Opm { namespace Opm {
class BlackoilWellModelGeneric; template<class Scalar> class BlackoilWellModelGeneric;
class DeferredLogger; class DeferredLogger;
template<class Scalar> class GroupState; template<class Scalar> class GroupState;
class SummaryState; class SummaryState;
template<class Scalar> class WellState; template<class Scalar> class WellState;
/// Class for handling constraints for the blackoil well model. /// Class for handling constraints for the blackoil well model.
template<class Scalar>
class BlackoilWellModelConstraints class BlackoilWellModelConstraints
{ {
public: public:
//! \brief Constructor initializes reference to the well model. //! \brief Constructor initializes reference to the well model.
BlackoilWellModelConstraints(const BlackoilWellModelGeneric& wellModel) BlackoilWellModelConstraints(const BlackoilWellModelGeneric<Scalar>& wellModel)
: wellModel_(wellModel) : wellModel_(wellModel)
{} {}
@ -56,7 +57,7 @@ public:
void actionOnBrokenConstraints(const Group& group, void actionOnBrokenConstraints(const Group& group,
const Group::InjectionCMode& newControl, const Group::InjectionCMode& newControl,
const Phase& controlPhase, const Phase& controlPhase,
GroupState<double>& group_state, GroupState<Scalar>& group_state,
DeferredLogger& deferred_logger) const; DeferredLogger& deferred_logger) const;
//! \brief Execute action on broken constraint for a production well group. Return true if a group control is changed //! \brief Execute action on broken constraint for a production well group. Return true if a group control is changed
@ -64,35 +65,35 @@ public:
const int reportStepIdx, const int reportStepIdx,
const Group::GroupLimitAction group_limit_action, const Group::GroupLimitAction group_limit_action,
const Group::ProductionCMode& newControl, const Group::ProductionCMode& newControl,
const WellState<double>& well_state, const WellState<Scalar>& well_state,
std::optional<std::string>& worst_offending_well, std::optional<std::string>& worst_offending_well,
GroupState<double>& group_state, GroupState<Scalar>& group_state,
DeferredLogger& deferred_logger) const; DeferredLogger& deferred_logger) const;
//! \brief Update the individual controls for wells in a group. Return true if a group control is changed //! \brief Update the individual controls for wells in a group. Return true if a group control is changed
bool updateGroupIndividualControl(const Group& group, bool updateGroupIndividualControl(const Group& group,
const int reportStepIdx, const int reportStepIdx,
std::map<std::pair<std::string,Opm::Phase>,std::string>& switched_inj, std::map<std::pair<std::string,Phase>,std::string>& switched_inj,
std::map<std::string, std::string>& switched_prod, std::map<std::string, std::string>& switched_prod,
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,
GroupState<double>& group_state, GroupState<Scalar>& group_state,
WellState<double>& well_state, WellState<Scalar>& well_state,
DeferredLogger& deferred_logger) const; DeferredLogger& deferred_logger) const;
private: private:
//! \brief Check and return value and type of constraints for an injection well group. //! \brief Check and return value and type of constraints for an injection well group.
std::pair<Group::InjectionCMode, double> std::pair<Group::InjectionCMode, Scalar>
checkGroupInjectionConstraints(const Group& group, checkGroupInjectionConstraints(const Group& group,
const int reportStepIdx, const int reportStepIdx,
const Phase& phase) const; const Phase& phase) const;
//! \brief Check and return value and type of constraints for a production well group. //! \brief Check and return value and type of constraints for a production well group.
std::pair<Group::ProductionCMode, double> std::pair<Group::ProductionCMode, Scalar>
checkGroupProductionConstraints(const Group& group, checkGroupProductionConstraints(const Group& group,
const int reportStepIdx, const int reportStepIdx,
DeferredLogger& deferred_logger) const; DeferredLogger& deferred_logger) const;
const BlackoilWellModelGeneric& wellModel_; //!< Reference to well model const BlackoilWellModelGeneric<Scalar>& wellModel_; //!< Reference to well model
}; };
} // namespace Opm } // namespace Opm

View File

@ -76,7 +76,8 @@
namespace Opm { namespace Opm {
BlackoilWellModelGeneric:: template<class Scalar>
BlackoilWellModelGeneric<Scalar>::
BlackoilWellModelGeneric(Schedule& schedule, BlackoilWellModelGeneric(Schedule& schedule,
const SummaryState& summaryState, const SummaryState& summaryState,
const EclipseState& eclState, const EclipseState& eclState,
@ -115,22 +116,22 @@ BlackoilWellModelGeneric(Schedule& schedule,
} }
} }
int template<class Scalar>
BlackoilWellModelGeneric:: int BlackoilWellModelGeneric<Scalar>::
numLocalWells() const numLocalWells() const
{ {
return wells_ecl_.size(); return wells_ecl_.size();
} }
int template<class Scalar>
BlackoilWellModelGeneric:: int BlackoilWellModelGeneric<Scalar>::
numPhases() const numPhases() const
{ {
return phase_usage_.num_phases; return phase_usage_.num_phases;
} }
bool template<class Scalar>
BlackoilWellModelGeneric:: bool BlackoilWellModelGeneric<Scalar>::
hasWell(const std::string& wname) const hasWell(const std::string& wname) const
{ {
return std::any_of(this->wells_ecl_.begin(), this->wells_ecl_.end(), return std::any_of(this->wells_ecl_.begin(), this->wells_ecl_.end(),
@ -140,22 +141,22 @@ hasWell(const std::string& wname) const
}); });
} }
bool template<class Scalar>
BlackoilWellModelGeneric:: bool BlackoilWellModelGeneric<Scalar>::
wellsActive() const wellsActive() const
{ {
return wells_active_; return wells_active_;
} }
bool template<class Scalar>
BlackoilWellModelGeneric:: bool BlackoilWellModelGeneric<Scalar>::
networkActive() const networkActive() const
{ {
return network_active_; return network_active_;
} }
bool template<class Scalar>
BlackoilWellModelGeneric:: bool BlackoilWellModelGeneric<Scalar>::
anyMSWellOpenLocal() const anyMSWellOpenLocal() const
{ {
for (const auto& well : wells_ecl_) { for (const auto& well : wells_ecl_) {
@ -166,8 +167,8 @@ anyMSWellOpenLocal() const
return false; return false;
} }
const Well& template<class Scalar>
BlackoilWellModelGeneric:: const Well& BlackoilWellModelGeneric<Scalar>::
getWellEcl(const std::string& well_name) const getWellEcl(const std::string& well_name) const
{ {
// finding the iterator of the well in wells_ecl // finding the iterator of the well in wells_ecl
@ -182,8 +183,8 @@ getWellEcl(const std::string& well_name) const
return *well_ecl; return *well_ecl;
} }
void template<class Scalar>
BlackoilWellModelGeneric:: void BlackoilWellModelGeneric<Scalar>::
initFromRestartFile(const RestartValue& restartValues, initFromRestartFile(const RestartValue& restartValues,
WellTestState wtestState, WellTestState wtestState,
const std::size_t numCells, const std::size_t numCells,
@ -210,22 +211,27 @@ initFromRestartFile(const RestartValue& restartValues,
this->schedule(), handle_ms_well, numCells, this->schedule(), handle_ms_well, numCells,
this->well_perf_data_, this->summaryState_); this->well_perf_data_, this->summaryState_);
BlackoilWellModelRestart(*this).loadRestartData(restartValues.wells, BlackoilWellModelRestart(*this).
restartValues.grp_nwrk, loadRestartData(restartValues.wells,
handle_ms_well, restartValues.grp_nwrk,
this->wellState(), handle_ms_well,
this->groupState()); this->wellState(),
this->groupState());
if (config.has_model()) { if (config.has_model()) {
BlackoilWellModelRestart(*this).loadRestartGuideRates(report_step, BlackoilWellModelRestart(*this).
config.model().target(), loadRestartGuideRates(report_step,
restartValues.wells, config.model().target(),
this->guideRate_); restartValues.wells,
this->guideRate_);
}
BlackoilWellModelRestart(*this).loadRestartGuideRates(report_step, if (config.has_model()) {
config, BlackoilWellModelRestart(*this).
restartValues.grp_nwrk.groupData, loadRestartGuideRates(report_step,
this->guideRate_); config,
restartValues.grp_nwrk.groupData,
this->guideRate_);
this->guideRate_.updateGuideRateExpiration(this->schedule().seconds(report_step), report_step); this->guideRate_.updateGuideRateExpiration(this->schedule().seconds(report_step), report_step);
} }
@ -235,8 +241,8 @@ initFromRestartFile(const RestartValue& restartValues,
initial_step_ = false; initial_step_ = false;
} }
void template<class Scalar>
BlackoilWellModelGeneric:: void BlackoilWellModelGeneric<Scalar>::
prepareDeserialize(int report_step, const std::size_t numCells, bool handle_ms_well) prepareDeserialize(int report_step, const std::size_t numCells, bool handle_ms_well)
{ {
// wells_ecl_ should only contain wells on this processor. // wells_ecl_ should only contain wells on this processor.
@ -258,8 +264,8 @@ prepareDeserialize(int report_step, const std::size_t numCells, bool handle_ms_w
this->updateNupcolWGState(); this->updateNupcolWGState();
} }
std::vector<Well> template<class Scalar>
BlackoilWellModelGeneric:: std::vector<Well> BlackoilWellModelGeneric<Scalar>::
getLocalWells(const int timeStepIdx) const getLocalWells(const int timeStepIdx) const
{ {
auto w = schedule().getWells(timeStepIdx); auto w = schedule().getWells(timeStepIdx);
@ -267,8 +273,9 @@ getLocalWells(const int timeStepIdx) const
return w; return w;
} }
template<class Scalar>
std::vector<std::reference_wrapper<ParallelWellInfo>> std::vector<std::reference_wrapper<ParallelWellInfo>>
BlackoilWellModelGeneric:: BlackoilWellModelGeneric<Scalar>::
createLocalParallelWellInfo(const std::vector<Well>& wells) createLocalParallelWellInfo(const std::vector<Well>& wells)
{ {
std::vector<std::reference_wrapper<ParallelWellInfo>> local_parallel_well_info; std::vector<std::reference_wrapper<ParallelWellInfo>> local_parallel_well_info;
@ -286,8 +293,8 @@ createLocalParallelWellInfo(const std::vector<Well>& wells)
return local_parallel_well_info; return local_parallel_well_info;
} }
void template<class Scalar>
BlackoilWellModelGeneric:: void BlackoilWellModelGeneric<Scalar>::
initializeWellProdIndCalculators() initializeWellProdIndCalculators()
{ {
this->prod_index_calc_.clear(); this->prod_index_calc_.clear();
@ -297,8 +304,8 @@ initializeWellProdIndCalculators()
} }
} }
void template<class Scalar>
BlackoilWellModelGeneric:: void BlackoilWellModelGeneric<Scalar>::
initializeWellPerfData() initializeWellPerfData()
{ {
well_perf_data_.resize(wells_ecl_.size()); well_perf_data_.resize(wells_ecl_.size());
@ -388,8 +395,8 @@ initializeWellPerfData()
} }
} }
void template<class Scalar>
BlackoilWellModelGeneric:: void BlackoilWellModelGeneric<Scalar>::
checkGEconLimits( checkGEconLimits(
const Group& group, const Group& group,
const double simulation_time, const double simulation_time,
@ -407,7 +414,7 @@ checkGEconLimits(
return; return;
} }
GroupEconomicLimitsChecker<double> checker { GroupEconomicLimitsChecker<Scalar> checker {
*this, wellTestState(), group, simulation_time, report_step_idx, deferred_logger *this, wellTestState(), group, simulation_time, report_step_idx, deferred_logger
}; };
if (checker.minOilRate() || checker.minGasRate()) { if (checker.minOilRate() || checker.minGasRate()) {
@ -423,10 +430,10 @@ checkGEconLimits(
} }
} }
void template<class Scalar>
BlackoilWellModelGeneric:: void BlackoilWellModelGeneric<Scalar>::
checkGconsaleLimits(const Group& group, checkGconsaleLimits(const Group& group,
WellState<double>& well_state, WellState<Scalar>& well_state,
const int reportStepIdx, const int reportStepIdx,
DeferredLogger& deferred_logger) DeferredLogger& deferred_logger)
{ {
@ -450,25 +457,24 @@ checkGconsaleLimits(const Group& group,
const Group::ProductionCMode& oldProductionControl = this->groupState().production_control(group.name()); const Group::ProductionCMode& oldProductionControl = this->groupState().production_control(group.name());
int gasPos = phase_usage_.phase_pos[BlackoilPhases::Vapour]; int gasPos = phase_usage_.phase_pos[BlackoilPhases::Vapour];
double production_rate = WellGroupHelpers<double>::sumWellSurfaceRates(group, Scalar production_rate = WellGroupHelpers<Scalar>::sumWellSurfaceRates(group,
schedule(), schedule(),
well_state, well_state,
reportStepIdx, reportStepIdx,
gasPos, gasPos,
/*isInjector*/false); /*isInjector*/false);
double injection_rate = WellGroupHelpers<double>::sumWellSurfaceRates(group, Scalar injection_rate = WellGroupHelpers<Scalar>::sumWellSurfaceRates(group,
schedule(), schedule(),
well_state, well_state,
reportStepIdx, reportStepIdx,
gasPos, gasPos,
/*isInjector*/true); /*isInjector*/true);
// sum over all nodes // sum over all nodes
injection_rate = comm_.sum(injection_rate); injection_rate = comm_.sum(injection_rate);
production_rate = comm_.sum(production_rate); production_rate = comm_.sum(production_rate);
double sales_rate = production_rate - injection_rate; Scalar sales_rate = production_rate - injection_rate;
double production_target = gconsale.sales_target + injection_rate; Scalar production_target = gconsale.sales_target + injection_rate;
// add import rate and subtract consumption rate for group for gas // add import rate and subtract consumption rate for group for gas
if (schedule()[reportStepIdx].gconsump().has(group.name())) { if (schedule()[reportStepIdx].gconsump().has(group.name())) {
@ -482,7 +488,7 @@ checkGconsaleLimits(const Group& group,
} }
if (sales_rate > gconsale.max_sales_rate) { if (sales_rate > gconsale.max_sales_rate) {
switch(gconsale.max_proc) { switch (gconsale.max_proc) {
case GConSale::MaxProcedure::NONE: { case GConSale::MaxProcedure::NONE: {
if (oldProductionControl != Group::ProductionCMode::GRAT && oldProductionControl != Group::ProductionCMode::NONE) { if (oldProductionControl != Group::ProductionCMode::GRAT && oldProductionControl != Group::ProductionCMode::NONE) {
ss = fmt::format("Group sales exceed maximum limit, but the action is NONE for {}. Nothing happens", ss = fmt::format("Group sales exceed maximum limit, but the action is NONE for {}. Nothing happens",
@ -554,8 +560,8 @@ checkGconsaleLimits(const Group& group,
deferred_logger.info(ss); deferred_logger.info(ss);
} }
bool template<class Scalar>
BlackoilWellModelGeneric:: bool BlackoilWellModelGeneric<Scalar>::
checkGroupHigherConstraints(const Group& group, checkGroupHigherConstraints(const Group& group,
DeferredLogger& deferred_logger, DeferredLogger& deferred_logger,
const int reportStepIdx) const int reportStepIdx)
@ -586,16 +592,16 @@ checkGroupHigherConstraints(const Group& group,
->first; ->first;
} }
std::vector<double> rates(phase_usage_.num_phases, 0.0); std::vector<Scalar> rates(phase_usage_.num_phases, 0.0);
bool isField = group.name() == "FIELD"; bool isField = group.name() == "FIELD";
if (!isField && group.isInjectionGroup()) { if (!isField && group.isInjectionGroup()) {
// Obtain rates for group. // Obtain rates for group.
std::vector<double> resv_coeff_inj(phase_usage_.num_phases, 0.0); std::vector<Scalar> resv_coeff_inj(phase_usage_.num_phases, 0.0);
calcInjRates(fipnum, pvtreg, resv_coeff_inj); calcInjRates(fipnum, pvtreg, resv_coeff_inj);
for (int phasePos = 0; phasePos < phase_usage_.num_phases; ++phasePos) { for (int phasePos = 0; phasePos < phase_usage_.num_phases; ++phasePos) {
const double local_current_rate = WellGroupHelpers<double>::sumWellSurfaceRates(group, const Scalar local_current_rate = WellGroupHelpers<Scalar>::sumWellSurfaceRates(group,
schedule(), schedule(),
this->wellState(), this->wellState(),
reportStepIdx, reportStepIdx,
@ -611,7 +617,7 @@ checkGroupHigherConstraints(const Group& group,
if (currentControl != Group::InjectionCMode::FLD && group.injectionGroupControlAvailable(phase)) { if (currentControl != Group::InjectionCMode::FLD && group.injectionGroupControlAvailable(phase)) {
const Group& parentGroup = schedule().getGroup(group.parent(), reportStepIdx); const Group& parentGroup = schedule().getGroup(group.parent(), reportStepIdx);
const auto [is_changed, scaling_factor] = const auto [is_changed, scaling_factor] =
WellGroupHelpers<double>::checkGroupConstraintsInj(group.name(), WellGroupHelpers<Scalar>::checkGroupConstraintsInj(group.name(),
group.parent(), group.parent(),
parentGroup, parentGroup,
this->wellState(), this->wellState(),
@ -632,7 +638,7 @@ checkGroupHigherConstraints(const Group& group,
actionOnBrokenConstraints(group, Group::InjectionCMode::FLD, actionOnBrokenConstraints(group, Group::InjectionCMode::FLD,
phase, this->groupState(), phase, this->groupState(),
deferred_logger); deferred_logger);
WellGroupHelpers<double>::updateWellRatesFromGroupTargetScale(scaling_factor, WellGroupHelpers<Scalar>::updateWellRatesFromGroupTargetScale(scaling_factor,
group, group,
schedule(), schedule(),
reportStepIdx, reportStepIdx,
@ -648,7 +654,7 @@ checkGroupHigherConstraints(const Group& group,
if (!isField && group.isProductionGroup()) { if (!isField && group.isProductionGroup()) {
// Obtain rates for group. // Obtain rates for group.
for (int phasePos = 0; phasePos < phase_usage_.num_phases; ++phasePos) { for (int phasePos = 0; phasePos < phase_usage_.num_phases; ++phasePos) {
const double local_current_rate = WellGroupHelpers<double>::sumWellSurfaceRates(group, const Scalar local_current_rate = WellGroupHelpers<Scalar>::sumWellSurfaceRates(group,
schedule(), schedule(),
this->wellState(), this->wellState(),
reportStepIdx, reportStepIdx,
@ -657,14 +663,14 @@ checkGroupHigherConstraints(const Group& group,
// Sum over all processes // Sum over all processes
rates[phasePos] = -comm_.sum(local_current_rate); rates[phasePos] = -comm_.sum(local_current_rate);
} }
std::vector<double> resv_coeff(phase_usage_.num_phases, 0.0); std::vector<Scalar> resv_coeff(phase_usage_.num_phases, 0.0);
calcRates(fipnum, pvtreg, this->groupState().production_rates(group.name()), resv_coeff); calcRates(fipnum, pvtreg, this->groupState().production_rates(group.name()), resv_coeff);
// Check higher up only if under individual (not FLD) control. // Check higher up only if under individual (not FLD) control.
const Group::ProductionCMode& currentControl = this->groupState().production_control(group.name()); const Group::ProductionCMode& currentControl = this->groupState().production_control(group.name());
if (currentControl != Group::ProductionCMode::FLD && group.productionGroupControlAvailable()) { if (currentControl != Group::ProductionCMode::FLD && group.productionGroupControlAvailable()) {
const Group& parentGroup = schedule().getGroup(group.parent(), reportStepIdx); const Group& parentGroup = schedule().getGroup(group.parent(), reportStepIdx);
const auto [is_changed, scaling_factor] = const auto [is_changed, scaling_factor] =
WellGroupHelpers<double>::checkGroupConstraintsProd(group.name(), WellGroupHelpers<Scalar>::checkGroupConstraintsProd(group.name(),
group.parent(), group.parent(),
parentGroup, parentGroup,
this->wellState(), this->wellState(),
@ -692,7 +698,7 @@ checkGroupHigherConstraints(const Group& group,
if (changed) { if (changed) {
switched_prod_groups_.insert_or_assign(group.name(), switched_prod_groups_.insert_or_assign(group.name(),
Group::ProductionCMode2String(Group::ProductionCMode::FLD)); Group::ProductionCMode2String(Group::ProductionCMode::FLD));
WellGroupHelpers<double>::updateWellRatesFromGroupTargetScale(scaling_factor, WellGroupHelpers<Scalar>::updateWellRatesFromGroupTargetScale(scaling_factor,
group, group,
schedule(), schedule(),
reportStepIdx, reportStepIdx,
@ -707,8 +713,8 @@ checkGroupHigherConstraints(const Group& group,
return changed; return changed;
} }
void template<class Scalar>
BlackoilWellModelGeneric:: void BlackoilWellModelGeneric<Scalar>::
updateEclWells(const int timeStepIdx, updateEclWells(const int timeStepIdx,
const SimulatorUpdate& sim_update, const SimulatorUpdate& sim_update,
const SummaryState& st) const SummaryState& st)
@ -756,8 +762,8 @@ updateEclWells(const int timeStepIdx,
this->wellStructureChangedDynamically_ = sim_update.well_structure_changed; this->wellStructureChangedDynamically_ = sim_update.well_structure_changed;
} }
double template<class Scalar>
BlackoilWellModelGeneric:: Scalar BlackoilWellModelGeneric<Scalar>::
wellPI(const int well_index) const wellPI(const int well_index) const
{ {
const auto& pu = this->phase_usage_; const auto& pu = this->phase_usage_;
@ -788,8 +794,8 @@ wellPI(const int well_index) const
} }
} }
double template<class Scalar>
BlackoilWellModelGeneric:: Scalar BlackoilWellModelGeneric<Scalar>::
wellPI(const std::string& well_name) const wellPI(const std::string& well_name) const
{ {
auto well_iter = std::find_if(this->wells_ecl_.begin(), this->wells_ecl_.end(), auto well_iter = std::find_if(this->wells_ecl_.begin(), this->wells_ecl_.end(),
@ -806,27 +812,27 @@ wellPI(const std::string& well_name) const
return this->wellPI(well_index); return this->wellPI(well_index);
} }
bool template<class Scalar>
BlackoilWellModelGeneric:: bool BlackoilWellModelGeneric<Scalar>::
wasDynamicallyShutThisTimeStep(const int well_index) const wasDynamicallyShutThisTimeStep(const int well_index) const
{ {
return wasDynamicallyShutThisTimeStep(this->wells_ecl_[well_index].name()); return wasDynamicallyShutThisTimeStep(this->wells_ecl_[well_index].name());
} }
template<class Scalar>
bool bool
BlackoilWellModelGeneric:: BlackoilWellModelGeneric<Scalar>::
wasDynamicallyShutThisTimeStep(const std::string& well_name) const wasDynamicallyShutThisTimeStep(const std::string& well_name) const
{ {
return this->closed_this_step_.find(well_name) != return this->closed_this_step_.find(well_name) !=
this->closed_this_step_.end(); this->closed_this_step_.end();
} }
template<class Scalar>
void void BlackoilWellModelGeneric<Scalar>::
BlackoilWellModelGeneric::
updateWsolvent(const Group& group, updateWsolvent(const Group& group,
const int reportStepIdx, const int reportStepIdx,
const WellState<double>& wellState) const WellState<Scalar>& wellState)
{ {
for (const std::string& groupName : group.groups()) { for (const std::string& groupName : group.groups()) {
const Group& groupTmp = schedule_.getGroup(groupName, reportStepIdx); const Group& groupTmp = schedule_.getGroup(groupName, reportStepIdx);
@ -841,13 +847,13 @@ updateWsolvent(const Group& group,
int gasPos = phase_usage_.phase_pos[BlackoilPhases::Vapour]; int gasPos = phase_usage_.phase_pos[BlackoilPhases::Vapour];
const auto& controls = group.injectionControls(Phase::GAS, summaryState_); const auto& controls = group.injectionControls(Phase::GAS, summaryState_);
const Group& groupRein = schedule_.getGroup(controls.reinj_group, reportStepIdx); const Group& groupRein = schedule_.getGroup(controls.reinj_group, reportStepIdx);
double gasProductionRate = WellGroupHelpers<double>::sumWellSurfaceRates(groupRein, Scalar gasProductionRate = WellGroupHelpers<Scalar>::sumWellSurfaceRates(groupRein,
schedule_, schedule_,
wellState, wellState,
reportStepIdx, reportStepIdx,
gasPos, gasPos,
/*isInjector*/false); /*isInjector*/false);
double solventProductionRate = WellGroupHelpers<double>::sumSolventRates(groupRein, Scalar solventProductionRate = WellGroupHelpers<Scalar>::sumSolventRates(groupRein,
schedule_, schedule_,
wellState, wellState,
reportStepIdx, reportStepIdx,
@ -856,7 +862,7 @@ updateWsolvent(const Group& group,
solventProductionRate = comm_.sum(solventProductionRate); solventProductionRate = comm_.sum(solventProductionRate);
gasProductionRate = comm_.sum(gasProductionRate); gasProductionRate = comm_.sum(gasProductionRate);
double wsolvent = 0.0; Scalar wsolvent = 0.0;
if (std::abs(gasProductionRate) > 1e-6) if (std::abs(gasProductionRate) > 1e-6)
wsolvent = solventProductionRate / gasProductionRate; wsolvent = solventProductionRate / gasProductionRate;
@ -864,11 +870,11 @@ updateWsolvent(const Group& group,
} }
} }
void template<class Scalar>
BlackoilWellModelGeneric:: void BlackoilWellModelGeneric<Scalar>::
setWsolvent(const Group& group, setWsolvent(const Group& group,
const int reportStepIdx, const int reportStepIdx,
double wsolvent) Scalar wsolvent)
{ {
for (const std::string& groupName : group.groups()) { for (const std::string& groupName : group.groups()) {
const Group& groupTmp = schedule_.getGroup(groupName, reportStepIdx); const Group& groupTmp = schedule_.getGroup(groupName, reportStepIdx);
@ -884,8 +890,8 @@ setWsolvent(const Group& group,
} }
} }
void template<class Scalar>
BlackoilWellModelGeneric:: void BlackoilWellModelGeneric<Scalar>::
assignShutConnections(data::Wells& wsrpt, assignShutConnections(data::Wells& wsrpt,
const int reportStepIndex) const const int reportStepIndex) const
{ {
@ -929,8 +935,8 @@ assignShutConnections(data::Wells& wsrpt,
} }
} }
void template<class Scalar>
BlackoilWellModelGeneric:: void BlackoilWellModelGeneric<Scalar>::
assignGroupControl(const Group& group, assignGroupControl(const Group& group,
data::GroupData& gdata) const data::GroupData& gdata) const
{ {
@ -960,8 +966,8 @@ assignGroupControl(const Group& group,
} }
} }
void template<class Scalar>
BlackoilWellModelGeneric:: void BlackoilWellModelGeneric<Scalar>::
assignGroupValues(const int reportStepIdx, assignGroupValues(const int reportStepIdx,
std::map<std::string, data::GroupData>& gvalues) const std::map<std::string, data::GroupData>& gvalues) const
{ {
@ -977,9 +983,10 @@ assignGroupValues(const int reportStepIdx,
} }
} }
void template<class Scalar>
BlackoilWellModelGeneric:: void BlackoilWellModelGeneric<Scalar>::
assignNodeValues(std::map<std::string, data::NodeData>& nodevalues, const int reportStepIdx) const assignNodeValues(std::map<std::string, data::NodeData>& nodevalues,
const int reportStepIdx) const
{ {
nodevalues.clear(); nodevalues.clear();
if (reportStepIdx < 0) return; if (reportStepIdx < 0) return;
@ -988,17 +995,21 @@ assignNodeValues(std::map<std::string, data::NodeData>& nodevalues, const int re
nodevalues.emplace(node, data::NodeData{pressure}); nodevalues.emplace(node, data::NodeData{pressure});
// Assign node values of well groups to GPR:WELLNAME // Assign node values of well groups to GPR:WELLNAME
const auto& sched = schedule(); const auto& sched = schedule();
if (!sched.hasGroup(node, reportStepIdx)) continue; if (!sched.hasGroup(node, reportStepIdx)) {
continue;
}
const auto& group = sched.getGroup(node, reportStepIdx); const auto& group = sched.getGroup(node, reportStepIdx);
for (const std::string& wellname : group.wells()) { for (const std::string& wellname : group.wells()) {
nodevalues.emplace(wellname, data::NodeData{pressure}); nodevalues.emplace(wellname, data::NodeData{pressure});
} }
} }
const auto& network = schedule()[reportStepIdx].network(); const auto& network = schedule()[reportStepIdx].network();
if (!network.active()) return; if (!network.active()) {
return;
}
auto converged_pressures = WellGroupHelpers<double>::computeNetworkPressures(network, auto converged_pressures = WellGroupHelpers<Scalar>::computeNetworkPressures(network,
this->wellState(), this->wellState(),
this->groupState(), this->groupState(),
*(vfp_properties_->getProd()), *(vfp_properties_->getProd()),
@ -1010,30 +1021,33 @@ assignNodeValues(std::map<std::string, data::NodeData>& nodevalues, const int re
it->second.converged_pressure = converged_pressure; it->second.converged_pressure = converged_pressure;
// Assign node values of group to GPR:WELLNAME // Assign node values of group to GPR:WELLNAME
const auto& sched = schedule(); const auto& sched = schedule();
if (!sched.hasGroup(node, reportStepIdx)) continue; if (!sched.hasGroup(node, reportStepIdx)) {
continue;
}
const auto& group = sched.getGroup(node, reportStepIdx); const auto& group = sched.getGroup(node, reportStepIdx);
for (const std::string& wellname : group.wells()) { for (const std::string& wellname : group.wells()) {
auto it2 = nodevalues.find(wellname); auto it2 = nodevalues.find(wellname);
assert(it2 != nodevalues.end()); assert(it2 != nodevalues.end());
it2->second.converged_pressure = converged_pressure; it2->second.converged_pressure = converged_pressure;
} }
} }
} }
template<class Scalar>
data::GroupAndNetworkValues data::GroupAndNetworkValues
BlackoilWellModelGeneric:: BlackoilWellModelGeneric<Scalar>::
groupAndNetworkData(const int reportStepIdx) const groupAndNetworkData(const int reportStepIdx) const
{ {
auto grp_nwrk_values = data::GroupAndNetworkValues{}; auto grp_nwrk_values = data::GroupAndNetworkValues{};
this->assignGroupValues(reportStepIdx, grp_nwrk_values.groupData); this->assignGroupValues(reportStepIdx, grp_nwrk_values.groupData);
this->assignNodeValues(grp_nwrk_values.nodeData, reportStepIdx-1); // Schedule state info at previous step this->assignNodeValues(grp_nwrk_values.nodeData, reportStepIdx - 1); // Schedule state info at previous step
return grp_nwrk_values; return grp_nwrk_values;
} }
void template<class Scalar>
BlackoilWellModelGeneric:: void BlackoilWellModelGeneric<Scalar>::
updateAndCommunicateGroupData(const int reportStepIdx, updateAndCommunicateGroupData(const int reportStepIdx,
const int iterationIdx) const int iterationIdx)
{ {
@ -1052,8 +1066,8 @@ updateAndCommunicateGroupData(const int reportStepIdx,
const auto& well_state_nupcol = this->nupcolWellState(); const auto& well_state_nupcol = this->nupcolWellState();
// the group target reduction rates needs to be update since wells may have switched to/from GRUP control // the group target reduction rates needs to be update since wells may have switched to/from GRUP control
// The group target reduction does not honor NUPCOL. // The group target reduction does not honor NUPCOL.
std::vector<double> groupTargetReduction(numPhases(), 0.0); std::vector<Scalar> groupTargetReduction(numPhases(), 0.0);
WellGroupHelpers<double>::updateGroupTargetReduction(fieldGroup, WellGroupHelpers<Scalar>::updateGroupTargetReduction(fieldGroup,
schedule(), schedule(),
reportStepIdx, reportStepIdx,
/*isInjector*/ false, /*isInjector*/ false,
@ -1062,8 +1076,8 @@ updateAndCommunicateGroupData(const int reportStepIdx,
well_state, well_state,
this->groupState(), this->groupState(),
groupTargetReduction); groupTargetReduction);
std::vector<double> groupTargetReductionInj(numPhases(), 0.0); std::vector<Scalar> groupTargetReductionInj(numPhases(), 0.0);
WellGroupHelpers<double>::updateGroupTargetReduction(fieldGroup, WellGroupHelpers<Scalar>::updateGroupTargetReduction(fieldGroup,
schedule(), schedule(),
reportStepIdx, reportStepIdx,
/*isInjector*/ true, /*isInjector*/ true,
@ -1073,7 +1087,7 @@ updateAndCommunicateGroupData(const int reportStepIdx,
this->groupState(), this->groupState(),
groupTargetReductionInj); groupTargetReductionInj);
WellGroupHelpers<double>::updateREINForGroups(fieldGroup, WellGroupHelpers<Scalar>::updateREINForGroups(fieldGroup,
schedule(), schedule(),
reportStepIdx, reportStepIdx,
phase_usage_, phase_usage_,
@ -1081,31 +1095,31 @@ updateAndCommunicateGroupData(const int reportStepIdx,
well_state_nupcol, well_state_nupcol,
this->groupState(), this->groupState(),
comm_.rank() == 0); comm_.rank() == 0);
WellGroupHelpers<double>::updateVREPForGroups(fieldGroup, WellGroupHelpers<Scalar>::updateVREPForGroups(fieldGroup,
schedule(), schedule(),
reportStepIdx, reportStepIdx,
well_state_nupcol, well_state_nupcol,
this->groupState()); this->groupState());
WellGroupHelpers<double>::updateReservoirRatesInjectionGroups(fieldGroup, WellGroupHelpers<Scalar>::updateReservoirRatesInjectionGroups(fieldGroup,
schedule(), schedule(),
reportStepIdx, reportStepIdx,
well_state_nupcol, well_state_nupcol,
this->groupState()); this->groupState());
WellGroupHelpers<double>::updateSurfaceRatesInjectionGroups(fieldGroup, WellGroupHelpers<Scalar>::updateSurfaceRatesInjectionGroups(fieldGroup,
schedule(), schedule(),
reportStepIdx, reportStepIdx,
well_state_nupcol, well_state_nupcol,
this->groupState()); this->groupState());
WellGroupHelpers<double>::updateGroupProductionRates(fieldGroup, WellGroupHelpers<Scalar>::updateGroupProductionRates(fieldGroup,
schedule(), schedule(),
reportStepIdx, reportStepIdx,
well_state_nupcol, well_state_nupcol,
this->groupState()); this->groupState());
// We use the rates from the previous time-step to reduce oscillations // We use the rates from the previous time-step to reduce oscillations
WellGroupHelpers<double>::updateWellRates(fieldGroup, WellGroupHelpers<Scalar>::updateWellRates(fieldGroup,
schedule(), schedule(),
reportStepIdx, reportStepIdx,
this->prevWellState(), this->prevWellState(),
@ -1124,15 +1138,15 @@ updateAndCommunicateGroupData(const int reportStepIdx,
this->groupState().communicate_rates(comm_); this->groupState().communicate_rates(comm_);
} }
bool template<class Scalar>
BlackoilWellModelGeneric:: bool BlackoilWellModelGeneric<Scalar>::
hasTHPConstraints() const hasTHPConstraints() const
{ {
return BlackoilWellModelConstraints(*this).hasTHPConstraints(); return BlackoilWellModelConstraints(*this).hasTHPConstraints();
} }
void template<class Scalar>
BlackoilWellModelGeneric:: void BlackoilWellModelGeneric<Scalar>::
updateNetworkActiveState(const int report_step) { updateNetworkActiveState(const int report_step) {
const auto& network = schedule()[report_step].network(); const auto& network = schedule()[report_step].network();
if (!network.active()) { if (!network.active()) {
@ -1152,8 +1166,8 @@ updateNetworkActiveState(const int report_step) {
this->network_active_ = comm_.max(network_active); this->network_active_ = comm_.max(network_active);
} }
bool template<class Scalar>
BlackoilWellModelGeneric:: bool BlackoilWellModelGeneric<Scalar>::
needPreStepNetworkRebalance(const int report_step) const needPreStepNetworkRebalance(const int report_step) const
{ {
const auto& network = schedule()[report_step].network(); const auto& network = schedule()[report_step].network();
@ -1171,8 +1185,8 @@ needPreStepNetworkRebalance(const int report_step) const
return network_rebalance_necessary; return network_rebalance_necessary;
} }
bool template<class Scalar>
BlackoilWellModelGeneric:: bool BlackoilWellModelGeneric<Scalar>::
forceShutWellByName(const std::string& wellname, forceShutWellByName(const std::string& wellname,
const double simulation_time) const double simulation_time)
{ {
@ -1204,8 +1218,8 @@ forceShutWellByName(const std::string& wellname,
return (well_was_shut == 1); return (well_was_shut == 1);
} }
void template<class Scalar>
BlackoilWellModelGeneric:: void BlackoilWellModelGeneric<Scalar>::
inferLocalShutWells() inferLocalShutWells()
{ {
this->local_shut_wells_.clear(); this->local_shut_wells_.clear();
@ -1224,8 +1238,8 @@ inferLocalShutWells()
} }
} }
double template<class Scalar>
BlackoilWellModelGeneric:: Scalar BlackoilWellModelGeneric<Scalar>::
updateNetworkPressures(const int reportStepIdx) updateNetworkPressures(const int reportStepIdx)
{ {
// Get the network and return if inactive (no wells in network at this time) // Get the network and return if inactive (no wells in network at this time)
@ -1236,7 +1250,7 @@ updateNetworkPressures(const int reportStepIdx)
const auto previous_node_pressures = node_pressures_; const auto previous_node_pressures = node_pressures_;
node_pressures_ = WellGroupHelpers<double>::computeNetworkPressures(network, node_pressures_ = WellGroupHelpers<Scalar>::computeNetworkPressures(network,
this->wellState(), this->wellState(),
this->groupState(), this->groupState(),
*(vfp_properties_->getProd()), *(vfp_properties_->getProd()),
@ -1244,7 +1258,7 @@ updateNetworkPressures(const int reportStepIdx)
reportStepIdx); reportStepIdx);
// here, the network imbalance is the difference between the previous nodal pressure and the new nodal pressure // here, the network imbalance is the difference between the previous nodal pressure and the new nodal pressure
double network_imbalance = 0.; Scalar network_imbalance = 0.;
if (!this->networkActive()) if (!this->networkActive())
return network_imbalance; return network_imbalance;
@ -1257,18 +1271,18 @@ updateNetworkPressures(const int reportStepIdx)
continue; continue;
} }
const auto pressure = previous_node_pressures.at(name); const auto pressure = previous_node_pressures.at(name);
const double change = (new_pressure - pressure); const Scalar change = (new_pressure - pressure);
if (std::abs(change) > network_imbalance) { if (std::abs(change) > network_imbalance) {
network_imbalance = std::abs(change); network_imbalance = std::abs(change);
} }
// we dampen the amount of the nodal pressure can change during one iteration // we dampen the amount of the nodal pressure can change during one iteration
// due to the fact our nodal pressure calculation is somewhat explicit // due to the fact our nodal pressure calculation is somewhat explicit
// TODO: the following parameters are subject to adjustment for optimization purpose // TODO: the following parameters are subject to adjustment for optimization purpose
constexpr double upper_update_bound = 5.0 * unit::barsa; constexpr Scalar upper_update_bound = 5.0 * unit::barsa;
// relative dampening factor based on update value // relative dampening factor based on update value
constexpr double damping_factor = 0.1; constexpr Scalar damping_factor = 0.1;
const double damped_change = std::min(damping_factor * std::abs(change), upper_update_bound); const Scalar damped_change = std::min(damping_factor * std::abs(change), upper_update_bound);
const double sign = change > 0 ? 1. : -1.; const Scalar sign = change > 0 ? 1. : -1.;
node_pressures_[name] = pressure + sign * damped_change; node_pressures_[name] = pressure + sign * damped_change;
} }
} else { } else {
@ -1289,9 +1303,9 @@ updateNetworkPressures(const int reportStepIdx)
if (it != node_pressures_.end()) { if (it != node_pressures_.end()) {
// The well belongs to a group with has a network pressure constraint, // The well belongs to a group with has a network pressure constraint,
// set the dynamic THP constraint of the well accordingly. // set the dynamic THP constraint of the well accordingly.
const double new_limit = it->second; const Scalar new_limit = it->second;
well->setDynamicThpLimit(new_limit); well->setDynamicThpLimit(new_limit);
SingleWellState<double>& ws = this->wellState()[well->indexOfWell()]; SingleWellState<Scalar>& ws = this->wellState()[well->indexOfWell()];
const bool thp_is_limit = ws.production_cmode == Well::ProducerCMode::THP; const bool thp_is_limit = ws.production_cmode == Well::ProducerCMode::THP;
// TODO: not sure why the thp is NOT updated properly elsewhere // TODO: not sure why the thp is NOT updated properly elsewhere
if (thp_is_limit) { if (thp_is_limit) {
@ -1303,14 +1317,14 @@ updateNetworkPressures(const int reportStepIdx)
return network_imbalance; return network_imbalance;
} }
void template<class Scalar>
BlackoilWellModelGeneric:: void BlackoilWellModelGeneric<Scalar>::
calculateEfficiencyFactors(const int reportStepIdx) calculateEfficiencyFactors(const int reportStepIdx)
{ {
for (auto& well : well_container_generic_) { for (auto& well : well_container_generic_) {
const Well& wellEcl = well->wellEcl(); const Well& wellEcl = well->wellEcl();
double well_efficiency_factor = wellEcl.getEfficiencyFactor(); Scalar well_efficiency_factor = wellEcl.getEfficiencyFactor();
WellGroupHelpers<double>::accumulateGroupEfficiencyFactor(schedule().getGroup(wellEcl.groupName(), WellGroupHelpers<Scalar>::accumulateGroupEfficiencyFactor(schedule().getGroup(wellEcl.groupName(),
reportStepIdx), reportStepIdx),
schedule(), schedule(),
reportStepIdx, reportStepIdx,
@ -1319,8 +1333,9 @@ calculateEfficiencyFactors(const int reportStepIdx)
} }
} }
template<class Scalar>
WellInterfaceGeneric* WellInterfaceGeneric*
BlackoilWellModelGeneric:: 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
@ -1335,8 +1350,8 @@ getGenWell(const std::string& well_name)
return *well; return *well;
} }
void template<class Scalar>
BlackoilWellModelGeneric:: void BlackoilWellModelGeneric<Scalar>::
setRepRadiusPerfLength() setRepRadiusPerfLength()
{ {
for (const auto& well : well_container_generic_) { for (const auto& well : well_container_generic_) {
@ -1344,8 +1359,8 @@ setRepRadiusPerfLength()
} }
} }
void template<class Scalar>
BlackoilWellModelGeneric:: void BlackoilWellModelGeneric<Scalar>::
gliftDebug(const std::string& msg, gliftDebug(const std::string& msg,
DeferredLogger& deferred_logger) const DeferredLogger& deferred_logger) const
{ {
@ -1356,9 +1371,8 @@ gliftDebug(const std::string& msg,
} }
} }
template<class Scalar>
void void BlackoilWellModelGeneric<Scalar>::
BlackoilWellModelGeneric::
gliftDebugShowALQ(DeferredLogger& deferred_logger) gliftDebugShowALQ(DeferredLogger& deferred_logger)
{ {
for (auto& well : this->well_container_generic_) { for (auto& well : this->well_container_generic_) {
@ -1378,8 +1392,8 @@ gliftDebugShowALQ(DeferredLogger& deferred_logger)
// currently has the largest weighted incremental gradient. The // currently has the largest weighted incremental gradient. The
// procedure takes account of any limits on the group production // procedure takes account of any limits on the group production
// rate or lift gas supply applied to any level of group. // rate or lift gas supply applied to any level of group.
void template<class Scalar>
BlackoilWellModelGeneric:: void BlackoilWellModelGeneric<Scalar>::
gasLiftOptimizationStage2(DeferredLogger& deferred_logger, gasLiftOptimizationStage2(DeferredLogger& deferred_logger,
GLiftProdWells& prod_wells, GLiftProdWells& prod_wells,
GLiftOptWells& glift_wells, GLiftOptWells& glift_wells,
@ -1403,8 +1417,8 @@ gasLiftOptimizationStage2(DeferredLogger& deferred_logger,
glift.runOptimize(); glift.runOptimize();
} }
void template<class Scalar>
BlackoilWellModelGeneric:: void BlackoilWellModelGeneric<Scalar>::
updateWellPotentials(const int reportStepIdx, updateWellPotentials(const int reportStepIdx,
const bool onlyAfterEvent, const bool onlyAfterEvent,
const SummaryConfig& summaryConfig, const SummaryConfig& summaryConfig,
@ -1462,11 +1476,10 @@ updateWellPotentials(const int reportStepIdx,
logAndCheckForExceptionsAndThrow(deferred_logger, exc_type, logAndCheckForExceptionsAndThrow(deferred_logger, exc_type,
"computeWellPotentials() failed: " + exc_msg, "computeWellPotentials() failed: " + exc_msg,
terminal_output_, comm_); terminal_output_, comm_);
} }
void template<class Scalar>
BlackoilWellModelGeneric:: void BlackoilWellModelGeneric<Scalar>::
runWellPIScaling(const int reportStepIdx, runWellPIScaling(const int reportStepIdx,
DeferredLogger& local_deferredLogger) DeferredLogger& local_deferredLogger)
{ {
@ -1503,10 +1516,9 @@ runWellPIScaling(const int reportStepIdx,
this->prod_index_calc_[well_index].reInit(well); this->prod_index_calc_[well_index].reInit(well);
}; };
auto rescaleWellPI = auto rescaleWellPI =
[this, reportStepIdx](const int well_index, [this, reportStepIdx](const int well_index,
const double newWellPI) -> void const Scalar newWellPI) -> void
{ {
const auto& wname = this->wells_ecl_[well_index].name(); const auto& wname = this->wells_ecl_[well_index].name();
@ -1540,8 +1552,8 @@ runWellPIScaling(const int reportStepIdx,
this->last_run_wellpi_ = reportStepIdx; this->last_run_wellpi_ = reportStepIdx;
} }
bool template<class Scalar>
BlackoilWellModelGeneric:: bool BlackoilWellModelGeneric<Scalar>::
shouldBalanceNetwork(const int reportStepIdx, const int iterationIdx) const shouldBalanceNetwork(const int reportStepIdx, const int iterationIdx) const
{ {
// if network is not active, we do not need to balance the network // if network is not active, we do not need to balance the network
@ -1565,10 +1577,8 @@ shouldBalanceNetwork(const int reportStepIdx, const int iterationIdx) const
} }
} }
template<class Scalar>
std::vector<int> BlackoilWellModelGeneric<Scalar>::
std::vector<int>
BlackoilWellModelGeneric::
getCellsForConnections(const Well& well) const getCellsForConnections(const Well& well) const
{ {
std::vector<int> wellCells; std::vector<int> wellCells;
@ -1587,9 +1597,10 @@ getCellsForConnections(const Well& well) const
return wellCells; return wellCells;
} }
std::vector<std::string> template<class Scalar>
BlackoilWellModelGeneric::getWellsForTesting(const int timeStepIdx, std::vector<std::string> BlackoilWellModelGeneric<Scalar>::
const double simulationTime) getWellsForTesting(const int timeStepIdx,
const double simulationTime)
{ {
const auto& wtest_config = schedule()[timeStepIdx].wtest_config(); const auto& wtest_config = schedule()[timeStepIdx].wtest_config();
if (!wtest_config.empty()) { // there is a WTEST request if (!wtest_config.empty()) { // there is a WTEST request
@ -1598,8 +1609,8 @@ BlackoilWellModelGeneric::getWellsForTesting(const int timeStepIdx,
return {}; return {};
} }
void template<class Scalar>
BlackoilWellModelGeneric:: void BlackoilWellModelGeneric<Scalar>::
assignWellTracerRates(data::Wells& wsrpt, assignWellTracerRates(data::Wells& wsrpt,
const WellTracerRates& wellTracerRates) const const WellTracerRates& wellTracerRates) const
{ {
@ -1613,13 +1624,13 @@ assignWellTracerRates(data::Wells& wsrpt,
continue; continue;
} }
std::string tracerName = wTR.first.second; std::string tracerName = wTR.first.second;
double rate = wTR.second; Scalar rate = wTR.second;
xwPos->second.rates.set(data::Rates::opt::tracer, rate, tracerName); xwPos->second.rates.set(data::Rates::opt::tracer, rate, tracerName);
} }
} }
std::vector<std::vector<int>> template<class Scalar>
BlackoilWellModelGeneric:: std::vector<std::vector<int>> BlackoilWellModelGeneric<Scalar>::
getMaxWellConnections() const getMaxWellConnections() const
{ {
std::vector<std::vector<int>> wells; std::vector<std::vector<int>> wells;
@ -1629,7 +1640,7 @@ getMaxWellConnections() const
wells.reserve(schedule_wells.size()); wells.reserve(schedule_wells.size());
// initialize the additional cell connections introduced by wells. // initialize the additional cell connections introduced by wells.
for ( const auto& well : schedule_wells ) for (const auto& well : schedule_wells)
{ {
std::vector<int> compressed_well_perforations = this->getCellsForConnections(well); std::vector<int> compressed_well_perforations = this->getCellsForConnections(well);
@ -1642,26 +1653,29 @@ getMaxWellConnections() const
return wells; return wells;
} }
int BlackoilWellModelGeneric::numLocalWellsEnd() const template<class Scalar>
int BlackoilWellModelGeneric<Scalar>::numLocalWellsEnd() const
{ {
auto w = schedule().getWellsatEnd(); auto w = schedule().getWellsatEnd();
w.erase(std::remove_if(w.begin(), w.end(), not_on_process_), w.end()); w.erase(std::remove_if(w.begin(), w.end(), not_on_process_), w.end());
return w.size(); return w.size();
} }
int BlackoilWellModelGeneric::numLocalNonshutWells() const template<class Scalar>
int BlackoilWellModelGeneric<Scalar>::numLocalNonshutWells() const
{ {
return well_container_generic_.size(); return well_container_generic_.size();
} }
template<class Scalar>
void BlackoilWellModelGeneric::initInjMult() { void BlackoilWellModelGeneric<Scalar>::initInjMult()
{
for (auto& well : this->well_container_generic_) { for (auto& well : this->well_container_generic_) {
if (well->isInjector() && well->wellEcl().getInjMultMode() != Well::InjMultMode::NONE) { if (well->isInjector() && well->wellEcl().getInjMultMode() != Well::InjMultMode::NONE) {
const auto& ws = this->wellState().well(well->indexOfWell()); const auto& ws = this->wellState().well(well->indexOfWell());
const auto& perf_data = ws.perf_data; const auto& perf_data = ws.perf_data;
auto &values = this->prev_inj_multipliers_[well->name()]; auto& values = this->prev_inj_multipliers_[well->name()];
if (values.empty()) { if (values.empty()) {
values.assign(perf_data.size(), 1.0); values.assign(perf_data.size(), 1.0);
} }
@ -1670,13 +1684,14 @@ void BlackoilWellModelGeneric::initInjMult() {
} }
} }
template<class Scalar>
void BlackoilWellModelGeneric::updateFiltrationParticleVolume(const double dt, void BlackoilWellModelGeneric<Scalar>::
const std::size_t water_index) updateFiltrationParticleVolume(const double dt,
const std::size_t water_index)
{ {
for (auto& well : this->well_container_generic_) { for (auto& well : this->well_container_generic_) {
if (well->isInjector()) { if (well->isInjector()) {
const double conc = well->wellEcl().evalFilterConc(this->summaryState_); const Scalar conc = well->wellEcl().evalFilterConc(this->summaryState_);
if (conc > 0.) { if (conc > 0.) {
auto fc = this->filter_cake_ auto fc = this->filter_cake_
.emplace(std::piecewise_construct, .emplace(std::piecewise_construct,
@ -1690,7 +1705,9 @@ void BlackoilWellModelGeneric::updateFiltrationParticleVolume(const double dt,
} }
} }
void BlackoilWellModelGeneric::updateInjMult(DeferredLogger& deferred_logger) template<class Scalar>
void BlackoilWellModelGeneric<Scalar>::
updateInjMult(DeferredLogger& deferred_logger)
{ {
for (const auto& well : this->well_container_generic_) { for (const auto& well : this->well_container_generic_) {
if (well->isInjector() && well->wellEcl().getInjMultMode() != Well::InjMultMode::NONE) { if (well->isInjector() && well->wellEcl().getInjMultMode() != Well::InjMultMode::NONE) {
@ -1699,7 +1716,9 @@ void BlackoilWellModelGeneric::updateInjMult(DeferredLogger& deferred_logger)
} }
} }
void BlackoilWellModelGeneric::updateInjFCMult(DeferredLogger& deferred_logger) template<class Scalar>
void BlackoilWellModelGeneric<Scalar>::
updateInjFCMult(DeferredLogger& deferred_logger)
{ {
for (auto& well : this->well_container_generic_) { for (auto& well : this->well_container_generic_) {
if (well->isInjector()) { if (well->isInjector()) {
@ -1712,4 +1731,6 @@ void BlackoilWellModelGeneric::updateInjFCMult(DeferredLogger& deferred_logger)
} }
} }
template class BlackoilWellModelGeneric<double>;
} }

View File

@ -46,7 +46,6 @@
#include <memory> #include <memory>
#include <optional> #include <optional>
#include <string> #include <string>
#include <type_traits>
#include <unordered_map> #include <unordered_map>
#include <unordered_set> #include <unordered_set>
#include <vector> #include <vector>
@ -79,6 +78,7 @@ namespace Opm { namespace data {
namespace Opm { namespace Opm {
/// Class for handling the blackoil well model. /// Class for handling the blackoil well model.
template<class Scalar>
class BlackoilWellModelGeneric class BlackoilWellModelGeneric
{ {
public: public:
@ -114,14 +114,14 @@ public:
std::vector<Well> getLocalWells(const int timeStepIdx) const; std::vector<Well> getLocalWells(const int timeStepIdx) const;
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<double>& 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*> genericWells() const
{ return {well_container_generic_.begin(), well_container_generic_.end()}; } { return {well_container_generic_.begin(), well_container_generic_.end()}; }
/* /*
Immutable version of the currently active wellstate. Immutable version of the currently active wellstate.
*/ */
const WellState<double>& wellState() const const WellState<Scalar>& wellState() const
{ {
return this->active_wgstate_.well_state; return this->active_wgstate_.well_state;
} }
@ -129,7 +129,7 @@ public:
/* /*
Mutable version of the currently active wellstate. Mutable version of the currently active wellstate.
*/ */
WellState<double>& wellState() WellState<Scalar>& wellState()
{ {
return this->active_wgstate_.well_state; return this->active_wgstate_.well_state;
} }
@ -138,19 +138,18 @@ public:
Will return the currently active nupcolWellState; must initialize Will return the currently active nupcolWellState; must initialize
the internal nupcol wellstate with initNupcolWellState() first. the internal nupcol wellstate with initNupcolWellState() first.
*/ */
const WellState<double>& nupcolWellState() const const WellState<Scalar>& nupcolWellState() const
{ {
return this->nupcol_wgstate_.well_state; return this->nupcol_wgstate_.well_state;
} }
GroupState<double>& groupState() { return this->active_wgstate_.group_state; } GroupState<Scalar>& groupState() { return this->active_wgstate_.group_state; }
WellTestState& wellTestState() { return this->active_wgstate_.well_test_state; } WellTestState& wellTestState() { return this->active_wgstate_.well_test_state; }
const WellTestState& wellTestState() const { return this->active_wgstate_.well_test_state; } const WellTestState& wellTestState() const { return this->active_wgstate_.well_test_state; }
Scalar wellPI(const int well_index) const;
double wellPI(const int well_index) const; Scalar wellPI(const std::string& well_name) const;
double wellPI(const std::string& well_name) const;
void updateEclWells(const int timeStepIdx, void updateEclWells(const int timeStepIdx,
const SimulatorUpdate& sim_update, const SimulatorUpdate& sim_update,
@ -210,7 +209,8 @@ public:
bool shouldBalanceNetwork(const int reportStepIndex, bool shouldBalanceNetwork(const int reportStepIndex,
const int iterationIdx) const; const int iterationIdx) const;
void updateClosedWellsThisStep(const std::string& well_name) const { void updateClosedWellsThisStep(const std::string& well_name) const
{
this->closed_this_step_.insert(well_name); this->closed_this_step_.insert(well_name);
} }
bool wasDynamicallyShutThisTimeStep(const std::string& well_name) const; bool wasDynamicallyShutThisTimeStep(const std::string& well_name) const;
@ -254,7 +254,6 @@ public:
} }
protected: protected:
/* /*
The dynamic state of the well model is maintained with an instance The dynamic state of the well model is maintained with an instance
of the WellState class. Currently we have of the WellState class. Currently we have
@ -275,7 +274,6 @@ protected:
nupcol_well_state_ and the initNupcolWellState() function. nupcol_well_state_ and the initNupcolWellState() function.
*/ */
/* /*
Will return the last good wellstate. This is typcially used when Will return the last good wellstate. This is typcially used when
initializing a new report step where the Schedule object might initializing a new report step where the Schedule object might
@ -283,25 +281,22 @@ protected:
prevWellState() must have been stored with the commitWellState() prevWellState() must have been stored with the commitWellState()
function first. function first.
*/ */
const WellState<double>& prevWellState() const const WellState<Scalar>& prevWellState() const
{ {
return this->last_valid_wgstate_.well_state; return this->last_valid_wgstate_.well_state;
} }
const WGState<Scalar>& prevWGState() const
const WGState<double>& prevWGState() const
{ {
return this->last_valid_wgstate_; return this->last_valid_wgstate_;
} }
/* /*
Will store a copy of the input argument well_state in the Will store a copy of the input argument well_state in the
last_valid_well_state_ member, that state can then be recovered last_valid_well_state_ member, that state can then be recovered
with a subsequent call to resetWellState(). with a subsequent call to resetWellState().
*/ */
void commitWGState(WGState<double> wgstate) void commitWGState(WGState<Scalar> wgstate)
{ {
this->last_valid_wgstate_ = std::move(wgstate); this->last_valid_wgstate_ = std::move(wgstate);
} }
@ -328,28 +323,29 @@ protected:
/// \brief Create the parallel well information /// \brief Create the parallel well information
/// \param localWells The local wells from ECL schedule /// \param localWells The local wells from ECL schedule
std::vector<std::reference_wrapper<ParallelWellInfo>> createLocalParallelWellInfo(const std::vector<Well>& wells); std::vector<std::reference_wrapper<ParallelWellInfo>>
createLocalParallelWellInfo(const std::vector<Well>& wells);
void initializeWellProdIndCalculators(); void initializeWellProdIndCalculators();
void initializeWellPerfData(); void initializeWellPerfData();
bool wasDynamicallyShutThisTimeStep(const int well_index) const; bool wasDynamicallyShutThisTimeStep(const int well_index) const;
double updateNetworkPressures(const int reportStepIdx); Scalar updateNetworkPressures(const int reportStepIdx);
void updateWsolvent(const Group& group, void updateWsolvent(const Group& group,
const int reportStepIdx, const int reportStepIdx,
const WellState<double>& wellState); const WellState<Scalar>& wellState);
void setWsolvent(const Group& group, void setWsolvent(const Group& group,
const int reportStepIdx, const int reportStepIdx,
double wsolvent); Scalar wsolvent);
virtual void calcRates(const int fipnum, virtual void calcRates(const int fipnum,
const int pvtreg, const int pvtreg,
const std::vector<double>& production_rates, const std::vector<Scalar>& production_rates,
std::vector<double>& resv_coeff) = 0; std::vector<Scalar>& resv_coeff) = 0;
virtual void calcInjRates(const int fipnum, virtual void calcInjRates(const int fipnum,
const int pvtreg, const int pvtreg,
std::vector<double>& resv_coeff) = 0; std::vector<Scalar>& resv_coeff) = 0;
void assignShutConnections(data::Wells& wsrpt, void assignShutConnections(data::Wells& wsrpt,
const int reportStepIndex) const; const int reportStepIndex) const;
@ -357,12 +353,13 @@ protected:
data::GroupData& gdata) const; data::GroupData& gdata) const;
void assignGroupValues(const int reportStepIdx, void assignGroupValues(const int reportStepIdx,
std::map<std::string, data::GroupData>& gvalues) const; std::map<std::string, data::GroupData>& gvalues) const;
void assignNodeValues(std::map<std::string, data::NodeData>& nodevalues, const int reportStepIdx) const; void assignNodeValues(std::map<std::string, data::NodeData>& nodevalues,
const int reportStepIdx) const;
void calculateEfficiencyFactors(const int reportStepIdx); void calculateEfficiencyFactors(const int reportStepIdx);
void checkGconsaleLimits(const Group& group, void checkGconsaleLimits(const Group& group,
WellState<double>& well_state, WellState<Scalar>& well_state,
const int reportStepIdx, const int reportStepIdx,
DeferredLogger& deferred_logger); DeferredLogger& deferred_logger);
@ -395,7 +392,7 @@ protected:
const int episodeIndex); const int episodeIndex);
virtual void computePotentials(const std::size_t widx, virtual void computePotentials(const std::size_t widx,
const WellState<double>& well_state_copy, const WellState<Scalar>& well_state_copy,
std::string& exc_msg, std::string& exc_msg,
ExceptionType::ExcEnum& exc_type, ExceptionType::ExcEnum& exc_type,
DeferredLogger& deferred_logger) = 0; DeferredLogger& deferred_logger) = 0;
@ -408,11 +405,11 @@ protected:
void initInjMult(); void initInjMult();
void updateInjMult(DeferredLogger& deferred_logger); void updateInjMult(DeferredLogger& deferred_logger);
void updateInjFCMult(DeferredLogger& deferred_logger); void updateInjFCMult(DeferredLogger& deferred_logger);
void updateFiltrationParticleVolume(const double dt, const std::size_t water_index); void updateFiltrationParticleVolume(const double dt,
const std::size_t water_index);
// create the well container // create the well container
virtual void createWellContainer(const int time_step) = 0; virtual void createWellContainer(const int time_step) = 0;
@ -434,7 +431,7 @@ protected:
std::vector<std::string> getWellsForTesting(const int timeStepIdx, std::vector<std::string> getWellsForTesting(const int timeStepIdx,
const double simulationTime); const double simulationTime);
using WellTracerRates = std::map<std::pair<std::string, std::string>, double>; using WellTracerRates = std::map<std::pair<std::string, std::string>, Scalar>;
void assignWellTracerRates(data::Wells& wsrpt, void assignWellTracerRates(data::Wells& wsrpt,
const WellTracerRates& wellTracerRates) const; const WellTracerRates& wellTracerRates) const;
@ -561,13 +558,13 @@ protected:
GuideRate guideRate_; GuideRate guideRate_;
std::unique_ptr<VFPProperties> vfp_properties_{}; std::unique_ptr<VFPProperties> vfp_properties_{};
std::map<std::string, double> node_pressures_; // Storing network pressures for output. std::map<std::string, Scalar> node_pressures_; // Storing network pressures for output.
// previous injection multiplier, it is used in the injection multiplier calculation for WINJMULT keyword // previous injection multiplier, it is used in the injection multiplier calculation for WINJMULT keyword
std::unordered_map<std::string, std::vector<double>> prev_inj_multipliers_; std::unordered_map<std::string, std::vector<Scalar>> prev_inj_multipliers_;
// Handling for filter cake injection multipliers // Handling for filter cake injection multipliers
std::unordered_map<std::string, WellFilterCake<double>> filter_cake_; std::unordered_map<std::string, WellFilterCake<Scalar>> filter_cake_;
/* /*
The various wellState members should be accessed and modified The various wellState members should be accessed and modified
@ -575,9 +572,9 @@ protected:
commitWellState(), resetWellState(), nupcolWellState() and commitWellState(), resetWellState(), nupcolWellState() and
updateNupcolWellState(). updateNupcolWellState().
*/ */
WGState<double> active_wgstate_; WGState<Scalar> active_wgstate_;
WGState<double> last_valid_wgstate_; WGState<Scalar> last_valid_wgstate_;
WGState<double> nupcol_wgstate_; WGState<Scalar> nupcol_wgstate_;
bool glift_debug = false; bool glift_debug = false;
@ -587,11 +584,10 @@ protected:
// Store maps of group name and new group controls for output // Store maps of group name and new group controls for output
std::map<std::string, std::string> switched_prod_groups_; std::map<std::string, std::string> switched_prod_groups_;
std::map<std::pair<std::string, Opm::Phase>, std::string> switched_inj_groups_; std::map<std::pair<std::string, Phase>, std::string> switched_inj_groups_;
// Store map of group name and close offending well for output // Store map of group name and close offending well for output
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* getGenWell(const std::string& well_name);
}; };

View File

@ -283,8 +283,8 @@ const Opm::Well& GroupTreeWalker::getWell(std::string_view well) const
namespace Opm { namespace Opm {
void template<class Scalar>
BlackoilWellModelGuideRates:: void BlackoilWellModelGuideRates<Scalar>::
getGuideRateValues(const GuideRate::RateVector& qs, getGuideRateValues(const GuideRate::RateVector& qs,
const bool is_inj, const bool is_inj,
const std::string& wgname, const std::string& wgname,
@ -309,8 +309,9 @@ getGuideRateValues(const GuideRate::RateVector& qs,
} }
} }
template<class Scalar>
data::GuideRateValue data::GuideRateValue
BlackoilWellModelGuideRates:: BlackoilWellModelGuideRates<Scalar>::
getGuideRateValues(const Well& well) const getGuideRateValues(const Well& well) const
{ {
auto grval = data::GuideRateValue{}; auto grval = data::GuideRateValue{};
@ -328,7 +329,7 @@ getGuideRateValues(const Well& well) const
return grval; return grval;
} }
const auto qs = WellGroupHelpers<double>:: const auto qs = WellGroupHelpers<Scalar>::
getWellRateVector(wellModel_.wellState(), wellModel_.phaseUsage(), wname); getWellRateVector(wellModel_.wellState(), wellModel_.phaseUsage(), wname);
this->getGuideRateValues(qs, well.isInjector(), wname, grval); this->getGuideRateValues(qs, well.isInjector(), wname, grval);
@ -336,8 +337,9 @@ getGuideRateValues(const Well& well) const
return grval; return grval;
} }
template<class Scalar>
data::GuideRateValue data::GuideRateValue
BlackoilWellModelGuideRates:: BlackoilWellModelGuideRates<Scalar>::
getGuideRateValues(const Group& group) const getGuideRateValues(const Group& group) const
{ {
auto grval = data::GuideRateValue{}; auto grval = data::GuideRateValue{};
@ -355,7 +357,7 @@ getGuideRateValues(const Group& group) const
return grval; return grval;
} }
const auto qs = WellGroupHelpers<double>:: const auto qs = WellGroupHelpers<Scalar>::
getProductionGroupRateVector(wellModel_.groupState(), wellModel_.phaseUsage(), gname); getProductionGroupRateVector(wellModel_.groupState(), wellModel_.phaseUsage(), gname);
const auto is_inj = false; // This procedure only applies to G*PGR. const auto is_inj = false; // This procedure only applies to G*PGR.
@ -364,8 +366,9 @@ getGuideRateValues(const Group& group) const
return grval; return grval;
} }
template<class Scalar>
data::GuideRateValue data::GuideRateValue
BlackoilWellModelGuideRates:: BlackoilWellModelGuideRates<Scalar>::
getGuideRateInjectionGroupValues(const Group& group) const getGuideRateInjectionGroupValues(const Group& group) const
{ {
auto grval = data::GuideRateValue{}; auto grval = data::GuideRateValue{};
@ -384,7 +387,8 @@ getGuideRateInjectionGroupValues(const Group& group) const
return grval; return grval;
} }
void BlackoilWellModelGuideRates:: template<class Scalar>
void BlackoilWellModelGuideRates<Scalar>::
assignWellGuideRates(data::Wells& wsrpt, assignWellGuideRates(data::Wells& wsrpt,
const int reportStepIdx) const const int reportStepIdx) const
{ {
@ -433,7 +437,7 @@ assignWellGuideRates(data::Wells& wsrpt,
const auto get_gr = parent const auto get_gr = parent
|| RetrieveWellGuideRate{wellModel_.guideRate(), wname}; || RetrieveWellGuideRate{wellModel_.guideRate(), wname};
const auto qs = WellGroupHelpers<double>:: const auto qs = WellGroupHelpers<Scalar>::
getWellRateVector(wellModel_.wellState(), wellModel_.phaseUsage(), wname); getWellRateVector(wellModel_.wellState(), wellModel_.phaseUsage(), wname);
auto getGR = [this, &wname, &qs](const GuideRateModel::Target t) auto getGR = [this, &wname, &qs](const GuideRateModel::Target t)
@ -482,8 +486,9 @@ assignWellGuideRates(data::Wells& wsrpt,
} }
} }
template<class Scalar>
std::unordered_map<std::string, data::GroupGuideRates> std::unordered_map<std::string, data::GroupGuideRates>
BlackoilWellModelGuideRates:: BlackoilWellModelGuideRates<Scalar>::
calculateAllGroupGuideRates(const int reportStepIdx) const calculateAllGroupGuideRates(const int reportStepIdx) const
{ {
auto gr = std::unordered_map<std::string, data::GroupGuideRates>{}; auto gr = std::unordered_map<std::string, data::GroupGuideRates>{};
@ -542,7 +547,8 @@ calculateAllGroupGuideRates(const int reportStepIdx) const
return gr; return gr;
} }
void BlackoilWellModelGuideRates:: template<class Scalar>
void BlackoilWellModelGuideRates<Scalar>::
assignGroupGuideRates(const Group& group, assignGroupGuideRates(const Group& group,
const std::unordered_map<std::string, data::GroupGuideRates>& groupGuideRates, const std::unordered_map<std::string, data::GroupGuideRates>& groupGuideRates,
data::GroupData& gdata) const data::GroupData& gdata) const
@ -569,7 +575,8 @@ assignGroupGuideRates(const Group& group,
} }
} }
bool BlackoilWellModelGuideRates:: template<class Scalar>
bool BlackoilWellModelGuideRates<Scalar>::
guideRateUpdateIsNeeded(const int reportStepIdx) const guideRateUpdateIsNeeded(const int reportStepIdx) const
{ {
const auto& genWells = wellModel_.genericWells(); const auto& genWells = wellModel_.genericWells();
@ -595,4 +602,6 @@ guideRateUpdateIsNeeded(const int reportStepIdx) const
return wellModel_.comm().max(static_cast<int>(need_update)); return wellModel_.comm().max(static_cast<int>(need_update));
} }
template class BlackoilWellModelGuideRates<double>;
} // namespace Opm } // namespace Opm

View File

@ -30,7 +30,7 @@
namespace Opm { namespace Opm {
class BlackoilWellModelGeneric; template<class Scalar> class BlackoilWellModelGeneric;
namespace data { namespace data {
struct GroupData; struct GroupData;
struct GroupGuideRates; struct GroupGuideRates;
@ -41,11 +41,12 @@ class Group;
class Well; class Well;
/// Class for handling the guide rates in the blackoil well model. /// Class for handling the guide rates in the blackoil well model.
template<class Scalar>
class BlackoilWellModelGuideRates class BlackoilWellModelGuideRates
{ {
public: public:
//! \brief Constructor initializes reference to the well model. //! \brief Constructor initializes reference to the well model.
BlackoilWellModelGuideRates(const BlackoilWellModelGeneric& wellModel) BlackoilWellModelGuideRates(const BlackoilWellModelGeneric<Scalar>& wellModel)
: wellModel_(wellModel) : wellModel_(wellModel)
{} {}
@ -81,7 +82,7 @@ private:
//! \brief Obtain guide rate values for injection group. //! \brief Obtain guide rate values for injection group.
data::GuideRateValue getGuideRateInjectionGroupValues(const Group& group) const; data::GuideRateValue getGuideRateInjectionGroupValues(const Group& group) const;
const BlackoilWellModelGeneric& wellModel_; //!< Reference to well model const BlackoilWellModelGeneric<Scalar>& wellModel_; //!< Reference to well model
}; };

View File

@ -67,11 +67,12 @@ namespace {
namespace Opm { namespace Opm {
void BlackoilWellModelRestart:: template<class Scalar>
void BlackoilWellModelRestart<Scalar>::
loadRestartConnectionData(const std::vector<data::Rates::opt>& phs, loadRestartConnectionData(const std::vector<data::Rates::opt>& phs,
const data::Well& rst_well, const data::Well& rst_well,
const std::vector<PerforationData>& old_perf_data, const std::vector<PerforationData>& old_perf_data,
SingleWellState<double>& ws) const SingleWellState<Scalar>& ws) const
{ {
auto& perf_data = ws.perf_data; auto& perf_data = ws.perf_data;
auto perf_pressure = perf_data.pressure.begin(); auto perf_pressure = perf_data.pressure.begin();
@ -91,11 +92,12 @@ loadRestartConnectionData(const std::vector<data::Rates::opt>& phs,
} }
} }
void BlackoilWellModelRestart:: template<class Scalar>
void BlackoilWellModelRestart<Scalar>::
loadRestartSegmentData(const std::string& well_name, loadRestartSegmentData(const std::string& well_name,
const std::vector<data::Rates::opt>& phs, const std::vector<data::Rates::opt>& phs,
const data::Well& rst_well, const data::Well& rst_well,
SingleWellState<double>& ws) const SingleWellState<Scalar>& ws) const
{ {
const auto& segment_set = wellModel_.getWellEcl(well_name).getSegments(); const auto& segment_set = wellModel_.getWellEcl(well_name).getSegments();
const auto& rst_segments = rst_well.segments; const auto& rst_segments = rst_well.segments;
@ -122,13 +124,14 @@ loadRestartSegmentData(const std::string& well_name,
} }
} }
void BlackoilWellModelRestart:: template<class Scalar>
void BlackoilWellModelRestart<Scalar>::
loadRestartWellData(const std::string& well_name, loadRestartWellData(const std::string& well_name,
const bool handle_ms_well, const bool handle_ms_well,
const std::vector<data::Rates::opt>& phs, const std::vector<data::Rates::opt>& phs,
const data::Well& rst_well, const data::Well& rst_well,
const std::vector<PerforationData>& old_perf_data, const std::vector<PerforationData>& old_perf_data,
SingleWellState<double>& ws) const SingleWellState<Scalar>& ws) const
{ {
const auto np = phs.size(); const auto np = phs.size();
@ -155,10 +158,11 @@ loadRestartWellData(const std::string& well_name,
} }
} }
void BlackoilWellModelRestart:: template<class Scalar>
void BlackoilWellModelRestart<Scalar>::
loadRestartGroupData(const std::string& group, loadRestartGroupData(const std::string& group,
const data::GroupData& value, const data::GroupData& value,
GroupState<double>& grpState) const GroupState<Scalar>& grpState) const
{ {
using GPMode = Group::ProductionCMode; using GPMode = Group::ProductionCMode;
using GIMode = Group::InjectionCMode; using GIMode = Group::InjectionCMode;
@ -180,7 +184,8 @@ loadRestartGroupData(const std::string& group,
} }
} }
void BlackoilWellModelRestart:: template<class Scalar>
void BlackoilWellModelRestart<Scalar>::
loadRestartGuideRates(const int report_step, loadRestartGuideRates(const int report_step,
const GuideRateModel::Target target, const GuideRateModel::Target target,
const data::Wells& rst_wells, const data::Wells& rst_wells,
@ -196,7 +201,8 @@ loadRestartGuideRates(const int report_step,
} }
} }
void BlackoilWellModelRestart:: template<class Scalar>
void BlackoilWellModelRestart<Scalar>::
loadRestartGuideRates(const int report_step, loadRestartGuideRates(const int report_step,
const GuideRateConfig& config, const GuideRateConfig& config,
const std::map<std::string, data::GroupData>& rst_groups, const std::map<std::string, data::GroupData>& rst_groups,
@ -219,12 +225,13 @@ loadRestartGuideRates(const int report_step,
} }
} }
void BlackoilWellModelRestart:: template<class Scalar>
void BlackoilWellModelRestart<Scalar>::
loadRestartData(const data::Wells& rst_wells, loadRestartData(const data::Wells& rst_wells,
const data::GroupAndNetworkValues& grpNwrkValues, const data::GroupAndNetworkValues& grpNwrkValues,
const bool handle_ms_well, const bool handle_ms_well,
WellState<double>& well_state, WellState<Scalar>& well_state,
GroupState<double>& grpState) const GroupState<Scalar>& grpState) const
{ {
using rt = data::Rates::opt; using rt = data::Rates::opt;
const auto& phases = wellModel_.phaseUsage(); const auto& phases = wellModel_.phaseUsage();
@ -260,4 +267,6 @@ loadRestartData(const data::Wells& rst_wells,
} }
} }
template class BlackoilWellModelRestart<double>;
} // namespace Opm } // namespace Opm

View File

@ -30,7 +30,7 @@
namespace Opm { namespace Opm {
class BlackoilWellModelGeneric; template<class Scalar> class BlackoilWellModelGeneric;
namespace data { namespace data {
struct GroupData; struct GroupData;
class GroupAndNetworkValues; class GroupAndNetworkValues;
@ -44,11 +44,12 @@ template<class Scalar> class SingleWellState;
template<class Scalar> class WellState; template<class Scalar> class WellState;
/// Class for restarting the blackoil well model. /// Class for restarting the blackoil well model.
template<class Scalar>
class BlackoilWellModelRestart class BlackoilWellModelRestart
{ {
public: public:
//! \brief Constructor initializes reference to the well model. //! \brief Constructor initializes reference to the well model.
BlackoilWellModelRestart(const BlackoilWellModelGeneric& wellModel) BlackoilWellModelRestart(const BlackoilWellModelGeneric<Scalar>& wellModel)
: wellModel_(wellModel) : wellModel_(wellModel)
{} {}
@ -68,21 +69,21 @@ public:
void loadRestartData(const data::Wells& rst_wells, void loadRestartData(const data::Wells& rst_wells,
const data::GroupAndNetworkValues& grpNwrkValues, const data::GroupAndNetworkValues& grpNwrkValues,
const bool handle_ms_well, const bool handle_ms_well,
WellState<double>& well_state, WellState<Scalar>& well_state,
GroupState<double>& grpState) const; GroupState<Scalar>& grpState) const;
private: private:
//! \brief Loads per-connection data from restart structures. //! \brief Loads per-connection data from restart structures.
void loadRestartConnectionData(const std::vector<data::Rates::opt>& phs, void loadRestartConnectionData(const std::vector<data::Rates::opt>& phs,
const data::Well& rst_well, const data::Well& rst_well,
const std::vector<PerforationData>& old_perf_data, const std::vector<PerforationData>& old_perf_data,
SingleWellState<double>& ws) const; SingleWellState<Scalar>& ws) const;
//! \brief Loads per-segment data from restart structures. //! \brief Loads per-segment data from restart structures.
void loadRestartSegmentData(const std::string& well_name, void loadRestartSegmentData(const std::string& well_name,
const std::vector<data::Rates::opt>& phs, const std::vector<data::Rates::opt>& phs,
const data::Well& rst_well, const data::Well& rst_well,
SingleWellState<double>& ws) const; SingleWellState<Scalar>& ws) const;
//! \brief Loads per-well data from restart structures. //! \brief Loads per-well data from restart structures.
void loadRestartWellData(const std::string& well_name, void loadRestartWellData(const std::string& well_name,
@ -90,14 +91,14 @@ private:
const std::vector<data::Rates::opt>& phs, const std::vector<data::Rates::opt>& phs,
const data::Well& rst_well, const data::Well& rst_well,
const std::vector<PerforationData>& old_perf_data, const std::vector<PerforationData>& old_perf_data,
SingleWellState<double>& ws) const; SingleWellState<Scalar>& ws) const;
//! \brief Loads per-group data from restart structures. //! \brief Loads per-group data from restart structures.
void loadRestartGroupData(const std::string& group, void loadRestartGroupData(const std::string& group,
const data::GroupData& value, const data::GroupData& value,
GroupState<double>& grpState) const; GroupState<Scalar>& grpState) const;
const BlackoilWellModelGeneric& wellModel_; //!< Reference to well model const BlackoilWellModelGeneric<Scalar>& wellModel_; //!< Reference to well model
}; };

View File

@ -59,15 +59,15 @@ namespace Opm {
template<typename TypeTag> template<typename TypeTag>
BlackoilWellModel<TypeTag>:: BlackoilWellModel<TypeTag>::
BlackoilWellModel(Simulator& simulator, const PhaseUsage& phase_usage) BlackoilWellModel(Simulator& simulator, const PhaseUsage& phase_usage)
: BlackoilWellModelGeneric(simulator.vanguard().schedule(), : BlackoilWellModelGeneric<Scalar>(simulator.vanguard().schedule(),
simulator.vanguard().summaryState(), simulator.vanguard().summaryState(),
simulator.vanguard().eclState(), simulator.vanguard().eclState(),
phase_usage, phase_usage,
simulator.gridView().comm()) simulator.gridView().comm())
, simulator_(simulator) , simulator_(simulator)
{ {
terminal_output_ = ((simulator.gridView().comm().rank() == 0) && this->terminal_output_ = ((simulator.gridView().comm().rank() == 0) &&
Parameters::get<TypeTag, Properties::EnableTerminalOutput>()); Parameters::get<TypeTag, Properties::EnableTerminalOutput>());
local_num_cells_ = simulator_.gridView().size(0); local_num_cells_ = simulator_.gridView().size(0);
@ -90,9 +90,9 @@ namespace Opm {
.localCellIndex([this](const std::size_t globalIndex) .localCellIndex([this](const std::size_t globalIndex)
{ return this->compressedIndexForInterior(globalIndex); }) { return this->compressedIndexForInterior(globalIndex); })
.evalCellSource([this](const int localCell, .evalCellSource([this](const int localCell,
PAvgDynamicSourceData::SourceDataSpan<double> sourceTerms) PAvgDynamicSourceData::SourceDataSpan<Scalar> sourceTerms)
{ {
using Item = PAvgDynamicSourceData::SourceDataSpan<double>::Item; using Item = typename PAvgDynamicSourceData::SourceDataSpan<Scalar>::Item;
const auto* intQuants = this->simulator_.model() const auto* intQuants = this->simulator_.model()
.cachedIntensiveQuantities(localCell, /*timeIndex = */0); .cachedIntensiveQuantities(localCell, /*timeIndex = */0);
@ -146,7 +146,7 @@ namespace Opm {
gravity_ = simulator_.problem().gravity()[2]; gravity_ = simulator_.problem().gravity()[2];
initial_step_ = true; this->initial_step_ = true;
// add the eWoms auxiliary module for the wells to the list // add the eWoms auxiliary module for the wells to the list
simulator_.model().addAuxiliaryModule(this); simulator_.model().addAuxiliaryModule(this);
@ -162,9 +162,9 @@ namespace Opm {
{ {
const uint64_t effective_events_mask = ScheduleEvents::WELL_STATUS_CHANGE const uint64_t effective_events_mask = ScheduleEvents::WELL_STATUS_CHANGE
+ ScheduleEvents::NEW_WELL; + ScheduleEvents::NEW_WELL;
const auto& events = schedule()[reportStepIdx].wellgroup_events(); const auto& events = this->schedule()[reportStepIdx].wellgroup_events();
for (auto& wellPtr : this->well_container_) { for (auto& wellPtr : this->well_container_) {
const bool well_opened_this_step = report_step_starts_ && events.hasEvent(wellPtr->name(), effective_events_mask); const bool well_opened_this_step = this->report_step_starts_ && events.hasEvent(wellPtr->name(), effective_events_mask);
wellPtr->init(&this->phase_usage_, this->depth_, this->gravity_, wellPtr->init(&this->phase_usage_, this->depth_, this->gravity_,
this->local_num_cells_, this->B_avg_, well_opened_this_step); this->local_num_cells_, this->B_avg_, well_opened_this_step);
} }
@ -181,7 +181,7 @@ namespace Opm {
} }
// Create cartesian to compressed mapping // Create cartesian to compressed mapping
const auto& schedule_wells = schedule().getWellsatEnd(); const auto& schedule_wells = this->schedule().getWellsatEnd();
// initialize the additional cell connections introduced by wells. // initialize the additional cell connections introduced by wells.
for (const auto& well : schedule_wells) for (const auto& well : schedule_wells)
@ -419,8 +419,8 @@ namespace Opm {
this->resetWGState(); this->resetWGState();
const int reportStepIdx = simulator_.episodeIndex(); const int reportStepIdx = simulator_.episodeIndex();
updateAndCommunicateGroupData(reportStepIdx, this->updateAndCommunicateGroupData(reportStepIdx,
simulator_.model().newtonMethod().numIterations()); simulator_.model().newtonMethod().numIterations());
this->wellState().updateWellsDefaultALQ(this->wells_ecl_, this->summaryState()); this->wellState().updateWellsDefaultALQ(this->wells_ecl_, this->summaryState());
this->wellState().gliftTimeStepInit(); this->wellState().gliftTimeStepInit();
@ -436,8 +436,7 @@ namespace Opm {
// Wells are active if they are active wells on at least one process. // Wells are active if they are active wells on at least one process.
const Grid& grid = simulator_.vanguard().grid(); const Grid& grid = simulator_.vanguard().grid();
wells_active_ = !this->well_container_.empty(); this->wells_active_ = grid.comm().max(!this->well_container_.empty());
wells_active_ = grid.comm().max(wells_active_);
// do the initialization for all the wells // do the initialization for all the wells
// TODO: to see whether we can postpone of the intialization of the well containers to // TODO: to see whether we can postpone of the intialization of the well containers to
@ -451,29 +450,29 @@ namespace Opm {
} }
// calculate the efficiency factors for each well // calculate the efficiency factors for each well
calculateEfficiencyFactors(reportStepIdx); this->calculateEfficiencyFactors(reportStepIdx);
if constexpr (has_polymer_) if constexpr (has_polymer_)
{ {
if (PolymerModule::hasPlyshlog() || getPropValue<TypeTag, Properties::EnablePolymerMW>() ) { if (PolymerModule::hasPlyshlog() || getPropValue<TypeTag, Properties::EnablePolymerMW>() ) {
setRepRadiusPerfLength(); this->setRepRadiusPerfLength();
} }
} }
} }
OPM_END_PARALLEL_TRY_CATCH_LOG(local_deferredLogger, "beginTimeStep() failed: ", OPM_END_PARALLEL_TRY_CATCH_LOG(local_deferredLogger, "beginTimeStep() failed: ",
terminal_output_, simulator_.vanguard().grid().comm()); this->terminal_output_, simulator_.vanguard().grid().comm());
for (auto& well : well_container_) { for (auto& well : well_container_) {
well->setVFPProperties(vfp_properties_.get()); well->setVFPProperties(this->vfp_properties_.get());
well->setGuideRate(&guideRate_); well->setGuideRate(&this->guideRate_);
} }
this->updateInjFCMult(local_deferredLogger); this->updateInjFCMult(local_deferredLogger);
// Close completions due to economic reasons // Close completions due to economic reasons
for (auto& well : well_container_) { for (auto& well : well_container_) {
well->closeCompletions(wellTestState()); well->closeCompletions(this->wellTestState());
} }
// we need the inj_multiplier from the previous time step // we need the inj_multiplier from the previous time step
@ -501,10 +500,10 @@ namespace Opm {
// calculate the well potentials // calculate the well potentials
try { try {
updateWellPotentials(reportStepIdx, this->updateWellPotentials(reportStepIdx,
/*onlyAfterEvent*/true, /*onlyAfterEvent*/true,
simulator_.vanguard().summaryConfig(), simulator_.vanguard().summaryConfig(),
local_deferredLogger); local_deferredLogger);
} catch ( std::runtime_error& e ) { } catch ( std::runtime_error& e ) {
const std::string msg = "A zero well potential is returned for output purposes. "; const std::string msg = "A zero well potential is returned for output purposes. ";
local_deferredLogger.warning("WELL_POTENTIAL_CALCULATION_FAILED", msg); local_deferredLogger.warning("WELL_POTENTIAL_CALCULATION_FAILED", msg);
@ -512,9 +511,9 @@ namespace Opm {
//update guide rates //update guide rates
const auto& comm = simulator_.vanguard().grid().comm(); const auto& comm = simulator_.vanguard().grid().comm();
std::vector<double> pot(this->numPhases(), 0.0); std::vector<Scalar> pot(this->numPhases(), 0.0);
const Group& fieldGroup = this->schedule().getGroup("FIELD", reportStepIdx); const Group& fieldGroup = this->schedule().getGroup("FIELD", reportStepIdx);
WellGroupHelpers<double>::updateGuideRates(fieldGroup, WellGroupHelpers<Scalar>::updateGuideRates(fieldGroup,
this->schedule(), this->schedule(),
summaryState, summaryState,
this->phase_usage_, this->phase_usage_,
@ -529,12 +528,12 @@ namespace Opm {
std::string exc_msg; std::string exc_msg;
auto exc_type = ExceptionType::NONE; auto exc_type = ExceptionType::NONE;
// update gpmaint targets // update gpmaint targets
if (schedule_[reportStepIdx].has_gpmaint()) { if (this->schedule_[reportStepIdx].has_gpmaint()) {
for (auto& calculator : regionalAveragePressureCalculator_) { for (auto& calculator : regionalAveragePressureCalculator_) {
calculator.second->template defineState<ElementContext>(simulator_); calculator.second->template defineState<ElementContext>(simulator_);
} }
const double dt = simulator_.timeStepSize(); const double dt = simulator_.timeStepSize();
WellGroupHelpers<double>::updateGpMaintTargetForGroups(fieldGroup, WellGroupHelpers<Scalar>::updateGpMaintTargetForGroups(fieldGroup,
this->schedule_, this->schedule_,
regionalAveragePressureCalculator_, regionalAveragePressureCalculator_,
reportStepIdx, reportStepIdx,
@ -550,8 +549,8 @@ namespace Opm {
+ ScheduleEvents::WELL_SWITCHED_INJECTOR_PRODUCER + ScheduleEvents::WELL_SWITCHED_INJECTOR_PRODUCER
+ ScheduleEvents::NEW_WELL; + ScheduleEvents::NEW_WELL;
const auto& events = schedule()[reportStepIdx].wellgroup_events(); const auto& events = this->schedule()[reportStepIdx].wellgroup_events();
const bool event = report_step_starts_ && events.hasEvent(well->name(), effective_events_mask); const bool event = this->report_step_starts_ && events.hasEvent(well->name(), effective_events_mask);
const bool dyn_status_change = this->wellState().well(well->name()).status const bool dyn_status_change = this->wellState().well(well->name()).status
!= this->prevWellState().well(well->name()).status; != this->prevWellState().well(well->name()).status;
@ -576,7 +575,7 @@ namespace Opm {
} }
logAndCheckForExceptionsAndThrow(local_deferredLogger, logAndCheckForExceptionsAndThrow(local_deferredLogger,
exc_type, "beginTimeStep() failed: " + exc_msg, terminal_output_, comm); exc_type, "beginTimeStep() failed: " + exc_msg, this->terminal_output_, comm);
} }
@ -587,24 +586,24 @@ namespace Opm {
DeferredLogger& deferred_logger) DeferredLogger& deferred_logger)
{ {
for (const std::string& well_name : this->getWellsForTesting(timeStepIdx, simulationTime)) { for (const std::string& well_name : this->getWellsForTesting(timeStepIdx, simulationTime)) {
const Well& wellEcl = schedule().getWell(well_name, timeStepIdx); const Well& wellEcl = this->schedule().getWell(well_name, timeStepIdx);
if (wellEcl.getStatus() == Well::Status::SHUT) if (wellEcl.getStatus() == Well::Status::SHUT)
continue; continue;
WellInterfacePtr well = createWellForWellTest(well_name, timeStepIdx, deferred_logger); WellInterfacePtr well = createWellForWellTest(well_name, timeStepIdx, deferred_logger);
// some preparation before the well can be used // some preparation before the well can be used
well->init(&phase_usage_, depth_, gravity_, local_num_cells_, B_avg_, true); well->init(&this->phase_usage_, depth_, gravity_, local_num_cells_, B_avg_, true);
double well_efficiency_factor = wellEcl.getEfficiencyFactor(); Scalar well_efficiency_factor = wellEcl.getEfficiencyFactor();
WellGroupHelpers<double>::accumulateGroupEfficiencyFactor(this->schedule().getGroup(wellEcl.groupName(), WellGroupHelpers<Scalar>::accumulateGroupEfficiencyFactor(this->schedule().getGroup(wellEcl.groupName(),
timeStepIdx), timeStepIdx),
this->schedule(), this->schedule(),
timeStepIdx, timeStepIdx,
well_efficiency_factor); well_efficiency_factor);
well->setWellEfficiencyFactor(well_efficiency_factor); well->setWellEfficiencyFactor(well_efficiency_factor);
well->setVFPProperties(vfp_properties_.get()); well->setVFPProperties(this->vfp_properties_.get());
well->setGuideRate(&guideRate_); well->setGuideRate(&this->guideRate_);
// initialize rates/previous rates to prevent zero fractions in vfp-interpolation // initialize rates/previous rates to prevent zero fractions in vfp-interpolation
if (well->isProducer()) { if (well->isProducer()) {
@ -615,7 +614,8 @@ namespace Opm {
} }
try { try {
well->wellTesting(simulator_, simulationTime, this->wellState(), this->groupState(), wellTestState(), deferred_logger); well->wellTesting(simulator_, simulationTime, this->wellState(),
this->groupState(), this->wellTestState(), deferred_logger);
} catch (const std::exception& e) { } catch (const std::exception& e) {
const std::string msg = fmt::format("Exception during testing of well: {}. The well will not open.\n Exception message: {}", wellEcl.name(), e.what()); const std::string msg = fmt::format("Exception during testing of well: {}. The well will not open.\n Exception message: {}", wellEcl.name(), e.what());
deferred_logger.warning("WELL_TESTING_FAILED", msg); deferred_logger.warning("WELL_TESTING_FAILED", msg);
@ -663,7 +663,7 @@ namespace Opm {
this->closed_this_step_.clear(); this->closed_this_step_.clear();
// time step is finished and we are not any more at the beginning of an report step // time step is finished and we are not any more at the beginning of an report step
report_step_starts_ = false; this->report_step_starts_ = false;
const int reportStepIdx = simulator_.episodeIndex(); const int reportStepIdx = simulator_.episodeIndex();
DeferredLogger local_deferredLogger; DeferredLogger local_deferredLogger;
@ -690,9 +690,9 @@ namespace Opm {
well->reportWellSwitching(this->wellState().well(well->indexOfWell()), local_deferredLogger); well->reportWellSwitching(this->wellState().well(well->indexOfWell()), local_deferredLogger);
} }
// report group switching // report group switching
if (terminal_output_) { if (this->terminal_output_) {
for (const auto& [name, to] : switched_prod_groups_) { for (const auto& [name, to] : this->switched_prod_groups_) {
const Group::ProductionCMode& oldControl = this->prevWGState().group_state.production_control(name); const Group::ProductionCMode& oldControl = this->prevWGState().group_state.production_control(name);
std::string from = Group::ProductionCMode2String(oldControl); std::string from = Group::ProductionCMode2String(oldControl);
if (to != from) { if (to != from) {
@ -703,7 +703,7 @@ namespace Opm {
local_deferredLogger.info(msg); local_deferredLogger.info(msg);
} }
} }
for (const auto& [key, to] : switched_inj_groups_) { for (const auto& [key, to] : this->switched_inj_groups_) {
const std::string& name = key.first; const std::string& name = key.first;
const Opm::Phase& phase = key.second; const Opm::Phase& phase = key.second;
@ -724,23 +724,23 @@ namespace Opm {
// calculate the well potentials // calculate the well potentials
try { try {
updateWellPotentials(reportStepIdx, this->updateWellPotentials(reportStepIdx,
/*onlyAfterEvent*/false, /*onlyAfterEvent*/false,
simulator_.vanguard().summaryConfig(), simulator_.vanguard().summaryConfig(),
local_deferredLogger); local_deferredLogger);
} catch ( std::runtime_error& e ) { } catch ( std::runtime_error& e ) {
const std::string msg = "A zero well potential is returned for output purposes. "; const std::string msg = "A zero well potential is returned for output purposes. ";
local_deferredLogger.warning("WELL_POTENTIAL_CALCULATION_FAILED", msg); local_deferredLogger.warning("WELL_POTENTIAL_CALCULATION_FAILED", msg);
} }
updateWellTestState(simulationTime, wellTestState()); updateWellTestState(simulationTime, this->wellTestState());
// check group sales limits at the end of the timestep // check group sales limits at the end of the timestep
const Group& fieldGroup = schedule_.getGroup("FIELD", reportStepIdx); const Group& fieldGroup = this->schedule_.getGroup("FIELD", reportStepIdx);
checkGEconLimits( this->checkGEconLimits(fieldGroup, simulationTime,
fieldGroup, simulationTime, simulator_.episodeIndex(), local_deferredLogger); simulator_.episodeIndex(), local_deferredLogger);
checkGconsaleLimits(fieldGroup, this->wellState(), this->checkGconsaleLimits(fieldGroup, this->wellState(),
simulator_.episodeIndex(), local_deferredLogger); simulator_.episodeIndex(), local_deferredLogger);
this->calculateProductivityIndexValues(local_deferredLogger); this->calculateProductivityIndexValues(local_deferredLogger);
@ -748,7 +748,7 @@ namespace Opm {
const Opm::Parallel::Communication& comm = grid().comm(); const Opm::Parallel::Communication& comm = grid().comm();
DeferredLogger global_deferredLogger = gatherDeferredLogger(local_deferredLogger, comm); DeferredLogger global_deferredLogger = gatherDeferredLogger(local_deferredLogger, comm);
if (terminal_output_) { if (this->terminal_output_) {
global_deferredLogger.logMessages(); global_deferredLogger.logMessages();
} }
@ -799,7 +799,7 @@ namespace Opm {
BlackoilWellModel<TypeTag>:: BlackoilWellModel<TypeTag>::
initializeWellState(const int timeStepIdx) initializeWellState(const int timeStepIdx)
{ {
std::vector<double> cellPressures(this->local_num_cells_, 0.0); std::vector<Scalar> cellPressures(this->local_num_cells_, 0.0);
ElementContext elemCtx(simulator_); ElementContext elemCtx(simulator_);
const auto& gridView = simulator_.vanguard().gridView(); const auto& gridView = simulator_.vanguard().gridView();
@ -811,7 +811,7 @@ namespace Opm {
const auto& fs = elemCtx.intensiveQuantities(/*spaceIdx=*/0, /*timeIdx=*/0).fluidState(); const auto& fs = elemCtx.intensiveQuantities(/*spaceIdx=*/0, /*timeIdx=*/0).fluidState();
// copy of get perfpressure in Standard well except for value // copy of get perfpressure in Standard well except for value
double& perf_pressure = cellPressures[elemCtx.globalSpaceIndex(/*spaceIdx=*/0, /*timeIdx=*/0)]; Scalar& perf_pressure = cellPressures[elemCtx.globalSpaceIndex(/*spaceIdx=*/0, /*timeIdx=*/0)];
if (Indices::oilEnabled) { if (Indices::oilEnabled) {
perf_pressure = fs.pressure(FluidSystem::oilPhaseIdx).value(); perf_pressure = fs.pressure(FluidSystem::oilPhaseIdx).value();
} else if (Indices::waterEnabled) { } else if (Indices::waterEnabled) {
@ -822,8 +822,9 @@ namespace Opm {
} }
OPM_END_PARALLEL_TRY_CATCH("BlackoilWellModel::initializeWellState() failed: ", simulator_.vanguard().grid().comm()); OPM_END_PARALLEL_TRY_CATCH("BlackoilWellModel::initializeWellState() failed: ", simulator_.vanguard().grid().comm());
this->wellState().init(cellPressures, schedule(), wells_ecl_, local_parallel_well_info_, timeStepIdx, this->wellState().init(cellPressures, this->schedule(), this->wells_ecl_,
&this->prevWellState(), well_perf_data_, this->local_parallel_well_info_, timeStepIdx,
&this->prevWellState(), this->well_perf_data_,
this->summaryState()); this->summaryState());
} }
@ -838,7 +839,7 @@ namespace Opm {
{ {
DeferredLogger local_deferredLogger; DeferredLogger local_deferredLogger;
const int nw = numLocalWells(); const int nw = this->numLocalWells();
well_container_.clear(); well_container_.clear();
@ -846,7 +847,7 @@ namespace Opm {
well_container_.reserve(nw); well_container_.reserve(nw);
for (int w = 0; w < nw; ++w) { for (int w = 0; w < nw; ++w) {
const Well& well_ecl = wells_ecl_[w]; const Well& well_ecl = this->wells_ecl_[w];
if (!well_ecl.hasConnections()) { if (!well_ecl.hasConnections()) {
// No connections in this well. Nothing to do. // No connections in this well. Nothing to do.
@ -875,14 +876,14 @@ namespace Opm {
// a timestep without the well in question, after it caused // a timestep without the well in question, after it caused
// repeated timestep cuts. It should therefore not be opened, // repeated timestep cuts. It should therefore not be opened,
// even if it was new or received new targets this report step. // even if it was new or received new targets this report step.
const bool closed_this_step = (wellTestState().lastTestTime(well_name) == simulator_.time()); const bool closed_this_step = (this->wellTestState().lastTestTime(well_name) == simulator_.time());
// TODO: more checking here, to make sure this standard more specific and complete // TODO: more checking here, to make sure this standard more specific and complete
// maybe there is some WCON keywords will not open the well // maybe there is some WCON keywords will not open the well
auto& events = this->wellState().well(w).events; auto& events = this->wellState().well(w).events;
if (events.hasEvent(ScheduleEvents::REQUEST_OPEN_WELL)) { if (events.hasEvent(ScheduleEvents::REQUEST_OPEN_WELL)) {
if (!closed_this_step) { if (!closed_this_step) {
wellTestState().open_well(well_name); this->wellTestState().open_well(well_name);
wellTestState().open_completions(well_name); this->wellTestState().open_completions(well_name);
} }
events.clearEvent(ScheduleEvents::REQUEST_OPEN_WELL); events.clearEvent(ScheduleEvents::REQUEST_OPEN_WELL);
} }
@ -891,7 +892,7 @@ namespace Opm {
// TODO: should we do this for all kinds of closing reasons? // TODO: should we do this for all kinds of closing reasons?
// something like wellTestState().hasWell(well_name)? // something like wellTestState().hasWell(well_name)?
bool wellIsStopped = false; bool wellIsStopped = false;
if (wellTestState().well_is_closed(well_name)) if (this->wellTestState().well_is_closed(well_name))
{ {
if (well_ecl.getAutomaticShutIn()) { if (well_ecl.getAutomaticShutIn()) {
// shut wells are not added to the well container // shut wells are not added to the well container
@ -913,8 +914,8 @@ namespace Opm {
// shut wells with zero rante constraints and disallowing // shut wells with zero rante constraints and disallowing
if (!well_ecl.getAllowCrossFlow()) { if (!well_ecl.getAllowCrossFlow()) {
const bool any_zero_rate_constraint = well_ecl.isProducer() const bool any_zero_rate_constraint = well_ecl.isProducer()
? well_ecl.productionControls(summaryState_).anyZeroRateConstraint() ? well_ecl.productionControls(this->summaryState_).anyZeroRateConstraint()
: well_ecl.injectionControls(summaryState_).anyZeroRateConstraint(); : well_ecl.injectionControls(this->summaryState_).anyZeroRateConstraint();
if (any_zero_rate_constraint) { if (any_zero_rate_constraint) {
// Treat as shut, do not add to container. // Treat as shut, do not add to container.
local_deferredLogger.debug(fmt::format(" Well {} gets shut due to having zero rate constraint and disallowing crossflow ", well_ecl.name()) ); local_deferredLogger.debug(fmt::format(" Well {} gets shut due to having zero rate constraint and disallowing crossflow ", well_ecl.name()) );
@ -939,26 +940,26 @@ namespace Opm {
const Opm::Parallel::Communication& comm = grid().comm(); const Opm::Parallel::Communication& comm = grid().comm();
DeferredLogger global_deferredLogger = gatherDeferredLogger(local_deferredLogger, comm); DeferredLogger global_deferredLogger = gatherDeferredLogger(local_deferredLogger, comm);
if (terminal_output_) { if (this->terminal_output_) {
global_deferredLogger.logMessages(); global_deferredLogger.logMessages();
} }
well_container_generic_.clear(); this->well_container_generic_.clear();
for (auto& w : well_container_) for (auto& w : well_container_)
well_container_generic_.push_back(w.get()); this->well_container_generic_.push_back(w.get());
const auto& network = schedule()[report_step].network(); const auto& network = this->schedule()[report_step].network();
if (network.active() && !this->node_pressures_.empty()) { if (network.active() && !this->node_pressures_.empty()) {
for (auto& well: well_container_generic_) { for (auto& well: this->well_container_generic_) {
// Producers only, since we so far only support the // Producers only, since we so far only support the
// "extended" network model (properties defined by // "extended" network model (properties defined by
// BRANPROP and NODEPROP) which only applies to producers. // BRANPROP and NODEPROP) which only applies to producers.
if (well->isProducer()) { if (well->isProducer()) {
const auto it = node_pressures_.find(well->wellEcl().groupName()); const auto it = this->node_pressures_.find(well->wellEcl().groupName());
if (it != node_pressures_.end()) { if (it != this->node_pressures_.end()) {
// The well belongs to a group which has a network nodal pressure, // The well belongs to a group which has a network nodal pressure,
// set the dynamic THP constraint based on the network nodal pressure // set the dynamic THP constraint based on the network nodal pressure
const double nodal_pressure = it->second; const Scalar nodal_pressure = it->second;
well->setDynamicThpLimit(nodal_pressure); well->setDynamicThpLimit(nodal_pressure);
} }
} }
@ -1002,7 +1003,7 @@ namespace Opm {
// Cater for case where local part might have no perforations. // Cater for case where local part might have no perforations.
const auto pvtreg = perf_data.empty() const auto pvtreg = perf_data.empty()
? 0 : pvt_region_idx_[perf_data.front().cell_index]; ? 0 : this->pvt_region_idx_[perf_data.front().cell_index];
const auto& parallel_well_info = this->local_parallel_well_info_[wellID].get(); const auto& parallel_well_info = this->local_parallel_well_info_[wellID].get();
const auto global_pvtreg = parallel_well_info.broadcastFirstPerforationValue(pvtreg); const auto global_pvtreg = parallel_well_info.broadcastFirstPerforationValue(pvtreg);
@ -1031,10 +1032,10 @@ namespace Opm {
DeferredLogger& deferred_logger) const DeferredLogger& deferred_logger) const
{ {
// Finding the location of the well in wells_ecl // Finding the location of the well in wells_ecl
const int nw_wells_ecl = wells_ecl_.size(); const int nw_wells_ecl = this->wells_ecl_.size();
int index_well_ecl = 0; int index_well_ecl = 0;
for (; index_well_ecl < nw_wells_ecl; ++index_well_ecl) { for (; index_well_ecl < nw_wells_ecl; ++index_well_ecl) {
if (well_name == wells_ecl_[index_well_ecl].name()) { if (well_name == this->wells_ecl_[index_well_ecl].name()) {
break; break;
} }
} }
@ -1100,22 +1101,22 @@ namespace Opm {
if (this->glift_debug) { if (this->glift_debug) {
const std::string msg = fmt::format( const std::string msg = fmt::format(
"assemble() : iteration {}" , iterationIdx); "assemble() : iteration {}" , iterationIdx);
gliftDebug(msg, local_deferredLogger); this->gliftDebug(msg, local_deferredLogger);
} }
last_report_ = SimulatorReportSingle(); last_report_ = SimulatorReportSingle();
Dune::Timer perfTimer; Dune::Timer perfTimer;
perfTimer.start(); perfTimer.start();
closed_offending_wells_.clear(); this->closed_offending_wells_.clear();
{ {
const int episodeIdx = simulator_.episodeIndex(); const int episodeIdx = simulator_.episodeIndex();
const auto& network = schedule()[episodeIdx].network(); const auto& network = this->schedule()[episodeIdx].network();
if ( !wellsActive() && !network.active() ) { if (!this->wellsActive() && !network.active()) {
return; return;
} }
} }
if (iterationIdx == 0 && wellsActive()) { if (iterationIdx == 0 && this->wellsActive()) {
// try-catch is needed here as updateWellControls // try-catch is needed here as updateWellControls
// contains global communication and has either to // contains global communication and has either to
// be reached by all processes or all need to abort // be reached by all processes or all need to abort
@ -1127,14 +1128,14 @@ namespace Opm {
} }
OPM_END_PARALLEL_TRY_CATCH_LOG(local_deferredLogger, OPM_END_PARALLEL_TRY_CATCH_LOG(local_deferredLogger,
"assemble() failed (It=0): ", "assemble() failed (It=0): ",
terminal_output_, grid().comm()); this->terminal_output_, grid().comm());
} }
const bool well_group_control_changed = updateWellControlsAndNetwork(false, dt, local_deferredLogger); const bool well_group_control_changed = updateWellControlsAndNetwork(false, dt, local_deferredLogger);
// even when there is no wells active, the network nodal pressure still need to be updated through updateWellControlsAndNetwork() // even when there is no wells active, the network nodal pressure still need to be updated through updateWellControlsAndNetwork()
// but there is no need to assemble the well equations // but there is no need to assemble the well equations
if ( ! wellsActive() ) { if ( ! this->wellsActive() ) {
return; return;
} }
@ -1163,7 +1164,7 @@ namespace Opm {
const std::size_t max_iteration = param_.network_max_iterations_; const std::size_t max_iteration = param_.network_max_iterations_;
std::size_t network_update_iteration = 0; std::size_t network_update_iteration = 0;
while (do_network_update) { while (do_network_update) {
if (terminal_output_ && (network_update_iteration == iteration_to_relax) ) { if (this->terminal_output_ && (network_update_iteration == iteration_to_relax) ) {
local_deferredLogger.info(" we begin using relaxed tolerance for network update now after " + std::to_string(iteration_to_relax) + " iterations "); local_deferredLogger.info(" we begin using relaxed tolerance for network update now after " + std::to_string(iteration_to_relax) + " iterations ");
} }
const bool relax_network_balance = network_update_iteration >= iteration_to_relax; const bool relax_network_balance = network_update_iteration >= iteration_to_relax;
@ -1172,7 +1173,7 @@ namespace Opm {
++network_update_iteration; ++network_update_iteration;
if (network_update_iteration >= max_iteration ) { if (network_update_iteration >= max_iteration ) {
if (terminal_output_) { if (this->terminal_output_) {
local_deferredLogger.info("maximum of " + std::to_string(max_iteration) + " iterations has been used, we stop the network update now. " local_deferredLogger.info("maximum of " + std::to_string(max_iteration) + " iterations has been used, we stop the network update now. "
"The simulation will continue with unconverged network results"); "The simulation will continue with unconverged network results");
} }
@ -1207,18 +1208,18 @@ namespace Opm {
prepareWellsBeforeAssembling(dt, local_deferredLogger); prepareWellsBeforeAssembling(dt, local_deferredLogger);
} }
OPM_END_PARALLEL_TRY_CATCH_LOG(local_deferredLogger, "updateWellControlsAndNetworkIteration() failed: ", OPM_END_PARALLEL_TRY_CATCH_LOG(local_deferredLogger, "updateWellControlsAndNetworkIteration() failed: ",
terminal_output_, grid().comm()); this->terminal_output_, grid().comm());
//update guide rates //update guide rates
const int reportStepIdx = simulator_.episodeIndex(); const int reportStepIdx = simulator_.episodeIndex();
if (alq_updated || BlackoilWellModelGuideRates(*this). if (alq_updated || BlackoilWellModelGuideRates(*this).
guideRateUpdateIsNeeded(reportStepIdx)) { guideRateUpdateIsNeeded(reportStepIdx)) {
const double simulationTime = simulator_.time(); const double simulationTime = simulator_.time();
const auto& comm = simulator_.vanguard().grid().comm(); const auto& comm = simulator_.vanguard().grid().comm();
const auto& summaryState = simulator_.vanguard().summaryState(); const auto& summaryState = simulator_.vanguard().summaryState();
std::vector<double> pot(this->numPhases(), 0.0); std::vector<Scalar> pot(this->numPhases(), 0.0);
const Group& fieldGroup = this->schedule().getGroup("FIELD", reportStepIdx); const Group& fieldGroup = this->schedule().getGroup("FIELD", reportStepIdx);
WellGroupHelpers<double>::updateGuideRates(fieldGroup, WellGroupHelpers<Scalar>::updateGuideRates(fieldGroup,
this->schedule(), this->schedule(),
summaryState, summaryState,
this->phase_usage_, this->phase_usage_,
@ -1250,8 +1251,8 @@ namespace Opm {
{ {
const int episodeIdx = simulator_.episodeIndex(); const int episodeIdx = simulator_.episodeIndex();
const auto& network = schedule()[episodeIdx].network(); const auto& network = this->schedule()[episodeIdx].network();
if ( !wellsActive() && !network.active() ) { if (!this->wellsActive() && !network.active()) {
return; return;
} }
} }
@ -1268,7 +1269,7 @@ namespace Opm {
// TODO: errors here must be caught higher up, as this method is not called in parallel. // TODO: errors here must be caught higher up, as this method is not called in parallel.
// We will log errors on rank 0, but not other ranks for now. // We will log errors on rank 0, but not other ranks for now.
if (terminal_output_) { if (this->terminal_output_) {
local_deferredLogger.logMessages(); local_deferredLogger.logMessages();
} }
@ -1285,14 +1286,14 @@ namespace Opm {
bool do_glift_optimization = false; bool do_glift_optimization = false;
int num_wells_changed = 0; int num_wells_changed = 0;
const double simulation_time = simulator_.time(); const double simulation_time = simulator_.time();
const double min_wait = simulator_.vanguard().schedule().glo(simulator_.episodeIndex()).min_wait(); const Scalar min_wait = simulator_.vanguard().schedule().glo(simulator_.episodeIndex()).min_wait();
// We only optimize if a min_wait time has past. // We only optimize if a min_wait time has past.
// If all_newton is true we still want to optimize several times pr timestep // If all_newton is true we still want to optimize several times pr timestep
// i.e. we also optimize if check simulation_time == last_glift_opt_time_ // i.e. we also optimize if check simulation_time == last_glift_opt_time_
// that is when the last_glift_opt_time is already updated with the current time step // that is when the last_glift_opt_time is already updated with the current time step
if ( simulation_time == last_glift_opt_time_ || simulation_time >= (last_glift_opt_time_ + min_wait)) { if ( simulation_time == this->last_glift_opt_time_ || simulation_time >= (this->last_glift_opt_time_ + min_wait)) {
do_glift_optimization = true; do_glift_optimization = true;
last_glift_opt_time_ = simulation_time; this->last_glift_opt_time_ = simulation_time;
} }
if (do_glift_optimization) { if (do_glift_optimization) {
@ -1314,7 +1315,7 @@ namespace Opm {
simulator_.vanguard().summaryState(), simulator_.vanguard().summaryState(),
simulator_.episodeIndex(), simulator_.episodeIndex(),
simulator_.model().newtonMethod().numIterations(), simulator_.model().newtonMethod().numIterations(),
phase_usage_, this->phase_usage_,
deferred_logger, deferred_logger,
this->wellState(), this->wellState(),
this->groupState(), this->groupState(),
@ -1322,12 +1323,13 @@ namespace Opm {
this->glift_debug this->glift_debug
}; };
group_info.initialize(); group_info.initialize();
gasLiftOptimizationStage1( gasLiftOptimizationStage1(deferred_logger, prod_wells, glift_wells,
deferred_logger, prod_wells, glift_wells, group_info, state_map); group_info, state_map);
gasLiftOptimizationStage2( this->gasLiftOptimizationStage2(deferred_logger, prod_wells, glift_wells,
deferred_logger, prod_wells, glift_wells, group_info, state_map, group_info, state_map, simulator_.episodeIndex());
simulator_.episodeIndex()); if (this->glift_debug) {
if (this->glift_debug) gliftDebugShowALQ(deferred_logger); this->gliftDebugShowALQ(deferred_logger);
}
num_wells_changed = glift_wells.size(); num_wells_changed = glift_wells.size();
} }
num_wells_changed = this->comm_.sum(num_wells_changed); num_wells_changed = this->comm_.sum(num_wells_changed);
@ -1388,13 +1390,13 @@ namespace Opm {
if (num_rates_to_sync > 0) { if (num_rates_to_sync > 0) {
std::vector<int> group_indexes; std::vector<int> group_indexes;
group_indexes.reserve(num_rates_to_sync); group_indexes.reserve(num_rates_to_sync);
std::vector<double> group_alq_rates; std::vector<Scalar> group_alq_rates;
group_alq_rates.reserve(num_rates_to_sync); group_alq_rates.reserve(num_rates_to_sync);
std::vector<double> group_oil_rates; std::vector<Scalar> group_oil_rates;
group_oil_rates.reserve(num_rates_to_sync); group_oil_rates.reserve(num_rates_to_sync);
std::vector<double> group_gas_rates; std::vector<Scalar> group_gas_rates;
group_gas_rates.reserve(num_rates_to_sync); group_gas_rates.reserve(num_rates_to_sync);
std::vector<double> group_water_rates; std::vector<Scalar> group_water_rates;
group_water_rates.reserve(num_rates_to_sync); group_water_rates.reserve(num_rates_to_sync);
if (comm.rank() == i) { if (comm.rank() == i) {
for (auto idx : groups_to_sync) { for (auto idx : groups_to_sync) {
@ -1527,7 +1529,7 @@ namespace Opm {
deferred_logger); deferred_logger);
} }
OPM_END_PARALLEL_TRY_CATCH_LOG(deferred_logger, "BlackoilWellModel::assembleWellEqWithoutIteration failed: ", OPM_END_PARALLEL_TRY_CATCH_LOG(deferred_logger, "BlackoilWellModel::assembleWellEqWithoutIteration failed: ",
terminal_output_, grid().comm()); this->terminal_output_, grid().comm());
} }
@ -1678,7 +1680,7 @@ namespace Opm {
int wdof = rdofs + i; int wdof = rdofs + i;
jacobian.entry(wdof,wdof) = 1.0;// better scaling ? jacobian.entry(wdof,wdof) = 1.0;// better scaling ?
} }
std::vector<std::vector<int>> wellconnections = getMaxWellConnections(); std::vector<std::vector<int>> wellconnections = this->getMaxWellConnections();
for(int i=0; i < nw; i++){ for(int i=0; i < nw; i++){
const auto& perfcells = wellconnections[i]; const auto& perfcells = wellconnections[i];
for(int perfcell : perfcells){ for(int perfcell : perfcells){
@ -1705,7 +1707,7 @@ namespace Opm {
} }
OPM_END_PARALLEL_TRY_CATCH_LOG(local_deferredLogger, OPM_END_PARALLEL_TRY_CATCH_LOG(local_deferredLogger,
"recoverWellSolutionAndUpdateWellState() failed: ", "recoverWellSolutionAndUpdateWellState() failed: ",
terminal_output_, simulator_.vanguard().grid().comm()); this->terminal_output_, simulator_.vanguard().grid().comm());
} }
@ -1728,7 +1730,7 @@ namespace Opm {
} }
// TODO: avoid losing the logging information that could // TODO: avoid losing the logging information that could
// be stored in the local_deferredlogger in a parallel case. // be stored in the local_deferredlogger in a parallel case.
if (terminal_output_) { if (this->terminal_output_) {
local_deferredLogger.logMessages(); local_deferredLogger.logMessages();
} }
} }
@ -1792,7 +1794,7 @@ namespace Opm {
} }
// Log debug messages for NaN or too large residuals. // Log debug messages for NaN or too large residuals.
if (terminal_output_) { if (this->terminal_output_) {
for (const auto& f : report.wellFailures()) { for (const auto& f : report.wellFailures()) {
if (f.severity() == ConvergenceReport::Severity::NotANumber) { if (f.severity() == ConvergenceReport::Severity::NotANumber) {
local_deferredLogger.debug("NaN residual found with phase " + std::to_string(f.phase()) + " for well " + f.wellName()); local_deferredLogger.debug("NaN residual found with phase " + std::to_string(f.phase()) + " for well " + f.wellName());
@ -1841,11 +1843,11 @@ namespace Opm {
report.setWellGroupTargetsViolated(this->lastReport().well_group_control_changed); report.setWellGroupTargetsViolated(this->lastReport().well_group_control_changed);
} }
if (terminal_output_) { if (this->terminal_output_) {
global_deferredLogger.logMessages(); global_deferredLogger.logMessages();
} }
// Log debug messages for NaN or too large residuals. // Log debug messages for NaN or too large residuals.
if (terminal_output_) { if (this->terminal_output_) {
for (const auto& f : report.wellFailures()) { for (const auto& f : report.wellFailures()) {
if (f.severity() == ConvergenceReport::Severity::NotANumber) { if (f.severity() == ConvergenceReport::Severity::NotANumber) {
OpmLog::debug("NaN residual found with phase " + std::to_string(f.phase()) + " for well " + f.wellName()); OpmLog::debug("NaN residual found with phase " + std::to_string(f.phase()) + " for well " + f.wellName());
@ -1882,33 +1884,33 @@ namespace Opm {
updateWellControls(const bool mandatory_network_balance, DeferredLogger& deferred_logger, const bool relax_network_tolerance) updateWellControls(const bool mandatory_network_balance, DeferredLogger& deferred_logger, const bool relax_network_tolerance)
{ {
const int episodeIdx = simulator_.episodeIndex(); const int episodeIdx = simulator_.episodeIndex();
const auto& network = schedule()[episodeIdx].network(); const auto& network = this->schedule()[episodeIdx].network();
if (!wellsActive() && !network.active()) { if (!this->wellsActive() && !network.active()) {
return {false, false}; return {false, false};
} }
const int iterationIdx = simulator_.model().newtonMethod().numIterations(); const int iterationIdx = simulator_.model().newtonMethod().numIterations();
const auto& comm = simulator_.vanguard().grid().comm(); const auto& comm = simulator_.vanguard().grid().comm();
updateAndCommunicateGroupData(episodeIdx, iterationIdx); this->updateAndCommunicateGroupData(episodeIdx, iterationIdx);
// network related // network related
bool more_network_update = false; bool more_network_update = false;
if (shouldBalanceNetwork(episodeIdx, iterationIdx) || mandatory_network_balance) { if (this->shouldBalanceNetwork(episodeIdx, iterationIdx) || mandatory_network_balance) {
const auto local_network_imbalance = updateNetworkPressures(episodeIdx); const auto local_network_imbalance = this->updateNetworkPressures(episodeIdx);
const double network_imbalance = comm.max(local_network_imbalance); const Scalar network_imbalance = comm.max(local_network_imbalance);
const auto& balance = schedule()[episodeIdx].network_balance(); const auto& balance = this->schedule()[episodeIdx].network_balance();
constexpr double relaxtion_factor = 10.0; constexpr Scalar relaxation_factor = 10.0;
const double tolerance = relax_network_tolerance ? relaxtion_factor * balance.pressure_tolerance() : balance.pressure_tolerance(); const Scalar tolerance = relax_network_tolerance ? relaxation_factor * balance.pressure_tolerance() : balance.pressure_tolerance();
more_network_update = this->networkActive() && network_imbalance > tolerance; more_network_update = this->networkActive() && network_imbalance > tolerance;
} }
bool changed_well_group = false; bool changed_well_group = false;
// Check group individual constraints. // Check group individual constraints.
const int nupcol = schedule()[episodeIdx].nupcol(); const int nupcol = this->schedule()[episodeIdx].nupcol();
// don't switch group control when iterationIdx > nupcol // don't switch group control when iterationIdx > nupcol
// to avoid oscilations between group controls // to avoid oscilations between group controls
if (iterationIdx <= nupcol) { if (iterationIdx <= nupcol) {
const Group& fieldGroup = schedule().getGroup("FIELD", episodeIdx); const Group& fieldGroup = this->schedule().getGroup("FIELD", episodeIdx);
changed_well_group = updateGroupControls(fieldGroup, deferred_logger, episodeIdx, iterationIdx); changed_well_group = updateGroupControls(fieldGroup, deferred_logger, episodeIdx, iterationIdx);
} }
// Check wells' group constraints and communicate. // Check wells' group constraints and communicate.
@ -1958,8 +1960,8 @@ namespace Opm {
} }
// update wsolvent fraction for REIN wells // update wsolvent fraction for REIN wells
const Group& fieldGroup = schedule().getGroup("FIELD", episodeIdx); const Group& fieldGroup = this->schedule().getGroup("FIELD", episodeIdx);
updateWsolvent(fieldGroup, episodeIdx, this->nupcolWellState()); this->updateWsolvent(fieldGroup, episodeIdx, this->nupcolWellState());
return { changed_well_group, more_network_update }; return { changed_well_group, more_network_update };
} }
@ -1969,7 +1971,7 @@ namespace Opm {
BlackoilWellModel<TypeTag>:: BlackoilWellModel<TypeTag>::
updateWellControlsDomain(DeferredLogger& deferred_logger, const Domain& domain) updateWellControlsDomain(DeferredLogger& deferred_logger, const Domain& domain)
{ {
if ( !wellsActive() ) return ; if ( !this->wellsActive() ) return ;
// TODO: decide on and implement an approach to handling of // TODO: decide on and implement an approach to handling of
// group controls, network and similar for domain solves. // group controls, network and similar for domain solves.
@ -2066,7 +2068,7 @@ namespace Opm {
BlackoilWellModel<TypeTag>:: BlackoilWellModel<TypeTag>::
makeWellSourceEvaluatorFactory(const std::vector<Well>::size_type wellIdx) const makeWellSourceEvaluatorFactory(const std::vector<Well>::size_type wellIdx) const
{ {
using Span = PAvgDynamicSourceData::SourceDataSpan<double>; using Span = PAvgDynamicSourceData::SourceDataSpan<Scalar>;
using Item = typename Span::Item; using Item = typename Span::Item;
return [wellIdx, this]() -> ParallelWBPCalculation::Evaluator return [wellIdx, this]() -> ParallelWBPCalculation::Evaluator
@ -2140,18 +2142,19 @@ namespace Opm {
const int iterationIdx, const int iterationIdx,
DeferredLogger& deferred_logger) DeferredLogger& deferred_logger)
{ {
updateAndCommunicateGroupData(reportStepIdx, iterationIdx); this->updateAndCommunicateGroupData(reportStepIdx, iterationIdx);
// updateWellStateWithTarget might throw for multisegment wells hence we // updateWellStateWithTarget might throw for multisegment wells hence we
// have a parallel try catch here to thrown on all processes. // have a parallel try catch here to thrown on all processes.
OPM_BEGIN_PARALLEL_TRY_CATCH() OPM_BEGIN_PARALLEL_TRY_CATCH()
// if a well or group change control it affects all wells that are under the same group // if a well or group change control it affects all wells that are under the same group
for (const auto& well : well_container_) { for (const auto& well : well_container_) {
well->updateWellStateWithTarget(simulator_, this->groupState(), this->wellState(), deferred_logger); well->updateWellStateWithTarget(simulator_, this->groupState(),
this->wellState(), deferred_logger);
} }
OPM_END_PARALLEL_TRY_CATCH("BlackoilWellModel::updateAndCommunicate failed: ", OPM_END_PARALLEL_TRY_CATCH("BlackoilWellModel::updateAndCommunicate failed: ",
simulator_.gridView().comm()) simulator_.gridView().comm())
updateAndCommunicateGroupData(reportStepIdx, iterationIdx); this->updateAndCommunicateGroupData(reportStepIdx, iterationIdx);
} }
template<typename TypeTag> template<typename TypeTag>
@ -2163,7 +2166,7 @@ namespace Opm {
const int iterationIdx) const int iterationIdx)
{ {
bool changed = false; bool changed = false;
bool changed_hc = checkGroupHigherConstraints( group, deferred_logger, reportStepIdx); bool changed_hc = this->checkGroupHigherConstraints( group, deferred_logger, reportStepIdx);
if (changed_hc) { if (changed_hc) {
changed = true; changed = true;
updateAndCommunicate(reportStepIdx, iterationIdx, deferred_logger); updateAndCommunicate(reportStepIdx, iterationIdx, deferred_logger);
@ -2186,7 +2189,7 @@ namespace Opm {
} }
// call recursively down the group hierarchy // call recursively down the group hierarchy
for (const std::string& groupName : group.groups()) { for (const std::string& groupName : group.groups()) {
bool changed_this = updateGroupControls( schedule().getGroup(groupName, reportStepIdx), deferred_logger, reportStepIdx,iterationIdx); bool changed_this = updateGroupControls( this->schedule().getGroup(groupName, reportStepIdx), deferred_logger, reportStepIdx,iterationIdx);
changed = changed || changed_this; changed = changed || changed_this;
} }
return changed; return changed;
@ -2212,28 +2215,23 @@ namespace Opm {
const Opm::Parallel::Communication comm = grid().comm(); const Opm::Parallel::Communication comm = grid().comm();
DeferredLogger global_deferredLogger = gatherDeferredLogger(local_deferredLogger, comm); DeferredLogger global_deferredLogger = gatherDeferredLogger(local_deferredLogger, comm);
for (const auto& [group_name, to] : closed_offending_wells_) { for (const auto& [group_name, to] : this->closed_offending_wells_) {
if (!this->wasDynamicallyShutThisTimeStep(to.second)) { if (!this->wasDynamicallyShutThisTimeStep(to.second)) {
wellTestState.close_well( wellTestState.close_well(to.second, WellTestConfig::Reason::GROUP, simulationTime);
to.second, WellTestConfig::Reason::GROUP, simulationTime);
this->updateClosedWellsThisStep(to.second); this->updateClosedWellsThisStep(to.second);
std::string msg = fmt::format("Procedure on exceeding {} limit is WELL for group {}. Well {} is {}.", const std::string msg =
to.first, fmt::format("Procedure on exceeding {} limit is WELL for group {}. Well {} is {}.",
group_name, to.first,
to.second, group_name,
"shut"); to.second,
"shut");
global_deferredLogger.info(msg); global_deferredLogger.info(msg);
} }
} }
if (terminal_output_) { if (this->terminal_output_) {
global_deferredLogger.logMessages(); global_deferredLogger.logMessages();
} }
} }
@ -2245,8 +2243,8 @@ namespace Opm {
ExceptionType::ExcEnum& exc_type, ExceptionType::ExcEnum& exc_type,
DeferredLogger& deferred_logger) DeferredLogger& deferred_logger)
{ {
const int np = numPhases(); const int np = this->numPhases();
std::vector<double> potentials; std::vector<Scalar> potentials;
const auto& well = well_container_[widx]; const auto& well = well_container_[widx];
std::string cur_exc_msg; std::string cur_exc_msg;
auto cur_exc_type = ExceptionType::NONE; auto cur_exc_type = ExceptionType::NONE;
@ -2445,9 +2443,9 @@ namespace Opm {
const auto& eclProblem = simulator_.problem(); const auto& eclProblem = simulator_.problem();
const unsigned numCells = grid.size(/*codim=*/0); const unsigned numCells = grid.size(/*codim=*/0);
pvt_region_idx_.resize(numCells); this->pvt_region_idx_.resize(numCells);
for (unsigned cellIdx = 0; cellIdx < numCells; ++cellIdx) { for (unsigned cellIdx = 0; cellIdx < numCells; ++cellIdx) {
pvt_region_idx_[cellIdx] = this->pvt_region_idx_[cellIdx] =
eclProblem.pvtRegionIndex(cellIdx); eclProblem.pvtRegionIndex(cellIdx);
} }
} }
@ -2463,7 +2461,7 @@ namespace Opm {
// in the well equations. As a result, for an oil-water-polymer system, this function will return 2. // in the well equations. As a result, for an oil-water-polymer system, this function will return 2.
// In some way, it makes this function appear to be confusing from its name, and we need // In some way, it makes this function appear to be confusing from its name, and we need
// to revisit/revise this function again when extending the variants of system that flow can simulate. // to revisit/revise this function again when extending the variants of system that flow can simulate.
int numComp = numPhases() < 3? numPhases(): FluidSystem::numComponents; int numComp = this->numPhases() < 3 ? this->numPhases() : FluidSystem::numComponents;
if constexpr (has_solvent_) { if constexpr (has_solvent_) {
numComp++; numComp++;
} }
@ -2530,8 +2528,8 @@ namespace Opm {
BlackoilWellModel<TypeTag>:: BlackoilWellModel<TypeTag>::
calcRates(const int fipnum, calcRates(const int fipnum,
const int pvtreg, const int pvtreg,
const std::vector<double>& production_rates, const std::vector<Scalar>& production_rates,
std::vector<double>& resv_coeff) std::vector<Scalar>& resv_coeff)
{ {
rateConverter_->calcCoeff(fipnum, pvtreg, production_rates, resv_coeff); rateConverter_->calcCoeff(fipnum, pvtreg, production_rates, resv_coeff);
} }
@ -2540,8 +2538,8 @@ namespace Opm {
void void
BlackoilWellModel<TypeTag>:: BlackoilWellModel<TypeTag>::
calcInjRates(const int fipnum, calcInjRates(const int fipnum,
const int pvtreg, const int pvtreg,
std::vector<double>& resv_coeff) std::vector<Scalar>& resv_coeff)
{ {
rateConverter_->calcInjCoeff(fipnum, pvtreg, resv_coeff); rateConverter_->calcInjCoeff(fipnum, pvtreg, resv_coeff);
} }
@ -2555,35 +2553,35 @@ namespace Opm {
if (!has_energy_) if (!has_energy_)
return; return;
int np = numPhases(); int np = this->numPhases();
double cellInternalEnergy; Scalar cellInternalEnergy;
double cellBinv; Scalar cellBinv;
double cellDensity; Scalar cellDensity;
double perfPhaseRate; Scalar perfPhaseRate;
const int nw = numLocalWells(); const int nw = this->numLocalWells();
for (auto wellID = 0*nw; wellID < nw; ++wellID) { for (auto wellID = 0*nw; wellID < nw; ++wellID) {
const Well& well = wells_ecl_[wellID]; const Well& well = this->wells_ecl_[wellID];
if (well.isInjector()) if (well.isInjector())
continue; continue;
std::array<double,2> weighted{0.0,0.0}; std::array<Scalar,2> weighted{0.0,0.0};
auto& [weighted_temperature, total_weight] = weighted; auto& [weighted_temperature, total_weight] = weighted;
auto& well_info = local_parallel_well_info_[wellID].get(); auto& well_info = this->local_parallel_well_info_[wellID].get();
auto& ws = this->wellState().well(wellID); auto& ws = this->wellState().well(wellID);
auto& perf_data = ws.perf_data; auto& perf_data = ws.perf_data;
auto& perf_phase_rate = perf_data.phase_rates; auto& perf_phase_rate = perf_data.phase_rates;
using int_type = decltype(well_perf_data_[wellID].size()); using int_type = decltype(this->well_perf_data_[wellID].size());
for (int_type perf = 0, end_perf = well_perf_data_[wellID].size(); perf < end_perf; ++perf) { for (int_type perf = 0, end_perf = this->well_perf_data_[wellID].size(); perf < end_perf; ++perf) {
const int cell_idx = well_perf_data_[wellID][perf].cell_index; const int cell_idx = this->well_perf_data_[wellID][perf].cell_index;
const auto& intQuants = simulator_.model().intensiveQuantities(cell_idx, /*timeIdx=*/0); const auto& intQuants = simulator_.model().intensiveQuantities(cell_idx, /*timeIdx=*/0);
const auto& fs = intQuants.fluidState(); const auto& fs = intQuants.fluidState();
// we on only have one temperature pr cell any phaseIdx will do // we on only have one temperature pr cell any phaseIdx will do
double cellTemperatures = fs.temperature(/*phaseIdx*/0).value(); Scalar cellTemperatures = fs.temperature(/*phaseIdx*/0).value();
double weight_factor = 0.0; Scalar weight_factor = 0.0;
for (unsigned phaseIdx = 0; phaseIdx < FluidSystem::numPhases; ++phaseIdx) for (unsigned phaseIdx = 0; phaseIdx < FluidSystem::numPhases; ++phaseIdx)
{ {
if (!FluidSystem::phaseIsActive(phaseIdx)) { if (!FluidSystem::phaseIsActive(phaseIdx)) {
@ -2613,7 +2611,7 @@ namespace Opm {
for (const auto& w : well_container_) { for (const auto& w : well_container_) {
os << w->name() << ":"; os << w->name() << ":";
auto pv = w->getPrimaryVars(); auto pv = w->getPrimaryVars();
for (const double v : pv) { for (const Scalar v : pv) {
os << ' ' << v; os << ' ' << v;
} }
os << '\n'; os << '\n';
@ -2624,11 +2622,11 @@ namespace Opm {
template <typename TypeTag> template <typename TypeTag>
std::vector<double> std::vector<typename BlackoilWellModel<TypeTag>::Scalar>
BlackoilWellModel<TypeTag>:: BlackoilWellModel<TypeTag>::
getPrimaryVarsDomain(const Domain& domain) const getPrimaryVarsDomain(const Domain& domain) const
{ {
std::vector<double> ret; std::vector<Scalar> ret;
for (const auto& well : well_container_) { for (const auto& well : well_container_) {
if (well_domain_.at(well->name()) == domain.index) { if (well_domain_.at(well->name()) == domain.index) {
const auto& pv = well->getPrimaryVars(); const auto& pv = well->getPrimaryVars();
@ -2643,7 +2641,7 @@ namespace Opm {
template <typename TypeTag> template <typename TypeTag>
void void
BlackoilWellModel<TypeTag>:: BlackoilWellModel<TypeTag>::
setPrimaryVarsDomain(const Domain& domain, const std::vector<double>& vars) setPrimaryVarsDomain(const Domain& domain, const std::vector<Scalar>& vars)
{ {
std::size_t offset = 0; std::size_t offset = 0;
for (auto& well : well_container_) { for (auto& well : well_container_) {
@ -2708,7 +2706,7 @@ namespace Opm {
local_log.debug(os.str()); local_log.debug(os.str());
} }
auto global_log = gatherDeferredLogger(local_log, comm); auto global_log = gatherDeferredLogger(local_log, comm);
if (terminal_output_) { if (this->terminal_output_) {
global_log.logMessages(); global_log.logMessages();
} }
} }

View File

@ -54,7 +54,7 @@ std::string simTimeToString(const std::time_t start_time, const double sim_time)
template<class Scalar> template<class Scalar>
GroupEconomicLimitsChecker<Scalar>:: GroupEconomicLimitsChecker<Scalar>::
GroupEconomicLimitsChecker(const BlackoilWellModelGeneric& well_model, GroupEconomicLimitsChecker(const BlackoilWellModelGeneric<Scalar>& well_model,
WellTestState& well_test_state, WellTestState& well_test_state,
const Group& group, const Group& group,
const double simulation_time, const double simulation_time,

View File

@ -31,7 +31,7 @@
namespace Opm namespace Opm
{ {
class BlackoilWellModelGeneric; template<class Scalar> class BlackoilWellModelGeneric;
class DeferredLogger; class DeferredLogger;
class Group; class Group;
template<class Scalar> class WellState; template<class Scalar> class WellState;
@ -41,7 +41,7 @@ template<class Scalar>
class GroupEconomicLimitsChecker class GroupEconomicLimitsChecker
{ {
public: public:
GroupEconomicLimitsChecker(const BlackoilWellModelGeneric& well_model, GroupEconomicLimitsChecker(const BlackoilWellModelGeneric<Scalar>& well_model,
WellTestState& well_test_state, WellTestState& well_test_state,
const Group& group, const Group& group,
const double simulation_time, const double simulation_time,
@ -73,7 +73,7 @@ private:
bool closeWellsRecursive(const Group& group, int level = 0); bool closeWellsRecursive(const Group& group, int level = 0);
void throwNotImplementedError(const std::string& error) const; void throwNotImplementedError(const std::string& error) const;
const BlackoilWellModelGeneric& well_model_; const BlackoilWellModelGeneric<Scalar>& well_model_;
const Group& group_; const Group& group_;
const double simulation_time_; const double simulation_time_;
const int report_step_idx_; const int report_step_idx_;

View File

@ -259,7 +259,7 @@ BOOST_AUTO_TEST_CASE(EclGenericProblem)
namespace Opm { namespace Opm {
class BlackoilWellModelGenericTest : public BlackoilWellModelGeneric class BlackoilWellModelGenericTest : public BlackoilWellModelGeneric<double>
{ {
public: public:
BlackoilWellModelGenericTest(Schedule& schedule, BlackoilWellModelGenericTest(Schedule& schedule,
@ -268,8 +268,8 @@ public:
const PhaseUsage& phase_usage, const PhaseUsage& phase_usage,
const Parallel::Communication& comm, const Parallel::Communication& comm,
bool deserialize) bool deserialize)
: BlackoilWellModelGeneric(schedule, summaryState, : BlackoilWellModelGeneric<double>(schedule, summaryState,
eclState, phase_usage, comm) eclState, phase_usage, comm)
{ {
if (deserialize) { if (deserialize) {
active_wgstate_.well_state = WellState<double>(dummy); active_wgstate_.well_state = WellState<double>(dummy);