Explicitly delete UDAValue::operator=()

This commit is contained in:
Joakim Hove 2020-10-29 15:52:26 +01:00
parent f34f221be8
commit 9bec2673ad
9 changed files with 64 additions and 53 deletions

View File

@ -38,6 +38,19 @@ public:
UDAValue(double data, const Dimension& dim);
UDAValue(const std::string& data, const Dimension& dim);
/*
The assignment operators have been explicitly deleted, that is to prevent
people from adding them at a later stage. It seems very tempting/natural
to implement these assignment operators, but the problem is that the
resulting UDA object will typically have the wrong dimension member, and
subtle dimension related bugs will arise.
*/
UDAValue& operator=(double value) = delete;
UDAValue& operator=(const std::string& value) = delete;
void update(double d);
void update(const std::string& s);
void update_value(const UDAValue& other);
static UDAValue serializeObject();
/*
@ -66,9 +79,6 @@ public:
bool operator==(const UDAValue& other) const;
bool operator!=(const UDAValue& other) const;
UDAValue& operator=(double value);
UDAValue& operator=(const std::string& value);
void update_value(const UDAValue& other);
bool is_numeric() { return numeric_value; }

View File

@ -71,13 +71,16 @@ RstWell::RstWell(const ::Opm::UnitSystem& unit_system,
completion_ordering( iwel[VI::IWell::CompOrd]),
pvt_table( def_pvt_table),
msw_pressure_drop_model( iwel[VI::IWell::MSW_PlossMod]),
orat_target( unit_system.to_si(M::identity, swel_value(swel[VI::SWell::OilRateTarget]))),
wrat_target( unit_system.to_si(M::identity, swel_value(swel[VI::SWell::WatRateTarget]))),
grat_target( unit_system.to_si(M::identity, swel_value(swel[VI::SWell::GasRateTarget]))),
lrat_target( unit_system.to_si(M::identity, swel_value(swel[VI::SWell::LiqRateTarget]))),
resv_target( unit_system.to_si(M::identity, swel_value(swel[VI::SWell::ResVRateTarget]))),
thp_target( unit_system.to_si(M::identity, swel_value(swel[VI::SWell::THPTarget]))),
bhp_target_float( unit_system.to_si(M::identity, swel[VI::SWell::BHPTarget])),
// The values orat_target -> bhp_target_flow will be used in UDA values. The
// UDA values are responsible for unit conversion and raw values are
// internalized here.
orat_target( swel_value(swel[VI::SWell::OilRateTarget])),
wrat_target( swel_value(swel[VI::SWell::WatRateTarget])),
grat_target( swel_value(swel[VI::SWell::GasRateTarget])),
lrat_target( swel_value(swel[VI::SWell::LiqRateTarget])),
resv_target( swel_value(swel[VI::SWell::ResVRateTarget])),
thp_target( swel_value(swel[VI::SWell::THPTarget])),
bhp_target_float( swel[VI::SWell::BHPTarget]),
hist_lrat_target( unit_system.to_si(M::liquid_surface_rate, swel[VI::SWell::HistLiqRateTarget])),
hist_grat_target( unit_system.to_si(M::gas_surface_rate, swel[VI::SWell::HistGasRateTarget])),
hist_bhp_target( unit_system.to_si(M::pressure, swel[VI::SWell::HistBHPTarget])),

View File

@ -115,16 +115,14 @@ double UDAValue::getSI() const {
}
UDAValue& UDAValue::operator=(double value) {
void UDAValue::update(double value) {
this->double_value = value;
this->numeric_value = true;
return *this;
}
UDAValue& UDAValue::operator=(const std::string& value) {
void UDAValue::update(const std::string& value) {
this->string_value = value;
this->numeric_value = false;
return *this;
}

View File

@ -383,7 +383,7 @@ namespace {
{
auto group_ptr = std::make_shared<Group>(this->getGroup(group_name, handlerContext.currentStep));
Group::GroupProductionProperties production(group_name);
Group::GroupProductionProperties production(handlerContext.section.unitSystem(), group_name);
production.gconprod_cmode = controlMode;
production.active_cmode = controlMode;
production.oil_target = oil_target;

View File

@ -161,12 +161,12 @@ Well::Well(const RestartIO::RstWell& rst_well,
auto p = std::make_shared<WellProductionProperties>(this->unit_system, wname);
// Reverse of function ctrlMode() in AggregateWellData.cpp
p->whistctl_cmode = def_whistctl_cmode;
p->BHPTarget = rst_well.bhp_target_float;
p->OilRate = rst_well.orat_target ;
p->WaterRate = rst_well.wrat_target ;
p->GasRate = rst_well.grat_target ;
p->LiquidRate = rst_well.lrat_target ;
p->ResVRate = rst_well.resv_target ;
p->BHPTarget.update(rst_well.bhp_target_float);
p->OilRate.update(rst_well.orat_target);
p->WaterRate.update(rst_well.wrat_target);
p->GasRate.update(rst_well.grat_target);
p->LiquidRate.update(rst_well.lrat_target) ;
p->ResVRate.update(rst_well.resv_target);
p->VFPTableNumber = rst_well.vfp_table;
p->ALQValue = rst_well.alq_value;
p->predictionMode = this->prediction_mode;
@ -187,7 +187,7 @@ Well::Well(const RestartIO::RstWell& rst_well,
p->addProductionControl( Well::ProducerCMode::RESV );
if (rst_well.thp_target != 0) {
p->THPTarget = rst_well.thp_target;
p->THPTarget.update(rst_well.thp_target);
p->addProductionControl( Well::ProducerCMode::THP );
}
@ -270,10 +270,10 @@ Well::Well(const RestartIO::RstWell& rst_well,
i->injectorType = rst_well.wtype.injector_type();
switch (i->injectorType) {
case InjectorType::WATER:
i->surfaceInjectionRate = rst_well.wrat_target;
i->surfaceInjectionRate.update(rst_well.wrat_target);
break;
case InjectorType::GAS:
i->surfaceInjectionRate = rst_well.grat_target;
i->surfaceInjectionRate.update(rst_well.grat_target);
break;
default:
throw std::invalid_argument("What ...");
@ -284,17 +284,17 @@ Well::Well(const RestartIO::RstWell& rst_well,
i->addInjectionControl(Well::InjectorCMode::RATE);
if (std::abs(rst_well.resv_target) > 0.0f) {
i->reservoirInjectionRate = rst_well.resv_target;
i->reservoirInjectionRate.update(rst_well.resv_target);
i->addInjectionControl(Well::InjectorCMode::RESV);
}
i->addInjectionControl(Well::InjectorCMode::BHP);
i->BHPTarget = rst_well.bhp_target_float;
i->BHPTarget.update(rst_well.bhp_target_float);
if (this->isAvailableForGroupControl())
i->addInjectionControl(Well::InjectorCMode::GRUP);
if (rst_well.thp_target != 0) {
i->THPTarget = rst_well.thp_target;
i->THPTarget.update(rst_well.thp_target);
i->addInjectionControl(Well::InjectorCMode::THP);
}
@ -463,7 +463,7 @@ bool Well::updateEconLimits(std::shared_ptr<WellEconProductionLimits> econ_limit
void Well::switchToProducer() {
auto p = std::make_shared<WellInjectionProperties>(this->getInjectionProperties());
p->BHPTarget = 0;
p->BHPTarget.update(0);
p->dropInjectionControl( Opm::Well::InjectorCMode::BHP );
this->updateInjection( p );
this->wtype.update(true);

View File

@ -181,7 +181,7 @@ namespace Opm {
if (!record.getItem("RATE").defaultApplied(0)) {
double injectionRate = record.getItem("RATE").get<double>(0);
this->surfaceInjectionRate = injectionRate;
this->surfaceInjectionRate.update(injectionRate);
}
if ( record.getItem( "BHP" ).hasValue(0) )
this->BHPH = record.getItem("BHP").getSIDouble(0);

View File

@ -207,8 +207,8 @@ void Well::WellProductionProperties::handleWCONHIST(const std::optional<VFPProdT
{
this->init_rates(record);
this->init_vfp(alq_type, unit_system_arg, record);
this->LiquidRate = 0;
this->ResVRate = 0;
this->LiquidRate.update(0);
this->ResVRate.update(0);
// when the well is switching to history matching producer from prediction mode
// or switching from injector to producer

View File

@ -1338,10 +1338,10 @@ BOOST_AUTO_TEST_CASE(UDA_VALUE) {
BOOST_CHECK(!value0.is<std::string>());
BOOST_CHECK_EQUAL( value0.get<double>(), 0);
BOOST_CHECK_THROW( value0.get<std::string>(), std::invalid_argument);
value0 = 10;
value0.update(10);
BOOST_CHECK_EQUAL( value0.get<double>(), 10);
BOOST_CHECK_THROW( value0.get<std::string>(), std::invalid_argument);
value0 = "STRING";
value0.update("STRING");
BOOST_CHECK_EQUAL( value0.get<std::string>(), std::string("STRING"));
BOOST_CHECK_THROW( value0.get<double>(), std::invalid_argument);

View File

@ -220,7 +220,7 @@ BOOST_AUTO_TEST_CASE(isProducerCorrectlySet) {
/* Set a surface injection rate => Well becomes an Injector */
auto injectionProps1 = std::make_shared<Opm::Well::WellInjectionProperties>(well.getInjectionProperties());
injectionProps1->surfaceInjectionRate = 100;
injectionProps1->surfaceInjectionRate.update(100);
well.updateInjection(injectionProps1);
BOOST_CHECK_EQUAL( true , well.isInjector());
BOOST_CHECK_EQUAL( false , well.isProducer());
@ -233,7 +233,7 @@ BOOST_AUTO_TEST_CASE(isProducerCorrectlySet) {
/* Set a reservoir injection rate => Well becomes an Injector */
auto injectionProps2 = std::make_shared<Opm::Well::WellInjectionProperties>(well.getInjectionProperties());
injectionProps2->reservoirInjectionRate = 200;
injectionProps2->reservoirInjectionRate.update(200);
well.updateInjection(injectionProps2);
BOOST_CHECK_EQUAL( false , well.isProducer());
BOOST_CHECK_EQUAL( 200 , well.getInjectionProperties().reservoirInjectionRate.get<double>());
@ -247,9 +247,9 @@ BOOST_AUTO_TEST_CASE(isProducerCorrectlySet) {
well.updateInjection(injectionProps3);
auto properties = std::make_shared<Opm::Well::WellProductionProperties>( well.getProductionProperties() );
properties->OilRate = 100;
properties->GasRate = 200;
properties->WaterRate = 300;
properties->OilRate.update(100);
properties->GasRate.update(200);
properties->WaterRate.update(300);
well.updateProduction(properties);
BOOST_CHECK_EQUAL( false , well.isInjector());
@ -286,14 +286,14 @@ BOOST_AUTO_TEST_CASE(XHPLimitDefault) {
auto productionProps = std::make_shared<Opm::Well::WellProductionProperties>(well.getProductionProperties());
productionProps->BHPTarget = 100;
productionProps->BHPTarget.update(100);
productionProps->addProductionControl(Opm::Well::ProducerCMode::BHP);
well.updateProduction(productionProps);
BOOST_CHECK_EQUAL( 100 , well.getProductionProperties().BHPTarget.get<double>());
BOOST_CHECK_EQUAL( true, well.getProductionProperties().hasProductionControl( Opm::Well::ProducerCMode::BHP ));
auto injProps = std::make_shared<Opm::Well::WellInjectionProperties>(well.getInjectionProperties());
injProps->THPTarget = 200;
injProps->THPTarget.update(200);
well.updateInjection(injProps);
BOOST_CHECK_EQUAL( 200 , well.getInjectionProperties().THPTarget.get<double>());
BOOST_CHECK( !well.getInjectionProperties().hasInjectionControl( Opm::Well::InjectorCMode::THP ));
@ -327,26 +327,26 @@ BOOST_AUTO_TEST_CASE(WellHaveProductionControlLimit) {
BOOST_CHECK( !well.getProductionProperties().hasProductionControl( Opm::Well::ProducerCMode::RESV ));
auto properties1 = std::make_shared<Opm::Well::WellProductionProperties>(well.getProductionProperties());
properties1->OilRate = 100;
properties1->OilRate.update(100);
properties1->addProductionControl(Opm::Well::ProducerCMode::ORAT);
well.updateProduction(properties1);
BOOST_CHECK( well.getProductionProperties().hasProductionControl( Opm::Well::ProducerCMode::ORAT ));
BOOST_CHECK( !well.getProductionProperties().hasProductionControl( Opm::Well::ProducerCMode::RESV ));
auto properties2 = std::make_shared<Opm::Well::WellProductionProperties>(well.getProductionProperties());
properties2->ResVRate = 100;
properties2->ResVRate.update(100);
properties2->addProductionControl(Opm::Well::ProducerCMode::RESV);
well.updateProduction(properties2);
BOOST_CHECK( well.getProductionProperties().hasProductionControl( Opm::Well::ProducerCMode::RESV ));
auto properties3 = std::make_shared<Opm::Well::WellProductionProperties>(well.getProductionProperties());
properties3->OilRate = 100;
properties3->WaterRate = 100;
properties3->GasRate = 100;
properties3->LiquidRate = 100;
properties3->ResVRate = 100;
properties3->BHPTarget = 100;
properties3->THPTarget = 100;
properties3->OilRate.update(100);
properties3->WaterRate.update(100);
properties3->GasRate.update(100);
properties3->LiquidRate.update(100);
properties3->ResVRate.update(100);
properties3->BHPTarget.update(100);
properties3->THPTarget.update(100);
properties3->addProductionControl(Opm::Well::ProducerCMode::ORAT);
properties3->addProductionControl(Opm::Well::ProducerCMode::LRAT);
properties3->addProductionControl(Opm::Well::ProducerCMode::BHP);
@ -373,22 +373,22 @@ BOOST_AUTO_TEST_CASE(WellHaveInjectionControlLimit) {
BOOST_CHECK( !well.getInjectionProperties().hasInjectionControl( Opm::Well::InjectorCMode::RESV ));
auto injProps1 = std::make_shared<Opm::Well::WellInjectionProperties>(well.getInjectionProperties());
injProps1->surfaceInjectionRate = 100;
injProps1->surfaceInjectionRate.update(100);
injProps1->addInjectionControl(Opm::Well::InjectorCMode::RATE);
well.updateInjection(injProps1);
BOOST_CHECK( well.getInjectionProperties().hasInjectionControl( Opm::Well::InjectorCMode::RATE ));
BOOST_CHECK( !well.getInjectionProperties().hasInjectionControl( Opm::Well::InjectorCMode::RESV ));
auto injProps2 = std::make_shared<Opm::Well::WellInjectionProperties>(well.getInjectionProperties());
injProps2->reservoirInjectionRate = 100;
injProps2->reservoirInjectionRate.update(100);
injProps2->addInjectionControl(Opm::Well::InjectorCMode::RESV);
well.updateInjection(injProps2);
BOOST_CHECK( well.getInjectionProperties().hasInjectionControl( Opm::Well::InjectorCMode::RESV ));
auto injProps3 = std::make_shared<Opm::Well::WellInjectionProperties>(well.getInjectionProperties());
injProps3->BHPTarget = 100;
injProps3->BHPTarget.update(100);
injProps3->addInjectionControl(Opm::Well::InjectorCMode::BHP);
injProps3->THPTarget = 100;
injProps3->THPTarget.update(100);
injProps3->addInjectionControl(Opm::Well::InjectorCMode::THP);
well.updateInjection(injProps3);