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,
Action::State& actionState,
SummaryState& summaryState,
BlackoilWellModelGeneric& wellModel,
BlackoilWellModelGeneric<double>& wellModel,
Parallel::Communication comm)
: ecl_state_(ecl_state)
, schedule_(schedule)

View File

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

View File

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

View File

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

View File

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

View File

@ -76,7 +76,8 @@
namespace Opm {
BlackoilWellModelGeneric::
template<class Scalar>
BlackoilWellModelGeneric<Scalar>::
BlackoilWellModelGeneric(Schedule& schedule,
const SummaryState& summaryState,
const EclipseState& eclState,
@ -115,22 +116,22 @@ BlackoilWellModelGeneric(Schedule& schedule,
}
}
int
BlackoilWellModelGeneric::
template<class Scalar>
int BlackoilWellModelGeneric<Scalar>::
numLocalWells() const
{
return wells_ecl_.size();
}
int
BlackoilWellModelGeneric::
template<class Scalar>
int BlackoilWellModelGeneric<Scalar>::
numPhases() const
{
return phase_usage_.num_phases;
}
bool
BlackoilWellModelGeneric::
template<class Scalar>
bool BlackoilWellModelGeneric<Scalar>::
hasWell(const std::string& wname) const
{
return std::any_of(this->wells_ecl_.begin(), this->wells_ecl_.end(),
@ -140,22 +141,22 @@ hasWell(const std::string& wname) const
});
}
bool
BlackoilWellModelGeneric::
template<class Scalar>
bool BlackoilWellModelGeneric<Scalar>::
wellsActive() const
{
return wells_active_;
}
bool
BlackoilWellModelGeneric::
template<class Scalar>
bool BlackoilWellModelGeneric<Scalar>::
networkActive() const
{
return network_active_;
}
bool
BlackoilWellModelGeneric::
template<class Scalar>
bool BlackoilWellModelGeneric<Scalar>::
anyMSWellOpenLocal() const
{
for (const auto& well : wells_ecl_) {
@ -166,8 +167,8 @@ anyMSWellOpenLocal() const
return false;
}
const Well&
BlackoilWellModelGeneric::
template<class Scalar>
const Well& BlackoilWellModelGeneric<Scalar>::
getWellEcl(const std::string& well_name) const
{
// finding the iterator of the well in wells_ecl
@ -182,8 +183,8 @@ getWellEcl(const std::string& well_name) const
return *well_ecl;
}
void
BlackoilWellModelGeneric::
template<class Scalar>
void BlackoilWellModelGeneric<Scalar>::
initFromRestartFile(const RestartValue& restartValues,
WellTestState wtestState,
const std::size_t numCells,
@ -210,22 +211,27 @@ initFromRestartFile(const RestartValue& restartValues,
this->schedule(), handle_ms_well, numCells,
this->well_perf_data_, this->summaryState_);
BlackoilWellModelRestart(*this).loadRestartData(restartValues.wells,
restartValues.grp_nwrk,
handle_ms_well,
this->wellState(),
this->groupState());
BlackoilWellModelRestart(*this).
loadRestartData(restartValues.wells,
restartValues.grp_nwrk,
handle_ms_well,
this->wellState(),
this->groupState());
if (config.has_model()) {
BlackoilWellModelRestart(*this).loadRestartGuideRates(report_step,
config.model().target(),
restartValues.wells,
this->guideRate_);
BlackoilWellModelRestart(*this).
loadRestartGuideRates(report_step,
config.model().target(),
restartValues.wells,
this->guideRate_);
}
BlackoilWellModelRestart(*this).loadRestartGuideRates(report_step,
config,
restartValues.grp_nwrk.groupData,
this->guideRate_);
if (config.has_model()) {
BlackoilWellModelRestart(*this).
loadRestartGuideRates(report_step,
config,
restartValues.grp_nwrk.groupData,
this->guideRate_);
this->guideRate_.updateGuideRateExpiration(this->schedule().seconds(report_step), report_step);
}
@ -235,8 +241,8 @@ initFromRestartFile(const RestartValue& restartValues,
initial_step_ = false;
}
void
BlackoilWellModelGeneric::
template<class Scalar>
void BlackoilWellModelGeneric<Scalar>::
prepareDeserialize(int report_step, const std::size_t numCells, bool handle_ms_well)
{
// 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();
}
std::vector<Well>
BlackoilWellModelGeneric::
template<class Scalar>
std::vector<Well> BlackoilWellModelGeneric<Scalar>::
getLocalWells(const int timeStepIdx) const
{
auto w = schedule().getWells(timeStepIdx);
@ -267,8 +273,9 @@ getLocalWells(const int timeStepIdx) const
return w;
}
template<class Scalar>
std::vector<std::reference_wrapper<ParallelWellInfo>>
BlackoilWellModelGeneric::
BlackoilWellModelGeneric<Scalar>::
createLocalParallelWellInfo(const std::vector<Well>& wells)
{
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;
}
void
BlackoilWellModelGeneric::
template<class Scalar>
void BlackoilWellModelGeneric<Scalar>::
initializeWellProdIndCalculators()
{
this->prod_index_calc_.clear();
@ -297,8 +304,8 @@ initializeWellProdIndCalculators()
}
}
void
BlackoilWellModelGeneric::
template<class Scalar>
void BlackoilWellModelGeneric<Scalar>::
initializeWellPerfData()
{
well_perf_data_.resize(wells_ecl_.size());
@ -388,8 +395,8 @@ initializeWellPerfData()
}
}
void
BlackoilWellModelGeneric::
template<class Scalar>
void BlackoilWellModelGeneric<Scalar>::
checkGEconLimits(
const Group& group,
const double simulation_time,
@ -407,7 +414,7 @@ checkGEconLimits(
return;
}
GroupEconomicLimitsChecker<double> checker {
GroupEconomicLimitsChecker<Scalar> checker {
*this, wellTestState(), group, simulation_time, report_step_idx, deferred_logger
};
if (checker.minOilRate() || checker.minGasRate()) {
@ -423,10 +430,10 @@ checkGEconLimits(
}
}
void
BlackoilWellModelGeneric::
template<class Scalar>
void BlackoilWellModelGeneric<Scalar>::
checkGconsaleLimits(const Group& group,
WellState<double>& well_state,
WellState<Scalar>& well_state,
const int reportStepIdx,
DeferredLogger& deferred_logger)
{
@ -450,25 +457,24 @@ checkGconsaleLimits(const Group& group,
const Group::ProductionCMode& oldProductionControl = this->groupState().production_control(group.name());
int gasPos = phase_usage_.phase_pos[BlackoilPhases::Vapour];
double production_rate = WellGroupHelpers<double>::sumWellSurfaceRates(group,
Scalar production_rate = WellGroupHelpers<Scalar>::sumWellSurfaceRates(group,
schedule(),
well_state,
reportStepIdx,
gasPos,
/*isInjector*/false);
double injection_rate = WellGroupHelpers<double>::sumWellSurfaceRates(group,
Scalar injection_rate = WellGroupHelpers<Scalar>::sumWellSurfaceRates(group,
schedule(),
well_state,
reportStepIdx,
gasPos,
/*isInjector*/true);
// sum over all nodes
injection_rate = comm_.sum(injection_rate);
production_rate = comm_.sum(production_rate);
double sales_rate = production_rate - injection_rate;
double production_target = gconsale.sales_target + injection_rate;
Scalar sales_rate = production_rate - injection_rate;
Scalar production_target = gconsale.sales_target + injection_rate;
// add import rate and subtract consumption rate for group for gas
if (schedule()[reportStepIdx].gconsump().has(group.name())) {
@ -482,7 +488,7 @@ checkGconsaleLimits(const Group& group,
}
if (sales_rate > gconsale.max_sales_rate) {
switch(gconsale.max_proc) {
switch (gconsale.max_proc) {
case GConSale::MaxProcedure::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",
@ -554,8 +560,8 @@ checkGconsaleLimits(const Group& group,
deferred_logger.info(ss);
}
bool
BlackoilWellModelGeneric::
template<class Scalar>
bool BlackoilWellModelGeneric<Scalar>::
checkGroupHigherConstraints(const Group& group,
DeferredLogger& deferred_logger,
const int reportStepIdx)
@ -586,16 +592,16 @@ checkGroupHigherConstraints(const Group& group,
->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";
if (!isField && group.isInjectionGroup()) {
// 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);
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(),
this->wellState(),
reportStepIdx,
@ -611,7 +617,7 @@ checkGroupHigherConstraints(const Group& group,
if (currentControl != Group::InjectionCMode::FLD && group.injectionGroupControlAvailable(phase)) {
const Group& parentGroup = schedule().getGroup(group.parent(), reportStepIdx);
const auto [is_changed, scaling_factor] =
WellGroupHelpers<double>::checkGroupConstraintsInj(group.name(),
WellGroupHelpers<Scalar>::checkGroupConstraintsInj(group.name(),
group.parent(),
parentGroup,
this->wellState(),
@ -632,7 +638,7 @@ checkGroupHigherConstraints(const Group& group,
actionOnBrokenConstraints(group, Group::InjectionCMode::FLD,
phase, this->groupState(),
deferred_logger);
WellGroupHelpers<double>::updateWellRatesFromGroupTargetScale(scaling_factor,
WellGroupHelpers<Scalar>::updateWellRatesFromGroupTargetScale(scaling_factor,
group,
schedule(),
reportStepIdx,
@ -648,7 +654,7 @@ checkGroupHigherConstraints(const Group& group,
if (!isField && group.isProductionGroup()) {
// Obtain rates for group.
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(),
this->wellState(),
reportStepIdx,
@ -657,14 +663,14 @@ checkGroupHigherConstraints(const Group& group,
// Sum over all processes
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);
// Check higher up only if under individual (not FLD) control.
const Group::ProductionCMode& currentControl = this->groupState().production_control(group.name());
if (currentControl != Group::ProductionCMode::FLD && group.productionGroupControlAvailable()) {
const Group& parentGroup = schedule().getGroup(group.parent(), reportStepIdx);
const auto [is_changed, scaling_factor] =
WellGroupHelpers<double>::checkGroupConstraintsProd(group.name(),
WellGroupHelpers<Scalar>::checkGroupConstraintsProd(group.name(),
group.parent(),
parentGroup,
this->wellState(),
@ -692,7 +698,7 @@ checkGroupHigherConstraints(const Group& group,
if (changed) {
switched_prod_groups_.insert_or_assign(group.name(),
Group::ProductionCMode2String(Group::ProductionCMode::FLD));
WellGroupHelpers<double>::updateWellRatesFromGroupTargetScale(scaling_factor,
WellGroupHelpers<Scalar>::updateWellRatesFromGroupTargetScale(scaling_factor,
group,
schedule(),
reportStepIdx,
@ -707,8 +713,8 @@ checkGroupHigherConstraints(const Group& group,
return changed;
}
void
BlackoilWellModelGeneric::
template<class Scalar>
void BlackoilWellModelGeneric<Scalar>::
updateEclWells(const int timeStepIdx,
const SimulatorUpdate& sim_update,
const SummaryState& st)
@ -756,8 +762,8 @@ updateEclWells(const int timeStepIdx,
this->wellStructureChangedDynamically_ = sim_update.well_structure_changed;
}
double
BlackoilWellModelGeneric::
template<class Scalar>
Scalar BlackoilWellModelGeneric<Scalar>::
wellPI(const int well_index) const
{
const auto& pu = this->phase_usage_;
@ -788,8 +794,8 @@ wellPI(const int well_index) const
}
}
double
BlackoilWellModelGeneric::
template<class Scalar>
Scalar BlackoilWellModelGeneric<Scalar>::
wellPI(const std::string& well_name) const
{
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);
}
bool
BlackoilWellModelGeneric::
template<class Scalar>
bool BlackoilWellModelGeneric<Scalar>::
wasDynamicallyShutThisTimeStep(const int well_index) const
{
return wasDynamicallyShutThisTimeStep(this->wells_ecl_[well_index].name());
}
template<class Scalar>
bool
BlackoilWellModelGeneric::
BlackoilWellModelGeneric<Scalar>::
wasDynamicallyShutThisTimeStep(const std::string& well_name) const
{
return this->closed_this_step_.find(well_name) !=
this->closed_this_step_.end();
}
void
BlackoilWellModelGeneric::
template<class Scalar>
void BlackoilWellModelGeneric<Scalar>::
updateWsolvent(const Group& group,
const int reportStepIdx,
const WellState<double>& wellState)
const WellState<Scalar>& wellState)
{
for (const std::string& groupName : group.groups()) {
const Group& groupTmp = schedule_.getGroup(groupName, reportStepIdx);
@ -841,13 +847,13 @@ updateWsolvent(const Group& group,
int gasPos = phase_usage_.phase_pos[BlackoilPhases::Vapour];
const auto& controls = group.injectionControls(Phase::GAS, summaryState_);
const Group& groupRein = schedule_.getGroup(controls.reinj_group, reportStepIdx);
double gasProductionRate = WellGroupHelpers<double>::sumWellSurfaceRates(groupRein,
Scalar gasProductionRate = WellGroupHelpers<Scalar>::sumWellSurfaceRates(groupRein,
schedule_,
wellState,
reportStepIdx,
gasPos,
/*isInjector*/false);
double solventProductionRate = WellGroupHelpers<double>::sumSolventRates(groupRein,
Scalar solventProductionRate = WellGroupHelpers<Scalar>::sumSolventRates(groupRein,
schedule_,
wellState,
reportStepIdx,
@ -856,7 +862,7 @@ updateWsolvent(const Group& group,
solventProductionRate = comm_.sum(solventProductionRate);
gasProductionRate = comm_.sum(gasProductionRate);
double wsolvent = 0.0;
Scalar wsolvent = 0.0;
if (std::abs(gasProductionRate) > 1e-6)
wsolvent = solventProductionRate / gasProductionRate;
@ -864,11 +870,11 @@ updateWsolvent(const Group& group,
}
}
void
BlackoilWellModelGeneric::
template<class Scalar>
void BlackoilWellModelGeneric<Scalar>::
setWsolvent(const Group& group,
const int reportStepIdx,
double wsolvent)
Scalar wsolvent)
{
for (const std::string& groupName : group.groups()) {
const Group& groupTmp = schedule_.getGroup(groupName, reportStepIdx);
@ -884,8 +890,8 @@ setWsolvent(const Group& group,
}
}
void
BlackoilWellModelGeneric::
template<class Scalar>
void BlackoilWellModelGeneric<Scalar>::
assignShutConnections(data::Wells& wsrpt,
const int reportStepIndex) const
{
@ -929,8 +935,8 @@ assignShutConnections(data::Wells& wsrpt,
}
}
void
BlackoilWellModelGeneric::
template<class Scalar>
void BlackoilWellModelGeneric<Scalar>::
assignGroupControl(const Group& group,
data::GroupData& gdata) const
{
@ -960,8 +966,8 @@ assignGroupControl(const Group& group,
}
}
void
BlackoilWellModelGeneric::
template<class Scalar>
void BlackoilWellModelGeneric<Scalar>::
assignGroupValues(const int reportStepIdx,
std::map<std::string, data::GroupData>& gvalues) const
{
@ -977,9 +983,10 @@ assignGroupValues(const int reportStepIdx,
}
}
void
BlackoilWellModelGeneric::
assignNodeValues(std::map<std::string, data::NodeData>& nodevalues, const int reportStepIdx) const
template<class Scalar>
void BlackoilWellModelGeneric<Scalar>::
assignNodeValues(std::map<std::string, data::NodeData>& nodevalues,
const int reportStepIdx) const
{
nodevalues.clear();
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});
// Assign node values of well groups to GPR:WELLNAME
const auto& sched = schedule();
if (!sched.hasGroup(node, reportStepIdx)) continue;
if (!sched.hasGroup(node, reportStepIdx)) {
continue;
}
const auto& group = sched.getGroup(node, reportStepIdx);
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();
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->groupState(),
*(vfp_properties_->getProd()),
@ -1010,30 +1021,33 @@ assignNodeValues(std::map<std::string, data::NodeData>& nodevalues, const int re
it->second.converged_pressure = converged_pressure;
// Assign node values of group to GPR:WELLNAME
const auto& sched = schedule();
if (!sched.hasGroup(node, reportStepIdx)) continue;
if (!sched.hasGroup(node, reportStepIdx)) {
continue;
}
const auto& group = sched.getGroup(node, reportStepIdx);
for (const std::string& wellname : group.wells()) {
auto it2 = nodevalues.find(wellname);
assert(it2 != nodevalues.end());
it2->second.converged_pressure = converged_pressure;
auto it2 = nodevalues.find(wellname);
assert(it2 != nodevalues.end());
it2->second.converged_pressure = converged_pressure;
}
}
}
template<class Scalar>
data::GroupAndNetworkValues
BlackoilWellModelGeneric::
BlackoilWellModelGeneric<Scalar>::
groupAndNetworkData(const int reportStepIdx) const
{
auto grp_nwrk_values = data::GroupAndNetworkValues{};
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;
}
void
BlackoilWellModelGeneric::
template<class Scalar>
void BlackoilWellModelGeneric<Scalar>::
updateAndCommunicateGroupData(const int reportStepIdx,
const int iterationIdx)
{
@ -1052,8 +1066,8 @@ updateAndCommunicateGroupData(const int reportStepIdx,
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 does not honor NUPCOL.
std::vector<double> groupTargetReduction(numPhases(), 0.0);
WellGroupHelpers<double>::updateGroupTargetReduction(fieldGroup,
std::vector<Scalar> groupTargetReduction(numPhases(), 0.0);
WellGroupHelpers<Scalar>::updateGroupTargetReduction(fieldGroup,
schedule(),
reportStepIdx,
/*isInjector*/ false,
@ -1062,8 +1076,8 @@ updateAndCommunicateGroupData(const int reportStepIdx,
well_state,
this->groupState(),
groupTargetReduction);
std::vector<double> groupTargetReductionInj(numPhases(), 0.0);
WellGroupHelpers<double>::updateGroupTargetReduction(fieldGroup,
std::vector<Scalar> groupTargetReductionInj(numPhases(), 0.0);
WellGroupHelpers<Scalar>::updateGroupTargetReduction(fieldGroup,
schedule(),
reportStepIdx,
/*isInjector*/ true,
@ -1073,7 +1087,7 @@ updateAndCommunicateGroupData(const int reportStepIdx,
this->groupState(),
groupTargetReductionInj);
WellGroupHelpers<double>::updateREINForGroups(fieldGroup,
WellGroupHelpers<Scalar>::updateREINForGroups(fieldGroup,
schedule(),
reportStepIdx,
phase_usage_,
@ -1081,31 +1095,31 @@ updateAndCommunicateGroupData(const int reportStepIdx,
well_state_nupcol,
this->groupState(),
comm_.rank() == 0);
WellGroupHelpers<double>::updateVREPForGroups(fieldGroup,
WellGroupHelpers<Scalar>::updateVREPForGroups(fieldGroup,
schedule(),
reportStepIdx,
well_state_nupcol,
this->groupState());
WellGroupHelpers<double>::updateReservoirRatesInjectionGroups(fieldGroup,
WellGroupHelpers<Scalar>::updateReservoirRatesInjectionGroups(fieldGroup,
schedule(),
reportStepIdx,
well_state_nupcol,
this->groupState());
WellGroupHelpers<double>::updateSurfaceRatesInjectionGroups(fieldGroup,
WellGroupHelpers<Scalar>::updateSurfaceRatesInjectionGroups(fieldGroup,
schedule(),
reportStepIdx,
well_state_nupcol,
this->groupState());
WellGroupHelpers<double>::updateGroupProductionRates(fieldGroup,
WellGroupHelpers<Scalar>::updateGroupProductionRates(fieldGroup,
schedule(),
reportStepIdx,
well_state_nupcol,
this->groupState());
// We use the rates from the previous time-step to reduce oscillations
WellGroupHelpers<double>::updateWellRates(fieldGroup,
WellGroupHelpers<Scalar>::updateWellRates(fieldGroup,
schedule(),
reportStepIdx,
this->prevWellState(),
@ -1124,15 +1138,15 @@ updateAndCommunicateGroupData(const int reportStepIdx,
this->groupState().communicate_rates(comm_);
}
bool
BlackoilWellModelGeneric::
template<class Scalar>
bool BlackoilWellModelGeneric<Scalar>::
hasTHPConstraints() const
{
return BlackoilWellModelConstraints(*this).hasTHPConstraints();
}
void
BlackoilWellModelGeneric::
template<class Scalar>
void BlackoilWellModelGeneric<Scalar>::
updateNetworkActiveState(const int report_step) {
const auto& network = schedule()[report_step].network();
if (!network.active()) {
@ -1152,8 +1166,8 @@ updateNetworkActiveState(const int report_step) {
this->network_active_ = comm_.max(network_active);
}
bool
BlackoilWellModelGeneric::
template<class Scalar>
bool BlackoilWellModelGeneric<Scalar>::
needPreStepNetworkRebalance(const int report_step) const
{
const auto& network = schedule()[report_step].network();
@ -1171,8 +1185,8 @@ needPreStepNetworkRebalance(const int report_step) const
return network_rebalance_necessary;
}
bool
BlackoilWellModelGeneric::
template<class Scalar>
bool BlackoilWellModelGeneric<Scalar>::
forceShutWellByName(const std::string& wellname,
const double simulation_time)
{
@ -1204,8 +1218,8 @@ forceShutWellByName(const std::string& wellname,
return (well_was_shut == 1);
}
void
BlackoilWellModelGeneric::
template<class Scalar>
void BlackoilWellModelGeneric<Scalar>::
inferLocalShutWells()
{
this->local_shut_wells_.clear();
@ -1224,8 +1238,8 @@ inferLocalShutWells()
}
}
double
BlackoilWellModelGeneric::
template<class Scalar>
Scalar BlackoilWellModelGeneric<Scalar>::
updateNetworkPressures(const int reportStepIdx)
{
// 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_;
node_pressures_ = WellGroupHelpers<double>::computeNetworkPressures(network,
node_pressures_ = WellGroupHelpers<Scalar>::computeNetworkPressures(network,
this->wellState(),
this->groupState(),
*(vfp_properties_->getProd()),
@ -1244,7 +1258,7 @@ updateNetworkPressures(const int reportStepIdx)
reportStepIdx);
// 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())
return network_imbalance;
@ -1257,18 +1271,18 @@ updateNetworkPressures(const int reportStepIdx)
continue;
}
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) {
network_imbalance = std::abs(change);
}
// we dampen the amount of the nodal pressure can change during one iteration
// due to the fact our nodal pressure calculation is somewhat explicit
// 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
constexpr double damping_factor = 0.1;
const double damped_change = std::min(damping_factor * std::abs(change), upper_update_bound);
const double sign = change > 0 ? 1. : -1.;
constexpr Scalar damping_factor = 0.1;
const Scalar damped_change = std::min(damping_factor * std::abs(change), upper_update_bound);
const Scalar sign = change > 0 ? 1. : -1.;
node_pressures_[name] = pressure + sign * damped_change;
}
} else {
@ -1289,9 +1303,9 @@ updateNetworkPressures(const int reportStepIdx)
if (it != node_pressures_.end()) {
// The well belongs to a group with has a network pressure constraint,
// 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);
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;
// TODO: not sure why the thp is NOT updated properly elsewhere
if (thp_is_limit) {
@ -1303,14 +1317,14 @@ updateNetworkPressures(const int reportStepIdx)
return network_imbalance;
}
void
BlackoilWellModelGeneric::
template<class Scalar>
void BlackoilWellModelGeneric<Scalar>::
calculateEfficiencyFactors(const int reportStepIdx)
{
for (auto& well : well_container_generic_) {
const Well& wellEcl = well->wellEcl();
double well_efficiency_factor = wellEcl.getEfficiencyFactor();
WellGroupHelpers<double>::accumulateGroupEfficiencyFactor(schedule().getGroup(wellEcl.groupName(),
Scalar well_efficiency_factor = wellEcl.getEfficiencyFactor();
WellGroupHelpers<Scalar>::accumulateGroupEfficiencyFactor(schedule().getGroup(wellEcl.groupName(),
reportStepIdx),
schedule(),
reportStepIdx,
@ -1319,8 +1333,9 @@ calculateEfficiencyFactors(const int reportStepIdx)
}
}
template<class Scalar>
WellInterfaceGeneric*
BlackoilWellModelGeneric::
BlackoilWellModelGeneric<Scalar>::
getGenWell(const std::string& well_name)
{
// finding the iterator of the well in wells_ecl
@ -1335,8 +1350,8 @@ getGenWell(const std::string& well_name)
return *well;
}
void
BlackoilWellModelGeneric::
template<class Scalar>
void BlackoilWellModelGeneric<Scalar>::
setRepRadiusPerfLength()
{
for (const auto& well : well_container_generic_) {
@ -1344,8 +1359,8 @@ setRepRadiusPerfLength()
}
}
void
BlackoilWellModelGeneric::
template<class Scalar>
void BlackoilWellModelGeneric<Scalar>::
gliftDebug(const std::string& msg,
DeferredLogger& deferred_logger) const
{
@ -1356,9 +1371,8 @@ gliftDebug(const std::string& msg,
}
}
void
BlackoilWellModelGeneric::
template<class Scalar>
void BlackoilWellModelGeneric<Scalar>::
gliftDebugShowALQ(DeferredLogger& deferred_logger)
{
for (auto& well : this->well_container_generic_) {
@ -1378,8 +1392,8 @@ gliftDebugShowALQ(DeferredLogger& deferred_logger)
// currently has the largest weighted incremental gradient. The
// procedure takes account of any limits on the group production
// rate or lift gas supply applied to any level of group.
void
BlackoilWellModelGeneric::
template<class Scalar>
void BlackoilWellModelGeneric<Scalar>::
gasLiftOptimizationStage2(DeferredLogger& deferred_logger,
GLiftProdWells& prod_wells,
GLiftOptWells& glift_wells,
@ -1403,8 +1417,8 @@ gasLiftOptimizationStage2(DeferredLogger& deferred_logger,
glift.runOptimize();
}
void
BlackoilWellModelGeneric::
template<class Scalar>
void BlackoilWellModelGeneric<Scalar>::
updateWellPotentials(const int reportStepIdx,
const bool onlyAfterEvent,
const SummaryConfig& summaryConfig,
@ -1462,11 +1476,10 @@ updateWellPotentials(const int reportStepIdx,
logAndCheckForExceptionsAndThrow(deferred_logger, exc_type,
"computeWellPotentials() failed: " + exc_msg,
terminal_output_, comm_);
}
void
BlackoilWellModelGeneric::
template<class Scalar>
void BlackoilWellModelGeneric<Scalar>::
runWellPIScaling(const int reportStepIdx,
DeferredLogger& local_deferredLogger)
{
@ -1503,10 +1516,9 @@ runWellPIScaling(const int reportStepIdx,
this->prod_index_calc_[well_index].reInit(well);
};
auto rescaleWellPI =
[this, reportStepIdx](const int well_index,
const double newWellPI) -> void
const Scalar newWellPI) -> void
{
const auto& wname = this->wells_ecl_[well_index].name();
@ -1540,8 +1552,8 @@ runWellPIScaling(const int reportStepIdx,
this->last_run_wellpi_ = reportStepIdx;
}
bool
BlackoilWellModelGeneric::
template<class Scalar>
bool BlackoilWellModelGeneric<Scalar>::
shouldBalanceNetwork(const int reportStepIdx, const int iterationIdx) const
{
// 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
}
}
std::vector<int>
BlackoilWellModelGeneric::
template<class Scalar>
std::vector<int> BlackoilWellModelGeneric<Scalar>::
getCellsForConnections(const Well& well) const
{
std::vector<int> wellCells;
@ -1587,9 +1597,10 @@ getCellsForConnections(const Well& well) const
return wellCells;
}
std::vector<std::string>
BlackoilWellModelGeneric::getWellsForTesting(const int timeStepIdx,
const double simulationTime)
template<class Scalar>
std::vector<std::string> BlackoilWellModelGeneric<Scalar>::
getWellsForTesting(const int timeStepIdx,
const double simulationTime)
{
const auto& wtest_config = schedule()[timeStepIdx].wtest_config();
if (!wtest_config.empty()) { // there is a WTEST request
@ -1598,8 +1609,8 @@ BlackoilWellModelGeneric::getWellsForTesting(const int timeStepIdx,
return {};
}
void
BlackoilWellModelGeneric::
template<class Scalar>
void BlackoilWellModelGeneric<Scalar>::
assignWellTracerRates(data::Wells& wsrpt,
const WellTracerRates& wellTracerRates) const
{
@ -1613,13 +1624,13 @@ assignWellTracerRates(data::Wells& wsrpt,
continue;
}
std::string tracerName = wTR.first.second;
double rate = wTR.second;
Scalar rate = wTR.second;
xwPos->second.rates.set(data::Rates::opt::tracer, rate, tracerName);
}
}
std::vector<std::vector<int>>
BlackoilWellModelGeneric::
template<class Scalar>
std::vector<std::vector<int>> BlackoilWellModelGeneric<Scalar>::
getMaxWellConnections() const
{
std::vector<std::vector<int>> wells;
@ -1629,7 +1640,7 @@ getMaxWellConnections() const
wells.reserve(schedule_wells.size());
// 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);
@ -1642,26 +1653,29 @@ getMaxWellConnections() const
return wells;
}
int BlackoilWellModelGeneric::numLocalWellsEnd() const
template<class Scalar>
int BlackoilWellModelGeneric<Scalar>::numLocalWellsEnd() const
{
auto w = schedule().getWellsatEnd();
w.erase(std::remove_if(w.begin(), w.end(), not_on_process_), w.end());
return w.size();
}
int BlackoilWellModelGeneric::numLocalNonshutWells() const
template<class Scalar>
int BlackoilWellModelGeneric<Scalar>::numLocalNonshutWells() const
{
return well_container_generic_.size();
}
void BlackoilWellModelGeneric::initInjMult() {
template<class Scalar>
void BlackoilWellModelGeneric<Scalar>::initInjMult()
{
for (auto& well : this->well_container_generic_) {
if (well->isInjector() && well->wellEcl().getInjMultMode() != Well::InjMultMode::NONE) {
const auto& ws = this->wellState().well(well->indexOfWell());
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()) {
values.assign(perf_data.size(), 1.0);
}
@ -1670,13 +1684,14 @@ void BlackoilWellModelGeneric::initInjMult() {
}
}
void BlackoilWellModelGeneric::updateFiltrationParticleVolume(const double dt,
const std::size_t water_index)
template<class Scalar>
void BlackoilWellModelGeneric<Scalar>::
updateFiltrationParticleVolume(const double dt,
const std::size_t water_index)
{
for (auto& well : this->well_container_generic_) {
if (well->isInjector()) {
const double conc = well->wellEcl().evalFilterConc(this->summaryState_);
const Scalar conc = well->wellEcl().evalFilterConc(this->summaryState_);
if (conc > 0.) {
auto fc = this->filter_cake_
.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_) {
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_) {
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 <optional>
#include <string>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#include <vector>
@ -79,6 +78,7 @@ namespace Opm { namespace data {
namespace Opm {
/// Class for handling the blackoil well model.
template<class Scalar>
class BlackoilWellModelGeneric
{
public:
@ -114,14 +114,14 @@ public:
std::vector<Well> getLocalWells(const int timeStepIdx) const;
const Schedule& schedule() const { return schedule_; }
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
{ return {well_container_generic_.begin(), well_container_generic_.end()}; }
/*
Immutable version of the currently active wellstate.
*/
const WellState<double>& wellState() const
const WellState<Scalar>& wellState() const
{
return this->active_wgstate_.well_state;
}
@ -129,7 +129,7 @@ public:
/*
Mutable version of the currently active wellstate.
*/
WellState<double>& wellState()
WellState<Scalar>& wellState()
{
return this->active_wgstate_.well_state;
}
@ -138,19 +138,18 @@ public:
Will return the currently active nupcolWellState; must initialize
the internal nupcol wellstate with initNupcolWellState() first.
*/
const WellState<double>& nupcolWellState() const
const WellState<Scalar>& nupcolWellState() const
{
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; }
const WellTestState& wellTestState() const { return this->active_wgstate_.well_test_state; }
double wellPI(const int well_index) const;
double wellPI(const std::string& well_name) const;
Scalar wellPI(const int well_index) const;
Scalar wellPI(const std::string& well_name) const;
void updateEclWells(const int timeStepIdx,
const SimulatorUpdate& sim_update,
@ -210,7 +209,8 @@ public:
bool shouldBalanceNetwork(const int reportStepIndex,
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);
}
bool wasDynamicallyShutThisTimeStep(const std::string& well_name) const;
@ -254,7 +254,6 @@ public:
}
protected:
/*
The dynamic state of the well model is maintained with an instance
of the WellState class. Currently we have
@ -275,7 +274,6 @@ protected:
nupcol_well_state_ and the initNupcolWellState() function.
*/
/*
Will return the last good wellstate. This is typcially used when
initializing a new report step where the Schedule object might
@ -283,25 +281,22 @@ protected:
prevWellState() must have been stored with the commitWellState()
function first.
*/
const WellState<double>& prevWellState() const
const WellState<Scalar>& prevWellState() const
{
return this->last_valid_wgstate_.well_state;
}
const WGState<double>& prevWGState() const
const WGState<Scalar>& prevWGState() const
{
return this->last_valid_wgstate_;
}
/*
Will store a copy of the input argument well_state in the
last_valid_well_state_ member, that state can then be recovered
with a subsequent call to resetWellState().
*/
void commitWGState(WGState<double> wgstate)
void commitWGState(WGState<Scalar> wgstate)
{
this->last_valid_wgstate_ = std::move(wgstate);
}
@ -328,28 +323,29 @@ protected:
/// \brief Create the parallel well information
/// \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 initializeWellPerfData();
bool wasDynamicallyShutThisTimeStep(const int well_index) const;
double updateNetworkPressures(const int reportStepIdx);
Scalar updateNetworkPressures(const int reportStepIdx);
void updateWsolvent(const Group& group,
const int reportStepIdx,
const WellState<double>& wellState);
const WellState<Scalar>& wellState);
void setWsolvent(const Group& group,
const int reportStepIdx,
double wsolvent);
Scalar wsolvent);
virtual void calcRates(const int fipnum,
const int pvtreg,
const std::vector<double>& production_rates,
std::vector<double>& resv_coeff) = 0;
const std::vector<Scalar>& production_rates,
std::vector<Scalar>& resv_coeff) = 0;
virtual void calcInjRates(const int fipnum,
const int pvtreg,
std::vector<double>& resv_coeff) = 0;
const int pvtreg,
std::vector<Scalar>& resv_coeff) = 0;
void assignShutConnections(data::Wells& wsrpt,
const int reportStepIndex) const;
@ -357,12 +353,13 @@ protected:
data::GroupData& gdata) const;
void assignGroupValues(const int reportStepIdx,
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 checkGconsaleLimits(const Group& group,
WellState<double>& well_state,
WellState<Scalar>& well_state,
const int reportStepIdx,
DeferredLogger& deferred_logger);
@ -395,7 +392,7 @@ protected:
const int episodeIndex);
virtual void computePotentials(const std::size_t widx,
const WellState<double>& well_state_copy,
const WellState<Scalar>& well_state_copy,
std::string& exc_msg,
ExceptionType::ExcEnum& exc_type,
DeferredLogger& deferred_logger) = 0;
@ -408,11 +405,11 @@ protected:
void initInjMult();
void updateInjMult(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
virtual void createWellContainer(const int time_step) = 0;
@ -434,7 +431,7 @@ protected:
std::vector<std::string> getWellsForTesting(const int timeStepIdx,
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,
const WellTracerRates& wellTracerRates) const;
@ -561,13 +558,13 @@ protected:
GuideRate guideRate_;
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
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
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
@ -575,9 +572,9 @@ protected:
commitWellState(), resetWellState(), nupcolWellState() and
updateNupcolWellState().
*/
WGState<double> active_wgstate_;
WGState<double> last_valid_wgstate_;
WGState<double> nupcol_wgstate_;
WGState<Scalar> active_wgstate_;
WGState<Scalar> last_valid_wgstate_;
WGState<Scalar> nupcol_wgstate_;
bool glift_debug = false;
@ -587,11 +584,10 @@ protected:
// Store maps of group name and new group controls for output
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
std::map<std::string, std::pair<std::string, std::string>> closed_offending_wells_;
private:
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 {
void
BlackoilWellModelGuideRates::
template<class Scalar>
void BlackoilWellModelGuideRates<Scalar>::
getGuideRateValues(const GuideRate::RateVector& qs,
const bool is_inj,
const std::string& wgname,
@ -309,8 +309,9 @@ getGuideRateValues(const GuideRate::RateVector& qs,
}
}
template<class Scalar>
data::GuideRateValue
BlackoilWellModelGuideRates::
BlackoilWellModelGuideRates<Scalar>::
getGuideRateValues(const Well& well) const
{
auto grval = data::GuideRateValue{};
@ -328,7 +329,7 @@ getGuideRateValues(const Well& well) const
return grval;
}
const auto qs = WellGroupHelpers<double>::
const auto qs = WellGroupHelpers<Scalar>::
getWellRateVector(wellModel_.wellState(), wellModel_.phaseUsage(), wname);
this->getGuideRateValues(qs, well.isInjector(), wname, grval);
@ -336,8 +337,9 @@ getGuideRateValues(const Well& well) const
return grval;
}
template<class Scalar>
data::GuideRateValue
BlackoilWellModelGuideRates::
BlackoilWellModelGuideRates<Scalar>::
getGuideRateValues(const Group& group) const
{
auto grval = data::GuideRateValue{};
@ -355,7 +357,7 @@ getGuideRateValues(const Group& group) const
return grval;
}
const auto qs = WellGroupHelpers<double>::
const auto qs = WellGroupHelpers<Scalar>::
getProductionGroupRateVector(wellModel_.groupState(), wellModel_.phaseUsage(), gname);
const auto is_inj = false; // This procedure only applies to G*PGR.
@ -364,8 +366,9 @@ getGuideRateValues(const Group& group) const
return grval;
}
template<class Scalar>
data::GuideRateValue
BlackoilWellModelGuideRates::
BlackoilWellModelGuideRates<Scalar>::
getGuideRateInjectionGroupValues(const Group& group) const
{
auto grval = data::GuideRateValue{};
@ -384,7 +387,8 @@ getGuideRateInjectionGroupValues(const Group& group) const
return grval;
}
void BlackoilWellModelGuideRates::
template<class Scalar>
void BlackoilWellModelGuideRates<Scalar>::
assignWellGuideRates(data::Wells& wsrpt,
const int reportStepIdx) const
{
@ -433,7 +437,7 @@ assignWellGuideRates(data::Wells& wsrpt,
const auto get_gr = parent
|| RetrieveWellGuideRate{wellModel_.guideRate(), wname};
const auto qs = WellGroupHelpers<double>::
const auto qs = WellGroupHelpers<Scalar>::
getWellRateVector(wellModel_.wellState(), wellModel_.phaseUsage(), wname);
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>
BlackoilWellModelGuideRates::
BlackoilWellModelGuideRates<Scalar>::
calculateAllGroupGuideRates(const int reportStepIdx) const
{
auto gr = std::unordered_map<std::string, data::GroupGuideRates>{};
@ -542,7 +547,8 @@ calculateAllGroupGuideRates(const int reportStepIdx) const
return gr;
}
void BlackoilWellModelGuideRates::
template<class Scalar>
void BlackoilWellModelGuideRates<Scalar>::
assignGroupGuideRates(const Group& group,
const std::unordered_map<std::string, data::GroupGuideRates>& groupGuideRates,
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
{
const auto& genWells = wellModel_.genericWells();
@ -595,4 +602,6 @@ guideRateUpdateIsNeeded(const int reportStepIdx) const
return wellModel_.comm().max(static_cast<int>(need_update));
}
template class BlackoilWellModelGuideRates<double>;
} // namespace Opm

View File

@ -30,7 +30,7 @@
namespace Opm {
class BlackoilWellModelGeneric;
template<class Scalar> class BlackoilWellModelGeneric;
namespace data {
struct GroupData;
struct GroupGuideRates;
@ -41,11 +41,12 @@ class Group;
class Well;
/// Class for handling the guide rates in the blackoil well model.
template<class Scalar>
class BlackoilWellModelGuideRates
{
public:
//! \brief Constructor initializes reference to the well model.
BlackoilWellModelGuideRates(const BlackoilWellModelGeneric& wellModel)
BlackoilWellModelGuideRates(const BlackoilWellModelGeneric<Scalar>& wellModel)
: wellModel_(wellModel)
{}
@ -81,7 +82,7 @@ private:
//! \brief Obtain guide rate values for injection group.
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 {
void BlackoilWellModelRestart::
template<class Scalar>
void BlackoilWellModelRestart<Scalar>::
loadRestartConnectionData(const std::vector<data::Rates::opt>& phs,
const data::Well& rst_well,
const std::vector<PerforationData>& old_perf_data,
SingleWellState<double>& ws) const
SingleWellState<Scalar>& ws) const
{
auto& perf_data = ws.perf_data;
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,
const std::vector<data::Rates::opt>& phs,
const data::Well& rst_well,
SingleWellState<double>& ws) const
SingleWellState<Scalar>& ws) const
{
const auto& segment_set = wellModel_.getWellEcl(well_name).getSegments();
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,
const bool handle_ms_well,
const std::vector<data::Rates::opt>& phs,
const data::Well& rst_well,
const std::vector<PerforationData>& old_perf_data,
SingleWellState<double>& ws) const
SingleWellState<Scalar>& ws) const
{
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,
const data::GroupData& value,
GroupState<double>& grpState) const
GroupState<Scalar>& grpState) const
{
using GPMode = Group::ProductionCMode;
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,
const GuideRateModel::Target target,
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,
const GuideRateConfig& config,
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,
const data::GroupAndNetworkValues& grpNwrkValues,
const bool handle_ms_well,
WellState<double>& well_state,
GroupState<double>& grpState) const
WellState<Scalar>& well_state,
GroupState<Scalar>& grpState) const
{
using rt = data::Rates::opt;
const auto& phases = wellModel_.phaseUsage();
@ -260,4 +267,6 @@ loadRestartData(const data::Wells& rst_wells,
}
}
template class BlackoilWellModelRestart<double>;
} // namespace Opm

View File

@ -30,7 +30,7 @@
namespace Opm {
class BlackoilWellModelGeneric;
template<class Scalar> class BlackoilWellModelGeneric;
namespace data {
struct GroupData;
class GroupAndNetworkValues;
@ -44,11 +44,12 @@ template<class Scalar> class SingleWellState;
template<class Scalar> class WellState;
/// Class for restarting the blackoil well model.
template<class Scalar>
class BlackoilWellModelRestart
{
public:
//! \brief Constructor initializes reference to the well model.
BlackoilWellModelRestart(const BlackoilWellModelGeneric& wellModel)
BlackoilWellModelRestart(const BlackoilWellModelGeneric<Scalar>& wellModel)
: wellModel_(wellModel)
{}
@ -68,21 +69,21 @@ public:
void loadRestartData(const data::Wells& rst_wells,
const data::GroupAndNetworkValues& grpNwrkValues,
const bool handle_ms_well,
WellState<double>& well_state,
GroupState<double>& grpState) const;
WellState<Scalar>& well_state,
GroupState<Scalar>& grpState) const;
private:
//! \brief Loads per-connection data from restart structures.
void loadRestartConnectionData(const std::vector<data::Rates::opt>& phs,
const data::Well& rst_well,
const std::vector<PerforationData>& old_perf_data,
SingleWellState<double>& ws) const;
SingleWellState<Scalar>& ws) const;
//! \brief Loads per-segment data from restart structures.
void loadRestartSegmentData(const std::string& well_name,
const std::vector<data::Rates::opt>& phs,
const data::Well& rst_well,
SingleWellState<double>& ws) const;
SingleWellState<Scalar>& ws) const;
//! \brief Loads per-well data from restart structures.
void loadRestartWellData(const std::string& well_name,
@ -90,14 +91,14 @@ private:
const std::vector<data::Rates::opt>& phs,
const data::Well& rst_well,
const std::vector<PerforationData>& old_perf_data,
SingleWellState<double>& ws) const;
SingleWellState<Scalar>& ws) const;
//! \brief Loads per-group data from restart structures.
void loadRestartGroupData(const std::string& group,
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>
BlackoilWellModel<TypeTag>::
BlackoilWellModel(Simulator& simulator, const PhaseUsage& phase_usage)
: BlackoilWellModelGeneric(simulator.vanguard().schedule(),
simulator.vanguard().summaryState(),
simulator.vanguard().eclState(),
phase_usage,
simulator.gridView().comm())
: BlackoilWellModelGeneric<Scalar>(simulator.vanguard().schedule(),
simulator.vanguard().summaryState(),
simulator.vanguard().eclState(),
phase_usage,
simulator.gridView().comm())
, simulator_(simulator)
{
terminal_output_ = ((simulator.gridView().comm().rank() == 0) &&
Parameters::get<TypeTag, Properties::EnableTerminalOutput>());
this->terminal_output_ = ((simulator.gridView().comm().rank() == 0) &&
Parameters::get<TypeTag, Properties::EnableTerminalOutput>());
local_num_cells_ = simulator_.gridView().size(0);
@ -90,9 +90,9 @@ namespace Opm {
.localCellIndex([this](const std::size_t globalIndex)
{ return this->compressedIndexForInterior(globalIndex); })
.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()
.cachedIntensiveQuantities(localCell, /*timeIndex = */0);
@ -146,7 +146,7 @@ namespace Opm {
gravity_ = simulator_.problem().gravity()[2];
initial_step_ = true;
this->initial_step_ = true;
// add the eWoms auxiliary module for the wells to the list
simulator_.model().addAuxiliaryModule(this);
@ -162,9 +162,9 @@ namespace Opm {
{
const uint64_t effective_events_mask = ScheduleEvents::WELL_STATUS_CHANGE
+ ScheduleEvents::NEW_WELL;
const auto& events = schedule()[reportStepIdx].wellgroup_events();
const auto& events = this->schedule()[reportStepIdx].wellgroup_events();
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_,
this->local_num_cells_, this->B_avg_, well_opened_this_step);
}
@ -181,7 +181,7 @@ namespace Opm {
}
// 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.
for (const auto& well : schedule_wells)
@ -419,8 +419,8 @@ namespace Opm {
this->resetWGState();
const int reportStepIdx = simulator_.episodeIndex();
updateAndCommunicateGroupData(reportStepIdx,
simulator_.model().newtonMethod().numIterations());
this->updateAndCommunicateGroupData(reportStepIdx,
simulator_.model().newtonMethod().numIterations());
this->wellState().updateWellsDefaultALQ(this->wells_ecl_, this->summaryState());
this->wellState().gliftTimeStepInit();
@ -436,8 +436,7 @@ namespace Opm {
// Wells are active if they are active wells on at least one process.
const Grid& grid = simulator_.vanguard().grid();
wells_active_ = !this->well_container_.empty();
wells_active_ = grid.comm().max(wells_active_);
this->wells_active_ = grid.comm().max(!this->well_container_.empty());
// do the initialization for all the wells
// 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
calculateEfficiencyFactors(reportStepIdx);
this->calculateEfficiencyFactors(reportStepIdx);
if constexpr (has_polymer_)
{
if (PolymerModule::hasPlyshlog() || getPropValue<TypeTag, Properties::EnablePolymerMW>() ) {
setRepRadiusPerfLength();
this->setRepRadiusPerfLength();
}
}
}
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_) {
well->setVFPProperties(vfp_properties_.get());
well->setGuideRate(&guideRate_);
well->setVFPProperties(this->vfp_properties_.get());
well->setGuideRate(&this->guideRate_);
}
this->updateInjFCMult(local_deferredLogger);
// Close completions due to economic reasons
for (auto& well : well_container_) {
well->closeCompletions(wellTestState());
well->closeCompletions(this->wellTestState());
}
// we need the inj_multiplier from the previous time step
@ -501,10 +500,10 @@ namespace Opm {
// calculate the well potentials
try {
updateWellPotentials(reportStepIdx,
/*onlyAfterEvent*/true,
simulator_.vanguard().summaryConfig(),
local_deferredLogger);
this->updateWellPotentials(reportStepIdx,
/*onlyAfterEvent*/true,
simulator_.vanguard().summaryConfig(),
local_deferredLogger);
} catch ( std::runtime_error& e ) {
const std::string msg = "A zero well potential is returned for output purposes. ";
local_deferredLogger.warning("WELL_POTENTIAL_CALCULATION_FAILED", msg);
@ -512,9 +511,9 @@ namespace Opm {
//update guide rates
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);
WellGroupHelpers<double>::updateGuideRates(fieldGroup,
WellGroupHelpers<Scalar>::updateGuideRates(fieldGroup,
this->schedule(),
summaryState,
this->phase_usage_,
@ -529,12 +528,12 @@ namespace Opm {
std::string exc_msg;
auto exc_type = ExceptionType::NONE;
// update gpmaint targets
if (schedule_[reportStepIdx].has_gpmaint()) {
if (this->schedule_[reportStepIdx].has_gpmaint()) {
for (auto& calculator : regionalAveragePressureCalculator_) {
calculator.second->template defineState<ElementContext>(simulator_);
}
const double dt = simulator_.timeStepSize();
WellGroupHelpers<double>::updateGpMaintTargetForGroups(fieldGroup,
WellGroupHelpers<Scalar>::updateGpMaintTargetForGroups(fieldGroup,
this->schedule_,
regionalAveragePressureCalculator_,
reportStepIdx,
@ -550,8 +549,8 @@ namespace Opm {
+ ScheduleEvents::WELL_SWITCHED_INJECTOR_PRODUCER
+ ScheduleEvents::NEW_WELL;
const auto& events = schedule()[reportStepIdx].wellgroup_events();
const bool event = report_step_starts_ && events.hasEvent(well->name(), effective_events_mask);
const auto& events = this->schedule()[reportStepIdx].wellgroup_events();
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
!= this->prevWellState().well(well->name()).status;
@ -576,7 +575,7 @@ namespace Opm {
}
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)
{
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)
continue;
WellInterfacePtr well = createWellForWellTest(well_name, timeStepIdx, deferred_logger);
// 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();
WellGroupHelpers<double>::accumulateGroupEfficiencyFactor(this->schedule().getGroup(wellEcl.groupName(),
Scalar well_efficiency_factor = wellEcl.getEfficiencyFactor();
WellGroupHelpers<Scalar>::accumulateGroupEfficiencyFactor(this->schedule().getGroup(wellEcl.groupName(),
timeStepIdx),
this->schedule(),
timeStepIdx,
well_efficiency_factor);
well->setWellEfficiencyFactor(well_efficiency_factor);
well->setVFPProperties(vfp_properties_.get());
well->setGuideRate(&guideRate_);
well->setVFPProperties(this->vfp_properties_.get());
well->setGuideRate(&this->guideRate_);
// initialize rates/previous rates to prevent zero fractions in vfp-interpolation
if (well->isProducer()) {
@ -615,7 +614,8 @@ namespace Opm {
}
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) {
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);
@ -663,7 +663,7 @@ namespace Opm {
this->closed_this_step_.clear();
// 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();
DeferredLogger local_deferredLogger;
@ -690,9 +690,9 @@ namespace Opm {
well->reportWellSwitching(this->wellState().well(well->indexOfWell()), local_deferredLogger);
}
// 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);
std::string from = Group::ProductionCMode2String(oldControl);
if (to != from) {
@ -703,7 +703,7 @@ namespace Opm {
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 Opm::Phase& phase = key.second;
@ -724,23 +724,23 @@ namespace Opm {
// calculate the well potentials
try {
updateWellPotentials(reportStepIdx,
/*onlyAfterEvent*/false,
simulator_.vanguard().summaryConfig(),
local_deferredLogger);
this->updateWellPotentials(reportStepIdx,
/*onlyAfterEvent*/false,
simulator_.vanguard().summaryConfig(),
local_deferredLogger);
} catch ( std::runtime_error& e ) {
const std::string msg = "A zero well potential is returned for output purposes. ";
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
const Group& fieldGroup = schedule_.getGroup("FIELD", reportStepIdx);
checkGEconLimits(
fieldGroup, simulationTime, simulator_.episodeIndex(), local_deferredLogger);
checkGconsaleLimits(fieldGroup, this->wellState(),
simulator_.episodeIndex(), local_deferredLogger);
const Group& fieldGroup = this->schedule_.getGroup("FIELD", reportStepIdx);
this->checkGEconLimits(fieldGroup, simulationTime,
simulator_.episodeIndex(), local_deferredLogger);
this->checkGconsaleLimits(fieldGroup, this->wellState(),
simulator_.episodeIndex(), local_deferredLogger);
this->calculateProductivityIndexValues(local_deferredLogger);
@ -748,7 +748,7 @@ namespace Opm {
const Opm::Parallel::Communication& comm = grid().comm();
DeferredLogger global_deferredLogger = gatherDeferredLogger(local_deferredLogger, comm);
if (terminal_output_) {
if (this->terminal_output_) {
global_deferredLogger.logMessages();
}
@ -799,7 +799,7 @@ namespace Opm {
BlackoilWellModel<TypeTag>::
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_);
const auto& gridView = simulator_.vanguard().gridView();
@ -811,7 +811,7 @@ namespace Opm {
const auto& fs = elemCtx.intensiveQuantities(/*spaceIdx=*/0, /*timeIdx=*/0).fluidState();
// 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) {
perf_pressure = fs.pressure(FluidSystem::oilPhaseIdx).value();
} else if (Indices::waterEnabled) {
@ -822,8 +822,9 @@ namespace Opm {
}
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->prevWellState(), well_perf_data_,
this->wellState().init(cellPressures, this->schedule(), this->wells_ecl_,
this->local_parallel_well_info_, timeStepIdx,
&this->prevWellState(), this->well_perf_data_,
this->summaryState());
}
@ -838,7 +839,7 @@ namespace Opm {
{
DeferredLogger local_deferredLogger;
const int nw = numLocalWells();
const int nw = this->numLocalWells();
well_container_.clear();
@ -846,7 +847,7 @@ namespace Opm {
well_container_.reserve(nw);
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()) {
// No connections in this well. Nothing to do.
@ -875,14 +876,14 @@ namespace Opm {
// a timestep without the well in question, after it caused
// repeated timestep cuts. It should therefore not be opened,
// 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
// maybe there is some WCON keywords will not open the well
auto& events = this->wellState().well(w).events;
if (events.hasEvent(ScheduleEvents::REQUEST_OPEN_WELL)) {
if (!closed_this_step) {
wellTestState().open_well(well_name);
wellTestState().open_completions(well_name);
this->wellTestState().open_well(well_name);
this->wellTestState().open_completions(well_name);
}
events.clearEvent(ScheduleEvents::REQUEST_OPEN_WELL);
}
@ -891,7 +892,7 @@ namespace Opm {
// TODO: should we do this for all kinds of closing reasons?
// something like wellTestState().hasWell(well_name)?
bool wellIsStopped = false;
if (wellTestState().well_is_closed(well_name))
if (this->wellTestState().well_is_closed(well_name))
{
if (well_ecl.getAutomaticShutIn()) {
// shut wells are not added to the well container
@ -913,8 +914,8 @@ namespace Opm {
// shut wells with zero rante constraints and disallowing
if (!well_ecl.getAllowCrossFlow()) {
const bool any_zero_rate_constraint = well_ecl.isProducer()
? well_ecl.productionControls(summaryState_).anyZeroRateConstraint()
: well_ecl.injectionControls(summaryState_).anyZeroRateConstraint();
? well_ecl.productionControls(this->summaryState_).anyZeroRateConstraint()
: well_ecl.injectionControls(this->summaryState_).anyZeroRateConstraint();
if (any_zero_rate_constraint) {
// 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()) );
@ -939,26 +940,26 @@ namespace Opm {
const Opm::Parallel::Communication& comm = grid().comm();
DeferredLogger global_deferredLogger = gatherDeferredLogger(local_deferredLogger, comm);
if (terminal_output_) {
if (this->terminal_output_) {
global_deferredLogger.logMessages();
}
well_container_generic_.clear();
this->well_container_generic_.clear();
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()) {
for (auto& well: well_container_generic_) {
for (auto& well: this->well_container_generic_) {
// Producers only, since we so far only support the
// "extended" network model (properties defined by
// BRANPROP and NODEPROP) which only applies to producers.
if (well->isProducer()) {
const auto it = node_pressures_.find(well->wellEcl().groupName());
if (it != node_pressures_.end()) {
const auto it = this->node_pressures_.find(well->wellEcl().groupName());
if (it != this->node_pressures_.end()) {
// The well belongs to a group which has a 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);
}
}
@ -1002,7 +1003,7 @@ namespace Opm {
// Cater for case where local part might have no perforations.
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 global_pvtreg = parallel_well_info.broadcastFirstPerforationValue(pvtreg);
@ -1031,10 +1032,10 @@ namespace Opm {
DeferredLogger& deferred_logger) const
{
// 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;
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;
}
}
@ -1100,22 +1101,22 @@ namespace Opm {
if (this->glift_debug) {
const std::string msg = fmt::format(
"assemble() : iteration {}" , iterationIdx);
gliftDebug(msg, local_deferredLogger);
this->gliftDebug(msg, local_deferredLogger);
}
last_report_ = SimulatorReportSingle();
Dune::Timer perfTimer;
perfTimer.start();
closed_offending_wells_.clear();
this->closed_offending_wells_.clear();
{
const int episodeIdx = simulator_.episodeIndex();
const auto& network = schedule()[episodeIdx].network();
if ( !wellsActive() && !network.active() ) {
const auto& network = this->schedule()[episodeIdx].network();
if (!this->wellsActive() && !network.active()) {
return;
}
}
if (iterationIdx == 0 && wellsActive()) {
if (iterationIdx == 0 && this->wellsActive()) {
// try-catch is needed here as updateWellControls
// contains global communication and has either to
// be reached by all processes or all need to abort
@ -1127,14 +1128,14 @@ namespace Opm {
}
OPM_END_PARALLEL_TRY_CATCH_LOG(local_deferredLogger,
"assemble() failed (It=0): ",
terminal_output_, grid().comm());
this->terminal_output_, grid().comm());
}
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()
// but there is no need to assemble the well equations
if ( ! wellsActive() ) {
if ( ! this->wellsActive() ) {
return;
}
@ -1163,7 +1164,7 @@ namespace Opm {
const std::size_t max_iteration = param_.network_max_iterations_;
std::size_t network_update_iteration = 0;
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 ");
}
const bool relax_network_balance = network_update_iteration >= iteration_to_relax;
@ -1172,7 +1173,7 @@ namespace Opm {
++network_update_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. "
"The simulation will continue with unconverged network results");
}
@ -1207,18 +1208,18 @@ namespace Opm {
prepareWellsBeforeAssembling(dt, local_deferredLogger);
}
OPM_END_PARALLEL_TRY_CATCH_LOG(local_deferredLogger, "updateWellControlsAndNetworkIteration() failed: ",
terminal_output_, grid().comm());
this->terminal_output_, grid().comm());
//update guide rates
const int reportStepIdx = simulator_.episodeIndex();
if (alq_updated || BlackoilWellModelGuideRates(*this).
guideRateUpdateIsNeeded(reportStepIdx)) {
guideRateUpdateIsNeeded(reportStepIdx)) {
const double simulationTime = simulator_.time();
const auto& comm = simulator_.vanguard().grid().comm();
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);
WellGroupHelpers<double>::updateGuideRates(fieldGroup,
WellGroupHelpers<Scalar>::updateGuideRates(fieldGroup,
this->schedule(),
summaryState,
this->phase_usage_,
@ -1250,8 +1251,8 @@ namespace Opm {
{
const int episodeIdx = simulator_.episodeIndex();
const auto& network = schedule()[episodeIdx].network();
if ( !wellsActive() && !network.active() ) {
const auto& network = this->schedule()[episodeIdx].network();
if (!this->wellsActive() && !network.active()) {
return;
}
}
@ -1268,7 +1269,7 @@ namespace Opm {
// 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.
if (terminal_output_) {
if (this->terminal_output_) {
local_deferredLogger.logMessages();
}
@ -1285,14 +1286,14 @@ namespace Opm {
bool do_glift_optimization = false;
int num_wells_changed = 0;
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.
// 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_
// 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;
last_glift_opt_time_ = simulation_time;
this->last_glift_opt_time_ = simulation_time;
}
if (do_glift_optimization) {
@ -1314,7 +1315,7 @@ namespace Opm {
simulator_.vanguard().summaryState(),
simulator_.episodeIndex(),
simulator_.model().newtonMethod().numIterations(),
phase_usage_,
this->phase_usage_,
deferred_logger,
this->wellState(),
this->groupState(),
@ -1322,12 +1323,13 @@ namespace Opm {
this->glift_debug
};
group_info.initialize();
gasLiftOptimizationStage1(
deferred_logger, prod_wells, glift_wells, group_info, state_map);
gasLiftOptimizationStage2(
deferred_logger, prod_wells, glift_wells, group_info, state_map,
simulator_.episodeIndex());
if (this->glift_debug) gliftDebugShowALQ(deferred_logger);
gasLiftOptimizationStage1(deferred_logger, prod_wells, glift_wells,
group_info, state_map);
this->gasLiftOptimizationStage2(deferred_logger, prod_wells, glift_wells,
group_info, state_map, simulator_.episodeIndex());
if (this->glift_debug) {
this->gliftDebugShowALQ(deferred_logger);
}
num_wells_changed = glift_wells.size();
}
num_wells_changed = this->comm_.sum(num_wells_changed);
@ -1388,13 +1390,13 @@ namespace Opm {
if (num_rates_to_sync > 0) {
std::vector<int> group_indexes;
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);
std::vector<double> group_oil_rates;
std::vector<Scalar> group_oil_rates;
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);
std::vector<double> group_water_rates;
std::vector<Scalar> group_water_rates;
group_water_rates.reserve(num_rates_to_sync);
if (comm.rank() == i) {
for (auto idx : groups_to_sync) {
@ -1527,7 +1529,7 @@ namespace Opm {
deferred_logger);
}
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;
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++){
const auto& perfcells = wellconnections[i];
for(int perfcell : perfcells){
@ -1705,7 +1707,7 @@ namespace Opm {
}
OPM_END_PARALLEL_TRY_CATCH_LOG(local_deferredLogger,
"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
// be stored in the local_deferredlogger in a parallel case.
if (terminal_output_) {
if (this->terminal_output_) {
local_deferredLogger.logMessages();
}
}
@ -1792,7 +1794,7 @@ namespace Opm {
}
// Log debug messages for NaN or too large residuals.
if (terminal_output_) {
if (this->terminal_output_) {
for (const auto& f : report.wellFailures()) {
if (f.severity() == ConvergenceReport::Severity::NotANumber) {
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);
}
if (terminal_output_) {
if (this->terminal_output_) {
global_deferredLogger.logMessages();
}
// Log debug messages for NaN or too large residuals.
if (terminal_output_) {
if (this->terminal_output_) {
for (const auto& f : report.wellFailures()) {
if (f.severity() == ConvergenceReport::Severity::NotANumber) {
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)
{
const int episodeIdx = simulator_.episodeIndex();
const auto& network = schedule()[episodeIdx].network();
if (!wellsActive() && !network.active()) {
const auto& network = this->schedule()[episodeIdx].network();
if (!this->wellsActive() && !network.active()) {
return {false, false};
}
const int iterationIdx = simulator_.model().newtonMethod().numIterations();
const auto& comm = simulator_.vanguard().grid().comm();
updateAndCommunicateGroupData(episodeIdx, iterationIdx);
this->updateAndCommunicateGroupData(episodeIdx, iterationIdx);
// network related
bool more_network_update = false;
if (shouldBalanceNetwork(episodeIdx, iterationIdx) || mandatory_network_balance) {
const auto local_network_imbalance = updateNetworkPressures(episodeIdx);
const double network_imbalance = comm.max(local_network_imbalance);
const auto& balance = schedule()[episodeIdx].network_balance();
constexpr double relaxtion_factor = 10.0;
const double tolerance = relax_network_tolerance ? relaxtion_factor * balance.pressure_tolerance() : balance.pressure_tolerance();
if (this->shouldBalanceNetwork(episodeIdx, iterationIdx) || mandatory_network_balance) {
const auto local_network_imbalance = this->updateNetworkPressures(episodeIdx);
const Scalar network_imbalance = comm.max(local_network_imbalance);
const auto& balance = this->schedule()[episodeIdx].network_balance();
constexpr Scalar relaxation_factor = 10.0;
const Scalar tolerance = relax_network_tolerance ? relaxation_factor * balance.pressure_tolerance() : balance.pressure_tolerance();
more_network_update = this->networkActive() && network_imbalance > tolerance;
}
bool changed_well_group = false;
// 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
// to avoid oscilations between group controls
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);
}
// Check wells' group constraints and communicate.
@ -1958,8 +1960,8 @@ namespace Opm {
}
// update wsolvent fraction for REIN wells
const Group& fieldGroup = schedule().getGroup("FIELD", episodeIdx);
updateWsolvent(fieldGroup, episodeIdx, this->nupcolWellState());
const Group& fieldGroup = this->schedule().getGroup("FIELD", episodeIdx);
this->updateWsolvent(fieldGroup, episodeIdx, this->nupcolWellState());
return { changed_well_group, more_network_update };
}
@ -1969,7 +1971,7 @@ namespace Opm {
BlackoilWellModel<TypeTag>::
updateWellControlsDomain(DeferredLogger& deferred_logger, const Domain& domain)
{
if ( !wellsActive() ) return ;
if ( !this->wellsActive() ) return ;
// TODO: decide on and implement an approach to handling of
// group controls, network and similar for domain solves.
@ -2066,7 +2068,7 @@ namespace Opm {
BlackoilWellModel<TypeTag>::
makeWellSourceEvaluatorFactory(const std::vector<Well>::size_type wellIdx) const
{
using Span = PAvgDynamicSourceData::SourceDataSpan<double>;
using Span = PAvgDynamicSourceData::SourceDataSpan<Scalar>;
using Item = typename Span::Item;
return [wellIdx, this]() -> ParallelWBPCalculation::Evaluator
@ -2140,18 +2142,19 @@ namespace Opm {
const int iterationIdx,
DeferredLogger& deferred_logger)
{
updateAndCommunicateGroupData(reportStepIdx, iterationIdx);
this->updateAndCommunicateGroupData(reportStepIdx, iterationIdx);
// updateWellStateWithTarget might throw for multisegment wells hence we
// have a parallel try catch here to thrown on all processes.
OPM_BEGIN_PARALLEL_TRY_CATCH()
// if a well or group change control it affects all wells that are under the same group
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: ",
simulator_.gridView().comm())
updateAndCommunicateGroupData(reportStepIdx, iterationIdx);
this->updateAndCommunicateGroupData(reportStepIdx, iterationIdx);
}
template<typename TypeTag>
@ -2163,7 +2166,7 @@ namespace Opm {
const int iterationIdx)
{
bool changed = false;
bool changed_hc = checkGroupHigherConstraints( group, deferred_logger, reportStepIdx);
bool changed_hc = this->checkGroupHigherConstraints( group, deferred_logger, reportStepIdx);
if (changed_hc) {
changed = true;
updateAndCommunicate(reportStepIdx, iterationIdx, deferred_logger);
@ -2186,7 +2189,7 @@ namespace Opm {
}
// call recursively down the group hierarchy
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;
}
return changed;
@ -2212,28 +2215,23 @@ namespace Opm {
const Opm::Parallel::Communication comm = grid().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)) {
wellTestState.close_well(
to.second, WellTestConfig::Reason::GROUP, simulationTime);
wellTestState.close_well(to.second, WellTestConfig::Reason::GROUP, simulationTime);
this->updateClosedWellsThisStep(to.second);
std::string msg = fmt::format("Procedure on exceeding {} limit is WELL for group {}. Well {} is {}.",
to.first,
group_name,
to.second,
"shut");
const std::string msg =
fmt::format("Procedure on exceeding {} limit is WELL for group {}. Well {} is {}.",
to.first,
group_name,
to.second,
"shut");
global_deferredLogger.info(msg);
}
}
if (terminal_output_) {
if (this->terminal_output_) {
global_deferredLogger.logMessages();
}
}
@ -2245,8 +2243,8 @@ namespace Opm {
ExceptionType::ExcEnum& exc_type,
DeferredLogger& deferred_logger)
{
const int np = numPhases();
std::vector<double> potentials;
const int np = this->numPhases();
std::vector<Scalar> potentials;
const auto& well = well_container_[widx];
std::string cur_exc_msg;
auto cur_exc_type = ExceptionType::NONE;
@ -2445,9 +2443,9 @@ namespace Opm {
const auto& eclProblem = simulator_.problem();
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) {
pvt_region_idx_[cellIdx] =
this->pvt_region_idx_[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 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.
int numComp = numPhases() < 3? numPhases(): FluidSystem::numComponents;
int numComp = this->numPhases() < 3 ? this->numPhases() : FluidSystem::numComponents;
if constexpr (has_solvent_) {
numComp++;
}
@ -2530,8 +2528,8 @@ namespace Opm {
BlackoilWellModel<TypeTag>::
calcRates(const int fipnum,
const int pvtreg,
const std::vector<double>& production_rates,
std::vector<double>& resv_coeff)
const std::vector<Scalar>& production_rates,
std::vector<Scalar>& resv_coeff)
{
rateConverter_->calcCoeff(fipnum, pvtreg, production_rates, resv_coeff);
}
@ -2540,8 +2538,8 @@ namespace Opm {
void
BlackoilWellModel<TypeTag>::
calcInjRates(const int fipnum,
const int pvtreg,
std::vector<double>& resv_coeff)
const int pvtreg,
std::vector<Scalar>& resv_coeff)
{
rateConverter_->calcInjCoeff(fipnum, pvtreg, resv_coeff);
}
@ -2555,35 +2553,35 @@ namespace Opm {
if (!has_energy_)
return;
int np = numPhases();
double cellInternalEnergy;
double cellBinv;
double cellDensity;
double perfPhaseRate;
const int nw = numLocalWells();
int np = this->numPhases();
Scalar cellInternalEnergy;
Scalar cellBinv;
Scalar cellDensity;
Scalar perfPhaseRate;
const int nw = this->numLocalWells();
for (auto wellID = 0*nw; wellID < nw; ++wellID) {
const Well& well = wells_ecl_[wellID];
const Well& well = this->wells_ecl_[wellID];
if (well.isInjector())
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& 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& perf_data = ws.perf_data;
auto& perf_phase_rate = perf_data.phase_rates;
using int_type = decltype(well_perf_data_[wellID].size());
for (int_type perf = 0, end_perf = well_perf_data_[wellID].size(); perf < end_perf; ++perf) {
const int cell_idx = well_perf_data_[wellID][perf].cell_index;
using int_type = decltype(this->well_perf_data_[wellID].size());
for (int_type perf = 0, end_perf = this->well_perf_data_[wellID].size(); perf < end_perf; ++perf) {
const int cell_idx = this->well_perf_data_[wellID][perf].cell_index;
const auto& intQuants = simulator_.model().intensiveQuantities(cell_idx, /*timeIdx=*/0);
const auto& fs = intQuants.fluidState();
// 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)
{
if (!FluidSystem::phaseIsActive(phaseIdx)) {
@ -2613,7 +2611,7 @@ namespace Opm {
for (const auto& w : well_container_) {
os << w->name() << ":";
auto pv = w->getPrimaryVars();
for (const double v : pv) {
for (const Scalar v : pv) {
os << ' ' << v;
}
os << '\n';
@ -2624,11 +2622,11 @@ namespace Opm {
template <typename TypeTag>
std::vector<double>
std::vector<typename BlackoilWellModel<TypeTag>::Scalar>
BlackoilWellModel<TypeTag>::
getPrimaryVarsDomain(const Domain& domain) const
{
std::vector<double> ret;
std::vector<Scalar> ret;
for (const auto& well : well_container_) {
if (well_domain_.at(well->name()) == domain.index) {
const auto& pv = well->getPrimaryVars();
@ -2643,7 +2641,7 @@ namespace Opm {
template <typename TypeTag>
void
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;
for (auto& well : well_container_) {
@ -2708,7 +2706,7 @@ namespace Opm {
local_log.debug(os.str());
}
auto global_log = gatherDeferredLogger(local_log, comm);
if (terminal_output_) {
if (this->terminal_output_) {
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>
GroupEconomicLimitsChecker<Scalar>::
GroupEconomicLimitsChecker(const BlackoilWellModelGeneric& well_model,
GroupEconomicLimitsChecker(const BlackoilWellModelGeneric<Scalar>& well_model,
WellTestState& well_test_state,
const Group& group,
const double simulation_time,

View File

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

View File

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