diff --git a/opm/material/fluidsystems/blackoilpvt/GasPvtMultiplexer.cpp b/opm/material/fluidsystems/blackoilpvt/GasPvtMultiplexer.cpp index d48fc2e6c93..1ebbb1067d3 100644 --- a/opm/material/fluidsystems/blackoilpvt/GasPvtMultiplexer.cpp +++ b/opm/material/fluidsystems/blackoilpvt/GasPvtMultiplexer.cpp @@ -26,88 +26,51 @@ #include -namespace Opm { - -template -GasPvtMultiplexer:: -~GasPvtMultiplexer() +namespace Opm { - switch (gasPvtApproach_) { - case GasPvtApproach::DryGas: { - delete &getRealPvt(); - break; - } - case GasPvtApproach::DryHumidGas: { - delete &getRealPvt(); - break; - } - case GasPvtApproach::WetHumidGas: { - delete &getRealPvt(); - break; - } - case GasPvtApproach::WetGas: { - delete &getRealPvt(); - break; - } - case GasPvtApproach::ThermalGas: { - delete &getRealPvt(); - break; - } - case GasPvtApproach::Co2Gas: { - delete &getRealPvt(); - break; - } - case GasPvtApproach::H2Gas: { - delete &getRealPvt(); - break; - } - case GasPvtApproach::NoGas: - break; - } -} template -void GasPvtMultiplexer:: -initEnd() +void +GasPvtMultiplexer::initEnd() { OPM_GAS_PVT_MULTIPLEXER_CALL(pvtImpl.initEnd(), break); } template -unsigned GasPvtMultiplexer:: -numRegions() const +unsigned +GasPvtMultiplexer::numRegions() const { OPM_GAS_PVT_MULTIPLEXER_CALL(return pvtImpl.numRegions()); } template -void GasPvtMultiplexer:: -setVapPars(const Scalar par1, const Scalar par2) +void +GasPvtMultiplexer::setVapPars(const Scalar par1, const Scalar par2) { OPM_GAS_PVT_MULTIPLEXER_CALL(pvtImpl.setVapPars(par1, par2), break); } template -Scalar GasPvtMultiplexer:: -gasReferenceDensity(unsigned regionIdx) +Scalar +GasPvtMultiplexer::gasReferenceDensity(unsigned regionIdx) { OPM_GAS_PVT_MULTIPLEXER_CALL(return pvtImpl.gasReferenceDensity(regionIdx)); } template -Scalar GasPvtMultiplexer:: -hVap(unsigned regionIdx) const +Scalar +GasPvtMultiplexer::hVap(unsigned regionIdx) const { OPM_GAS_PVT_MULTIPLEXER_CALL(return pvtImpl.hVap(regionIdx)); } #if HAVE_ECL_INPUT template -void GasPvtMultiplexer:: -initFromState(const EclipseState& eclState, const Schedule& schedule) +void +GasPvtMultiplexer::initFromState(const EclipseState& eclState, const Schedule& schedule) { if (!eclState.runspec().phases().active(Phase::GAS)) return; @@ -118,8 +81,8 @@ initFromState(const EclipseState& eclState, const Schedule& schedule) setApproach(GasPvtApproach::H2Gas); else if (enableThermal && eclState.getSimulationConfig().isThermal()) setApproach(GasPvtApproach::ThermalGas); - else if (!eclState.getTableManager().getPvtgwTables().empty() && - !eclState.getTableManager().getPvtgTables().empty()) + else if (!eclState.getTableManager().getPvtgwTables().empty() + && !eclState.getTableManager().getPvtgTables().empty()) setApproach(GasPvtApproach::WetHumidGas); else if (!eclState.getTableManager().getPvtgTables().empty()) setApproach(GasPvtApproach::WetGas); @@ -133,37 +96,49 @@ initFromState(const EclipseState& eclState, const Schedule& schedule) } #endif +// Helper function to keep the switch case tidy when constructing different pvts template -void GasPvtMultiplexer:: +template +std::unique_ptr> +GasPvtMultiplexer::makeGasPvt() +{ + return UniqueVoidPtrWithDeleter( + new ConcreteGasPvt, + [this](void* ptr) { deleter(ptr); } + ); +} + +template +void GasPvtMultiplexer:: setApproach(GasPvtApproach gasPvtAppr) { switch (gasPvtAppr) { case GasPvtApproach::DryGas: - realGasPvt_ = new DryGasPvt; + realGasPvt_ = makeGasPvt>(); break; case GasPvtApproach::DryHumidGas: - realGasPvt_ = new DryHumidGasPvt; + realGasPvt_ = makeGasPvt>(); break; case GasPvtApproach::WetHumidGas: - realGasPvt_ = new WetHumidGasPvt; + realGasPvt_ = makeGasPvt>(); break; case GasPvtApproach::WetGas: - realGasPvt_ = new WetGasPvt; + realGasPvt_ = makeGasPvt>(); break; case GasPvtApproach::ThermalGas: - realGasPvt_ = new GasPvtThermal; + realGasPvt_ = makeGasPvt>(); break; case GasPvtApproach::Co2Gas: - realGasPvt_ = new Co2GasPvt; + realGasPvt_ = makeGasPvt>(); break; case GasPvtApproach::H2Gas: - realGasPvt_ = new H2GasPvt; + realGasPvt_ = makeGasPvt>(); break; case GasPvtApproach::NoGas: @@ -173,33 +148,44 @@ setApproach(GasPvtApproach gasPvtAppr) gasPvtApproach_ = gasPvtAppr; } +// Helper template to create copies of PVT objects template -GasPvtMultiplexer& -GasPvtMultiplexer:: -operator=(const GasPvtMultiplexer& data) +template +std::unique_ptr> +GasPvtMultiplexer:: +copyPvt(const std::unique_ptr>& sourcePvt) { + return UniqueVoidPtrWithDeleter( + new ConcretePvt(*static_cast(sourcePvt.get())), + [this](void* ptr) { deleter(ptr); } + ); +} + +template +GasPvtMultiplexer& +GasPvtMultiplexer::operator=(const GasPvtMultiplexer& data) { gasPvtApproach_ = data.gasPvtApproach_; switch (gasPvtApproach_) { case GasPvtApproach::DryGas: - realGasPvt_ = new DryGasPvt(*static_cast*>(data.realGasPvt_)); + realGasPvt_ = copyPvt>(data.realGasPvt_); break; case GasPvtApproach::DryHumidGas: - realGasPvt_ = new DryHumidGasPvt(*static_cast*>(data.realGasPvt_)); + realGasPvt_ = copyPvt>(data.realGasPvt_); break; case GasPvtApproach::WetHumidGas: - realGasPvt_ = new WetHumidGasPvt(*static_cast*>(data.realGasPvt_)); + realGasPvt_ = copyPvt>(data.realGasPvt_); break; case GasPvtApproach::WetGas: - realGasPvt_ = new WetGasPvt(*static_cast*>(data.realGasPvt_)); + realGasPvt_ = copyPvt>(data.realGasPvt_); break; case GasPvtApproach::ThermalGas: - realGasPvt_ = new GasPvtThermal(*static_cast*>(data.realGasPvt_)); + realGasPvt_ = copyPvt>(data.realGasPvt_); break; case GasPvtApproach::Co2Gas: - realGasPvt_ = new Co2GasPvt(*static_cast*>(data.realGasPvt_)); + realGasPvt_ = copyPvt>(data.realGasPvt_); break; -case GasPvtApproach::H2Gas: - realGasPvt_ = new H2GasPvt(*static_cast*>(data.realGasPvt_)); + case GasPvtApproach::H2Gas: + realGasPvt_ = copyPvt>(data.realGasPvt_); break; default: break; @@ -208,9 +194,46 @@ case GasPvtApproach::H2Gas: return *this; } -template class GasPvtMultiplexer; -template class GasPvtMultiplexer; -template class GasPvtMultiplexer; -template class GasPvtMultiplexer; +template +void GasPvtMultiplexer::deleter(void* ptr) +{ + switch (gasPvtApproach_) { + case GasPvtApproach::DryGas: { + delete static_cast*>(ptr); + break; + } + case GasPvtApproach::DryHumidGas: { + delete static_cast*>(ptr); + break; + } + case GasPvtApproach::WetHumidGas: { + delete static_cast*>(ptr); + break; + } + case GasPvtApproach::WetGas: { + delete static_cast*>(ptr); + break; + } + case GasPvtApproach::ThermalGas: { + delete static_cast*>(ptr); + break; + } + case GasPvtApproach::Co2Gas: { + delete static_cast*>(ptr); + break; + } + case GasPvtApproach::H2Gas: { + delete static_cast*>(ptr); + break; + } + case GasPvtApproach::NoGas: + break; + } +} + +template class GasPvtMultiplexer; +template class GasPvtMultiplexer; +template class GasPvtMultiplexer; +template class GasPvtMultiplexer; } // namespace Opm diff --git a/opm/material/fluidsystems/blackoilpvt/GasPvtMultiplexer.hpp b/opm/material/fluidsystems/blackoilpvt/GasPvtMultiplexer.hpp index 185376a2cd8..91afe397eae 100644 --- a/opm/material/fluidsystems/blackoilpvt/GasPvtMultiplexer.hpp +++ b/opm/material/fluidsystems/blackoilpvt/GasPvtMultiplexer.hpp @@ -35,6 +35,7 @@ #include #include +#include namespace Opm { #if HAVE_ECL_INPUT @@ -111,13 +112,13 @@ class GasPvtMultiplexer public: GasPvtMultiplexer() : gasPvtApproach_(GasPvtApproach::NoGas) - , realGasPvt_(nullptr) + , realGasPvt_(nullptr, [](void*){}) { } GasPvtMultiplexer(GasPvtApproach approach, void* realGasPvt) : gasPvtApproach_(approach) - , realGasPvt_(realGasPvt) + , realGasPvt_(realGasPvt, [this](void* ptr){ deleter(ptr); }) { } GasPvtMultiplexer(const GasPvtMultiplexer& data) @@ -125,7 +126,7 @@ class GasPvtMultiplexer *this = data; } - ~GasPvtMultiplexer(); + ~GasPvtMultiplexer() = default; bool mixingEnergy() const { @@ -285,14 +286,14 @@ class GasPvtMultiplexer typename std::enable_if >::type& getRealPvt() { assert(gasPvtApproach() == approachV); - return *static_cast* >(realGasPvt_); + return *static_cast* >(realGasPvt_.get()); } template typename std::enable_if >::type& getRealPvt() const { assert(gasPvtApproach() == approachV); - return *static_cast* >(realGasPvt_); + return *static_cast* >(realGasPvt_.get()); } // get the parameter object for the dry humid gas case @@ -300,14 +301,14 @@ class GasPvtMultiplexer typename std::enable_if >::type& getRealPvt() { assert(gasPvtApproach() == approachV); - return *static_cast* >(realGasPvt_); + return *static_cast* >(realGasPvt_.get()); } template typename std::enable_if >::type& getRealPvt() const { assert(gasPvtApproach() == approachV); - return *static_cast* >(realGasPvt_); + return *static_cast* >(realGasPvt_.get()); } // get the parameter object for the wet humid gas case @@ -315,14 +316,14 @@ class GasPvtMultiplexer typename std::enable_if >::type& getRealPvt() { assert(gasPvtApproach() == approachV); - return *static_cast* >(realGasPvt_); + return *static_cast* >(realGasPvt_.get()); } template typename std::enable_if >::type& getRealPvt() const { assert(gasPvtApproach() == approachV); - return *static_cast* >(realGasPvt_); + return *static_cast* >(realGasPvt_.get()); } // get the parameter object for the wet gas case @@ -330,14 +331,14 @@ class GasPvtMultiplexer typename std::enable_if >::type& getRealPvt() { assert(gasPvtApproach() == approachV); - return *static_cast* >(realGasPvt_); + return *static_cast* >(realGasPvt_.get()); } template typename std::enable_if >::type& getRealPvt() const { assert(gasPvtApproach() == approachV); - return *static_cast* >(realGasPvt_); + return *static_cast* >(realGasPvt_.get()); } // get the parameter object for the thermal gas case @@ -345,51 +346,59 @@ class GasPvtMultiplexer typename std::enable_if >::type& getRealPvt() { assert(gasPvtApproach() == approachV); - return *static_cast* >(realGasPvt_); + return *static_cast* >(realGasPvt_.get()); } template typename std::enable_if >::type& getRealPvt() const { assert(gasPvtApproach() == approachV); - return *static_cast* >(realGasPvt_); + return *static_cast* >(realGasPvt_.get()); } template typename std::enable_if >::type& getRealPvt() { assert(gasPvtApproach() == approachV); - return *static_cast* >(realGasPvt_); + return *static_cast* >(realGasPvt_.get()); } template typename std::enable_if >::type& getRealPvt() const { assert(gasPvtApproach() == approachV); - return *static_cast* >(realGasPvt_); + return *static_cast* >(realGasPvt_.get()); } template typename std::enable_if >::type& getRealPvt() { assert(gasPvtApproach() == approachV); - return *static_cast* >(realGasPvt_); + return *static_cast* >(realGasPvt_.get()); } template typename std::enable_if >::type& getRealPvt() const { assert(gasPvtApproach() == approachV); - return *static_cast* >(realGasPvt_); + return *static_cast* >(realGasPvt_.get()); } - const void* realGasPvt() const { return realGasPvt_; } + const void* realGasPvt() const { return realGasPvt_.get(); } GasPvtMultiplexer& operator=(const GasPvtMultiplexer& data); private: + using UniqueVoidPtrWithDeleter = std::unique_ptr>; + + template UniqueVoidPtrWithDeleter makeGasPvt(); + + template UniqueVoidPtrWithDeleter copyPvt(const UniqueVoidPtrWithDeleter&); + GasPvtApproach gasPvtApproach_{GasPvtApproach::NoGas}; - void* realGasPvt_{nullptr}; + UniqueVoidPtrWithDeleter realGasPvt_; + + void deleter(void* ptr); }; } // namespace Opm