mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-01-16 01:51:55 -06:00
Merge pull request #5299 from akva2/blackoilwellmodel_template_scalar
BlackoilWellModel: template Scalar type
This commit is contained in:
commit
20949ea950
@ -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)
|
||||
|
@ -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_;
|
||||
};
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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>;
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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>;
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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_;
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user