diff --git a/CMakeLists_files.cmake b/CMakeLists_files.cmake index eaf4773cca0..de38acc4b25 100644 --- a/CMakeLists_files.cmake +++ b/CMakeLists_files.cmake @@ -378,6 +378,7 @@ list (APPEND TEST_SOURCE_FILES tests/test_tabulation.cpp tests/test_threecomponents_ptflash.cpp tests/test_uniformtablelinear.cpp + tests/test_Visitor.cpp ) if(ENABLE_ECL_INPUT) list(APPEND TEST_SOURCE_FILES @@ -662,6 +663,7 @@ list( APPEND PUBLIC_HEADER_FILES opm/common/utility/FileSystem.hpp opm/common/utility/OpmInputError.hpp opm/common/utility/Serializer.hpp + opm/common/utility/Visitor.hpp opm/common/utility/numeric/cmp.hpp opm/common/utility/platform_dependent/disable_warnings.h opm/common/utility/platform_dependent/reenable_warnings.h @@ -877,6 +879,7 @@ list( APPEND PUBLIC_HEADER_FILES opm/material/thermal/FluidThermalConductionLawParams.hpp opm/material/thermal/EclHeatcrLawParams.hpp opm/material/thermal/NullThermalConductionLaw.hpp + opm/material/thermal/NullThermalConductionLawParams.hpp opm/material/thermal/EclSolidEnergyLawMultiplexer.hpp opm/material/thermal/EclThermalConductionLawMultiplexerParams.hpp opm/material/thermal/EclThermalConductionLawMultiplexer.hpp diff --git a/opm/common/utility/Visitor.hpp b/opm/common/utility/Visitor.hpp new file mode 100644 index 00000000000..e28146ed815 --- /dev/null +++ b/opm/common/utility/Visitor.hpp @@ -0,0 +1,64 @@ +/* + This file is part of the Open Porous Media project (OPM). + + OPM is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + OPM is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OPM. If not, see . + + Consult the COPYING file in the top-level source directory of this + module for the precise wording of the license and the list of + copyright holders. +*/ + +#ifndef VISITOR_HPP +#define VISITOR_HPP + +#include +#include + +namespace Opm { + +//! \brief Helper struct for for generating visitor overload sets. +template +struct VisitorOverloadSet : Ts... +{ + using Ts::operator()...; +}; + +//! \brief Deduction guide for visitor overload sets. +template VisitorOverloadSet(Ts...) -> VisitorOverloadSet; + +//! \brief A functor for handling a monostate in a visitor overload set. +//! \details Throws an exception +template +struct MonoThrowHandler { + MonoThrowHandler(const std::string& message) + : message_(message) + {} + + void operator()(std::monostate&) + { + throw Exception(message_); + } + + void operator()(const std::monostate&) const + { + throw Exception(message_); + } + +private: + std::string message_; +}; + +} + +#endif diff --git a/opm/material/thermal/EclSolidEnergyLawMultiplexer.hpp b/opm/material/thermal/EclSolidEnergyLawMultiplexer.hpp index d8280793859..fafe87fc2c2 100644 --- a/opm/material/thermal/EclSolidEnergyLawMultiplexer.hpp +++ b/opm/material/thermal/EclSolidEnergyLawMultiplexer.hpp @@ -65,15 +65,15 @@ class EclSolidEnergyLawMultiplexer static Evaluation solidInternalEnergy(const Params& params, const FluidState& fluidState) { switch (params.solidEnergyApproach()) { - case Params::heatcrApproach: + case EclSolidEnergyApproach::Heatcr: // relevant ECL keywords: HEATCR, HEATCRT and STCOND - return HeatcrLaw::solidInternalEnergy(params.template getRealParams(), fluidState); + return HeatcrLaw::solidInternalEnergy(params.template getRealParams(), fluidState); - case Params::specrockApproach: + case EclSolidEnergyApproach::Specrock: // relevant ECL keyword: SPECROCK - return SpecrockLaw::solidInternalEnergy(params.template getRealParams(), fluidState); + return SpecrockLaw::solidInternalEnergy(params.template getRealParams(), fluidState); - case Params::nullApproach: + case EclSolidEnergyApproach::Null: // (no relevant ECL keyword) return NullLaw::solidInternalEnergy(0, fluidState); diff --git a/opm/material/thermal/EclSolidEnergyLawMultiplexerParams.hpp b/opm/material/thermal/EclSolidEnergyLawMultiplexerParams.hpp index 217bf7df773..e222eda61e5 100644 --- a/opm/material/thermal/EclSolidEnergyLawMultiplexerParams.hpp +++ b/opm/material/thermal/EclSolidEnergyLawMultiplexerParams.hpp @@ -38,6 +38,13 @@ namespace Opm { +enum class EclSolidEnergyApproach { + Undefined, + Heatcr, // keywords: HEATCR, HEATCRT, STCOND + Specrock, // keyword: SPECROCK + Null // (no keywords) +}; + /*! * \brief The default implementation of a parameter object for the * ECL thermal law. @@ -50,61 +57,54 @@ class EclSolidEnergyLawMultiplexerParams : public EnsureFinalized public: using Scalar = ScalarT; - enum SolidEnergyApproach { - undefinedApproach, - heatcrApproach, // keywords: HEATCR, HEATCRT, STCOND - specrockApproach, // keyword: SPECROCK - nullApproach, // (no keywords) - }; - using HeatcrLawParams = EclHeatcrLawParams; using SpecrockLawParams = EclSpecrockLawParams; EclSolidEnergyLawMultiplexerParams(const EclSolidEnergyLawMultiplexerParams&) = default; EclSolidEnergyLawMultiplexerParams() - { solidEnergyApproach_ = undefinedApproach; } + { solidEnergyApproach_ = EclSolidEnergyApproach::Undefined; } ~EclSolidEnergyLawMultiplexerParams() { destroy_(); } - void setSolidEnergyApproach(SolidEnergyApproach newApproach) + void setSolidEnergyApproach(EclSolidEnergyApproach newApproach) { destroy_(); solidEnergyApproach_ = newApproach; switch (solidEnergyApproach()) { - case undefinedApproach: + case EclSolidEnergyApproach::Undefined: throw std::logic_error("Cannot set the approach for solid energy storage to 'undefined'!"); - case heatcrApproach: + case EclSolidEnergyApproach::Heatcr: realParams_ = new HeatcrLawParams; break; - case specrockApproach: + case EclSolidEnergyApproach::Specrock: realParams_ = new SpecrockLawParams; break; - case nullApproach: + case EclSolidEnergyApproach::Null: realParams_ = nullptr; break; } } - SolidEnergyApproach solidEnergyApproach() const + EclSolidEnergyApproach solidEnergyApproach() const { return solidEnergyApproach_; } // get the parameter object for the HEATCR case - template - typename std::enable_if::type& + template + typename std::enable_if::type& getRealParams() { assert(solidEnergyApproach() == approachV); return *static_cast(realParams_); } - template - typename std::enable_if::type& + template + typename std::enable_if::type& getRealParams() const { assert(solidEnergyApproach() == approachV); @@ -112,16 +112,16 @@ class EclSolidEnergyLawMultiplexerParams : public EnsureFinalized } // get the parameter object for the SPECROCK case - template - typename std::enable_if::type& + template + typename std::enable_if::type& getRealParams() { assert(solidEnergyApproach() == approachV); return *static_cast(realParams_); } - template - typename std::enable_if::type& + template + typename std::enable_if::type& getRealParams() const { assert(solidEnergyApproach() == approachV); @@ -132,25 +132,25 @@ class EclSolidEnergyLawMultiplexerParams : public EnsureFinalized void destroy_() { switch (solidEnergyApproach()) { - case undefinedApproach: + case EclSolidEnergyApproach::Undefined: break; - case heatcrApproach: + case EclSolidEnergyApproach::Heatcr: delete static_cast(realParams_); break; - case specrockApproach: + case EclSolidEnergyApproach::Specrock: delete static_cast(realParams_); break; - case nullApproach: + case EclSolidEnergyApproach::Null: break; } - solidEnergyApproach_ = undefinedApproach; + solidEnergyApproach_ = EclSolidEnergyApproach::Undefined; } - SolidEnergyApproach solidEnergyApproach_; + EclSolidEnergyApproach solidEnergyApproach_; ParamPointerType realParams_; }; diff --git a/opm/material/thermal/EclThcLawParams.hpp b/opm/material/thermal/EclThcLawParams.hpp index bfce0ef70b3..d622d8091c7 100644 --- a/opm/material/thermal/EclThcLawParams.hpp +++ b/opm/material/thermal/EclThcLawParams.hpp @@ -31,6 +31,8 @@ namespace Opm { +template class EclThcLaw; + /*! * \brief The default implementation of a parameter object for the * thermal conduction law based on the THC* keywords from ECL. @@ -40,11 +42,7 @@ class EclThcLawParams : public EnsureFinalized { public: using Scalar = ScalarT; - - EclThcLawParams(const EclThcLawParams&) = default; - - EclThcLawParams() - { } + using Law = EclThcLaw>; /*! * \brief Set the porosity @@ -107,11 +105,11 @@ class EclThcLawParams : public EnsureFinalized { EnsureFinalized::check(); return thcwater_; } private: - Scalar porosity_; - Scalar thcrock_; - Scalar thcoil_; - Scalar thcgas_; - Scalar thcwater_; + Scalar porosity_{}; + Scalar thcrock_{}; + Scalar thcoil_{}; + Scalar thcgas_{}; + Scalar thcwater_{}; }; } // namespace Opm diff --git a/opm/material/thermal/EclThconrLaw.hpp b/opm/material/thermal/EclThconrLaw.hpp index 3ea5bca132a..5a348e6e471 100644 --- a/opm/material/thermal/EclThconrLaw.hpp +++ b/opm/material/thermal/EclThconrLaw.hpp @@ -40,7 +40,7 @@ namespace Opm */ template > + class ParamsT = EclThconrLawParams> class EclThconrLaw { public: diff --git a/opm/material/thermal/EclThconrLawParams.hpp b/opm/material/thermal/EclThconrLawParams.hpp index 93e66a1c962..2b46a657708 100644 --- a/opm/material/thermal/EclThconrLawParams.hpp +++ b/opm/material/thermal/EclThconrLawParams.hpp @@ -31,20 +31,18 @@ namespace Opm { +template class EclThconrLaw; + /*! * \brief The default implementation of a parameter object for the * thermal conduction law based on the THCONR keyword from ECL. */ -template +template class EclThconrLawParams : public EnsureFinalized { public: using Scalar = ScalarT; - - EclThconrLawParams(const EclThconrLawParams&) = default; - - EclThconrLawParams() - { } + using Law = EclThconrLaw>; /*! * \brief Set the total thermal conductivity [J/m^2 / (K/m)] of at Sg = 0 @@ -71,8 +69,8 @@ class EclThconrLawParams : public EnsureFinalized { EnsureFinalized::check(); return dTotalThermalConductivity_dSg_; } private: - Scalar referenceTotalThermalConductivity_; - Scalar dTotalThermalConductivity_dSg_; + Scalar referenceTotalThermalConductivity_{}; + Scalar dTotalThermalConductivity_dSg_{}; }; } // namespace Opm diff --git a/opm/material/thermal/EclThermalConductionLawMultiplexer.hpp b/opm/material/thermal/EclThermalConductionLawMultiplexer.hpp index 8e2b0ccc71b..6a009573e0f 100644 --- a/opm/material/thermal/EclThermalConductionLawMultiplexer.hpp +++ b/opm/material/thermal/EclThermalConductionLawMultiplexer.hpp @@ -27,14 +27,20 @@ #ifndef OPM_ECL_THERMAL_CONDUCTION_LAW_MULTIPLEXER_HPP #define OPM_ECL_THERMAL_CONDUCTION_LAW_MULTIPLEXER_HPP -#include "EclThermalConductionLawMultiplexerParams.hpp" +#include -#include "EclThconrLaw.hpp" -#include "EclThcLaw.hpp" -#include "NullThermalConductionLaw.hpp" +#include + +#include +#include +#include #include -#include + +namespace { +template +using remove_cvr_t = std::remove_cv_t>; +} namespace Opm { @@ -45,7 +51,7 @@ namespace Opm */ template > + class ParamsT = EclThermalConductionLawMultiplexerParams> class EclThermalConductionLawMultiplexer { enum { numPhases = FluidSystem::numPhases }; @@ -65,22 +71,17 @@ class EclThermalConductionLawMultiplexer static Evaluation thermalConductivity(const Params& params, const FluidState& fluidState) { - switch (params.thermalConductionApproach()) { - case Params::thconrApproach: - // relevant ECL keywords: THCONR and THCONSF - return ThconrLaw::thermalConductivity(params.template getRealParams(), fluidState); - - case Params::thcApproach: - // relevant ECL keywords: THCROCK, THCOIL, THCGAS and THCWATER - return ThcLaw::thermalConductivity(params.template getRealParams(), fluidState); - - case Params::nullApproach: - // relevant ECL keywords: none or none recognized - return NullLaw::thermalConductivity(0, fluidState); - - default: - throw std::logic_error("Invalid thermal conductivity approach: "+std::to_string(int(params.thermalConductionApproach()))); - } + Evaluation result; + params.visit(VisitorOverloadSet{[&](const auto& prm) + { + using Law = typename remove_cvr_t::Law; + result = Law::thermalConductivity(prm, fluidState); + }, + [](const std::monostate&) + { + throw std::runtime_error("Undefined thermal conduction approach."); + }}); + return result; } }; diff --git a/opm/material/thermal/EclThermalConductionLawMultiplexerParams.hpp b/opm/material/thermal/EclThermalConductionLawMultiplexerParams.hpp index 7cc360368e2..85acc10a2b4 100644 --- a/opm/material/thermal/EclThermalConductionLawMultiplexerParams.hpp +++ b/opm/material/thermal/EclThermalConductionLawMultiplexerParams.hpp @@ -27,8 +27,11 @@ #ifndef OPM_ECL_THERMAL_CONDUCTION_LAW_MULTIPLEXER_PARAMS_HPP #define OPM_ECL_THERMAL_CONDUCTION_LAW_MULTIPLEXER_PARAMS_HPP -#include "EclThconrLawParams.hpp" -#include "EclThcLawParams.hpp" +#include + +#include +#include +#include #include @@ -37,120 +40,69 @@ namespace Opm { +enum class EclThermalConductionApproach { + Undefined, + Thconr, // keywords: THCONR, THCONSF + Thc, // keywords: THCROCK, THCOIL, THCGAS, THCWATER + Null, // (no keywords) +}; + /*! * \brief The default implementation of a parameter object for the * ECL thermal law. */ -template +template class EclThermalConductionLawMultiplexerParams : public EnsureFinalized { - using ParamPointerType = void*; - public: using Scalar = ScalarT; - enum ThermalConductionApproach { - undefinedApproach, - thconrApproach, // keywords: THCONR, THCONSF - thcApproach, // keywords: THCROCK, THCOIL, THCGAS, THCWATER - nullApproach, // (no keywords) - }; - - using ThconrLawParams = EclThconrLawParams; + using ThconrLawParams = EclThconrLawParams; using ThcLawParams = EclThcLawParams; + using NullParams = NullThermalConductionLawParams; - EclThermalConductionLawMultiplexerParams(const EclThermalConductionLawMultiplexerParams&) = default; - - EclThermalConductionLawMultiplexerParams() - { thermalConductionApproach_ = undefinedApproach; } - - ~EclThermalConductionLawMultiplexerParams() - { destroy_(); } - - void setThermalConductionApproach(ThermalConductionApproach newApproach) + void setThermalConductionApproach(EclThermalConductionApproach newApproach) { - destroy_(); - thermalConductionApproach_ = newApproach; switch (thermalConductionApproach()) { - case undefinedApproach: - throw std::logic_error("Cannot set the approach for thermal conduction to 'undefined'!"); - - case thconrApproach: - realParams_ = new ThconrLawParams; + case EclThermalConductionApproach::Thconr: + realParams_ = ThconrLawParams{}; break; - case thcApproach: - realParams_ = new ThcLawParams; + case EclThermalConductionApproach::Thc: + realParams_ = ThcLawParams{}; break; - case nullApproach: - realParams_ = nullptr; + case EclThermalConductionApproach::Null: + realParams_ = NullParams{}; break; + + case EclThermalConductionApproach::Undefined: + throw std::logic_error("Cannot set the approach for thermal conduction to 'undefined'!"); } } - ThermalConductionApproach thermalConductionApproach() const + EclThermalConductionApproach thermalConductionApproach() const { return thermalConductionApproach_; } - // get the parameter object for the THCONR case - template - typename std::enable_if::type& - getRealParams() - { - assert(thermalConductionApproach() == approachV); - return *static_cast(realParams_); - } - - template - typename std::enable_if::type& - getRealParams() const + template + void visit1(Function f) { - assert(thermalConductionApproach() == approachV); - return *static_cast(realParams_); + std::visit(VisitorOverloadSet{f, [](auto&){}}, realParams_); } - // get the parameter object for the THC* case - template - typename std::enable_if::type& - getRealParams() + template + void visit(VisitorSet f) const { - assert(thermalConductionApproach() == approachV); - return *static_cast(realParams_); - } - - template - typename std::enable_if::type& - getRealParams() const - { - assert(thermalConductionApproach() == approachV); - return *static_cast(realParams_); + std::visit(f, realParams_); } private: - void destroy_() - { - switch (thermalConductionApproach()) { - case undefinedApproach: - break; - - case thconrApproach: - delete static_cast(realParams_); - break; - - case thcApproach: - delete static_cast(realParams_); - break; - - case nullApproach: - break; - } - - thermalConductionApproach_ = undefinedApproach; - } - - ThermalConductionApproach thermalConductionApproach_; - ParamPointerType realParams_; + EclThermalConductionApproach thermalConductionApproach_ = EclThermalConductionApproach::Undefined; + std::variant realParams_; }; } // namespace Opm diff --git a/opm/material/thermal/EclThermalLawManager.hpp b/opm/material/thermal/EclThermalLawManager.hpp index 4d5f4199ac3..cf11bae3839 100644 --- a/opm/material/thermal/EclThermalLawManager.hpp +++ b/opm/material/thermal/EclThermalLawManager.hpp @@ -63,11 +63,13 @@ class EclThermalLawManager using ThermalConductionLaw = EclThermalConductionLawMultiplexer; using ThermalConductionLawParams = typename ThermalConductionLaw::Params; + using ThconrLawParams = typename ThermalConductionLawParams::ThconrLawParams; + using ThcLawParams = typename ThermalConductionLawParams::ThcLawParams; EclThermalLawManager() { - solidEnergyApproach_ = SolidEnergyLawParams::undefinedApproach; - thermalConductivityApproach_ = ThermalConductionLawParams::undefinedApproach; + solidEnergyApproach_ = EclSolidEnergyApproach::Undefined; + thermalConductivityApproach_ = EclThermalConductionApproach::Undefined; } void initParamsForElements(const EclipseState& eclState, size_t numElems) @@ -96,11 +98,11 @@ class EclThermalLawManager const SolidEnergyLawParams& solidEnergyLawParams(unsigned elemIdx) const { switch (solidEnergyApproach_) { - case SolidEnergyLawParams::heatcrApproach: + case EclSolidEnergyApproach::Heatcr: assert(elemIdx < solidEnergyLawParams_.size()); return solidEnergyLawParams_[elemIdx]; - case SolidEnergyLawParams::specrockApproach: + case EclSolidEnergyApproach::Specrock: { assert(elemIdx < elemToSatnumIdx_.size()); unsigned satnumIdx = elemToSatnumIdx_[elemIdx]; @@ -108,7 +110,7 @@ class EclThermalLawManager return solidEnergyLawParams_[satnumIdx]; } - case SolidEnergyLawParams::nullApproach: + case EclSolidEnergyApproach::Null: return solidEnergyLawParams_[0]; default: @@ -120,12 +122,12 @@ class EclThermalLawManager const ThermalConductionLawParams& thermalConductionLawParams(unsigned elemIdx) const { switch (thermalConductivityApproach_) { - case ThermalConductionLawParams::thconrApproach: - case ThermalConductionLawParams::thcApproach: + case EclThermalConductionApproach::Thconr: + case EclThermalConductionApproach::Thc: assert(elemIdx < thermalConductionLawParams_.size()); return thermalConductionLawParams_[elemIdx]; - case ThermalConductionLawParams::nullApproach: + case EclThermalConductionApproach::Null: return thermalConductionLawParams_[0]; default: @@ -141,7 +143,7 @@ class EclThermalLawManager void initHeatcr_(const EclipseState& eclState, size_t numElems) { - solidEnergyApproach_ = SolidEnergyLawParams::heatcrApproach; + solidEnergyApproach_ = EclSolidEnergyApproach::Heatcr; // actually the value of the reference temperature does not matter for energy // conservation. We set it anyway to faciliate comparisons with ECL HeatcrLawParams::setReferenceTemperature(FluidSystem::surfaceTemperature); @@ -152,9 +154,8 @@ class EclThermalLawManager solidEnergyLawParams_.resize(numElems); for (unsigned elemIdx = 0; elemIdx < numElems; ++elemIdx) { auto& elemParam = solidEnergyLawParams_[elemIdx]; - elemParam.setSolidEnergyApproach(SolidEnergyLawParams::heatcrApproach); - auto& heatcrElemParams = elemParam.template getRealParams(); - + elemParam.setSolidEnergyApproach(EclSolidEnergyApproach::Heatcr); + auto& heatcrElemParams = elemParam.template getRealParams(); heatcrElemParams.setReferenceRockHeatCapacity(heatcrData[elemIdx]); heatcrElemParams.setDRockHeatCapacity_dT(heatcrtData[elemIdx]); heatcrElemParams.finalize(); @@ -168,7 +169,7 @@ class EclThermalLawManager void initSpecrock_(const EclipseState& eclState, size_t numElems) { - solidEnergyApproach_ = SolidEnergyLawParams::specrockApproach; + solidEnergyApproach_ = EclSolidEnergyApproach::Specrock; // initialize the element index -> SATNUM index mapping const auto& fp = eclState.fieldProps(); @@ -188,9 +189,9 @@ class EclThermalLawManager auto& multiplexerParams = solidEnergyLawParams_[satnumIdx]; - multiplexerParams.setSolidEnergyApproach(SolidEnergyLawParams::specrockApproach); + multiplexerParams.setSolidEnergyApproach(EclSolidEnergyApproach::Specrock); - auto& specrockParams = multiplexerParams.template getRealParams(); + auto& specrockParams = multiplexerParams.template getRealParams(); const auto& temperatureColumn = specrockTable.getColumn("TEMPERATURE"); const auto& cvRockColumn = specrockTable.getColumn("CV_ROCK"); specrockParams.setHeatCapacities(temperatureColumn, cvRockColumn); @@ -205,7 +206,7 @@ class EclThermalLawManager */ void initNullRockEnergy_() { - solidEnergyApproach_ = SolidEnergyLawParams::nullApproach; + solidEnergyApproach_ = EclSolidEnergyApproach::Null; solidEnergyLawParams_.resize(1); solidEnergyLawParams_[0].finalize(); @@ -217,7 +218,7 @@ class EclThermalLawManager void initThconr_(const EclipseState& eclState, size_t numElems) { - thermalConductivityApproach_ = ThermalConductionLawParams::thconrApproach; + thermalConductivityApproach_ = EclThermalConductionApproach::Thconr; const auto& fp = eclState.fieldProps(); std::vector thconrData; @@ -231,15 +232,15 @@ class EclThermalLawManager thermalConductionLawParams_.resize(numElems); for (unsigned elemIdx = 0; elemIdx < numElems; ++elemIdx) { auto& elemParams = thermalConductionLawParams_[elemIdx]; - elemParams.setThermalConductionApproach(ThermalConductionLawParams::thconrApproach); - auto& thconrElemParams = elemParams.template getRealParams(); - - double thconr = thconrData.empty() ? 0.0 : thconrData[elemIdx]; - double thconsf = thconsfData.empty() ? 0.0 : thconsfData[elemIdx]; - thconrElemParams.setReferenceTotalThermalConductivity(thconr); - thconrElemParams.setDTotalThermalConductivity_dSg(thconsf); - - thconrElemParams.finalize(); + elemParams.setThermalConductionApproach(EclThermalConductionApproach::Thconr); + elemParams.visit1([&](ThconrLawParams& thconrElemParams) + { + double thconr = thconrData.empty() ? 0.0 : thconrData[elemIdx]; + double thconsf = thconsfData.empty() ? 0.0 : thconsfData[elemIdx]; + thconrElemParams.setReferenceTotalThermalConductivity(thconr); + thconrElemParams.setDTotalThermalConductivity_dSg(thconsf); + thconrElemParams.finalize(); + }); elemParams.finalize(); } } @@ -250,7 +251,7 @@ class EclThermalLawManager void initThc_(const EclipseState& eclState, size_t numElems) { - thermalConductivityApproach_ = ThermalConductionLawParams::thcApproach; + thermalConductivityApproach_ = EclThermalConductionApproach::Thc; const auto& fp = eclState.fieldProps(); std::vector thcrockData; @@ -275,20 +276,20 @@ class EclThermalLawManager thermalConductionLawParams_.resize(numElems); for (unsigned elemIdx = 0; elemIdx < numElems; ++elemIdx) { auto& elemParams = thermalConductionLawParams_[elemIdx]; - elemParams.setThermalConductionApproach(ThermalConductionLawParams::thcApproach); - auto& thcElemParams = elemParams.template getRealParams(); - - thcElemParams.setPorosity(poroData[elemIdx]); - double thcrock = thcrockData.empty() ? 0.0 : thcrockData[elemIdx]; - double thcoil = thcoilData.empty() ? 0.0 : thcoilData[elemIdx]; - double thcgas = thcgasData.empty() ? 0.0 : thcgasData[elemIdx]; - double thcwater = thcwaterData.empty() ? 0.0 : thcwaterData[elemIdx]; - thcElemParams.setThcrock(thcrock); - thcElemParams.setThcoil(thcoil); - thcElemParams.setThcgas(thcgas); - thcElemParams.setThcwater(thcwater); - - thcElemParams.finalize(); + elemParams.setThermalConductionApproach(EclThermalConductionApproach::Thc); + elemParams.visit1([&](ThcLawParams& thcElemParams) + { + thcElemParams.setPorosity(poroData[elemIdx]); + double thcrock = thcrockData.empty() ? 0.0 : thcrockData[elemIdx]; + double thcoil = thcoilData.empty() ? 0.0 : thcoilData[elemIdx]; + double thcgas = thcgasData.empty() ? 0.0 : thcgasData[elemIdx]; + double thcwater = thcwaterData.empty() ? 0.0 : thcwaterData[elemIdx]; + thcElemParams.setThcrock(thcrock); + thcElemParams.setThcoil(thcoil); + thcElemParams.setThcgas(thcgas); + thcElemParams.setThcwater(thcwater); + thcElemParams.finalize(); + }); elemParams.finalize(); } } @@ -298,15 +299,15 @@ class EclThermalLawManager */ void initNullCond_() { - thermalConductivityApproach_ = ThermalConductionLawParams::nullApproach; + thermalConductivityApproach_ = EclThermalConductionApproach::Null; thermalConductionLawParams_.resize(1); thermalConductionLawParams_[0].finalize(); } private: - typename ThermalConductionLawParams::ThermalConductionApproach thermalConductivityApproach_; - typename SolidEnergyLawParams::SolidEnergyApproach solidEnergyApproach_; + EclThermalConductionApproach thermalConductivityApproach_; + EclSolidEnergyApproach solidEnergyApproach_; std::vector elemToSatnumIdx_; diff --git a/opm/material/thermal/NullThermalConductionLaw.hpp b/opm/material/thermal/NullThermalConductionLaw.hpp index add8a436640..5a0d92874bc 100644 --- a/opm/material/thermal/NullThermalConductionLaw.hpp +++ b/opm/material/thermal/NullThermalConductionLaw.hpp @@ -27,6 +27,8 @@ #ifndef OPM_NULL_THERMAL_CONDUCTION_LAW_HPP #define OPM_NULL_THERMAL_CONDUCTION_LAW_HPP +#include + namespace Opm { /*! @@ -41,7 +43,7 @@ template class NullThermalConductionLaw { public: - using Params = int; + using Params = NullThermalConductionLawParams; using Scalar = ScalarT; /*! diff --git a/opm/material/thermal/NullThermalConductionLawParams.hpp b/opm/material/thermal/NullThermalConductionLawParams.hpp new file mode 100644 index 00000000000..d9fc449febe --- /dev/null +++ b/opm/material/thermal/NullThermalConductionLawParams.hpp @@ -0,0 +1,46 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/* + This file is part of the Open Porous Media project (OPM). + + OPM is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + OPM is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OPM. If not, see . + + Consult the COPYING file in the top-level source directory of this + module for the precise wording of the license and the list of + copyright holders. +*/ +/*! + * \file + * \copydoc Opm::EclThconrLawParams + */ +#ifndef OPM_NULL_THERMAL_CONDUCTION_LAW_PARAMS_HPP +#define OPM_NULL_THERMAL_CONDUCTION_LAW_PARAMS_HPP + +namespace Opm { + +template class NullThermalConductionLaw; + +/*! + * \brief Dummy parameter class for the null thermal conduction law. + */ +template +class NullThermalConductionLawParams +{ +public: + using Law = NullThermalConductionLaw; +}; + +} // namespace Opm + +#endif diff --git a/tests/test_Visitor.cpp b/tests/test_Visitor.cpp new file mode 100644 index 00000000000..a10c16f8a0a --- /dev/null +++ b/tests/test_Visitor.cpp @@ -0,0 +1,92 @@ +/* + This file is part of the Open Porous Media project (OPM). + + OPM is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OPM is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OPM. If not, see . + */ + +#include + +#define BOOST_TEST_MODULE VISITOR_TESTS +#include + +#include + +#include +#include + +namespace { + +struct TestA { + void testThrow() + { + throw std::runtime_error("A"); + } + + char returnData() + { + return 'A'; + } +}; + +struct TestB { + void testThrow() + { + throw std::range_error("B"); + } + + char returnData() + { + return 'B'; + } +}; + +} + +using Variant = std::variant; + +// Test overload set visitor on a simple list of classes +BOOST_AUTO_TEST_CASE(VariantReturn) +{ + Variant v{}; + char result = '\0'; + Opm::MonoThrowHandler mh{"Mono state"}; + auto rD = [&result](auto& param) + { + result = param.returnData(); + }; + BOOST_CHECK_THROW(std::visit(Opm::VisitorOverloadSet{mh, rD}, v), std::logic_error); + BOOST_CHECK(result == '\0'); + v = TestA{}; + BOOST_CHECK_NO_THROW(std::visit(Opm::VisitorOverloadSet{mh, rD}, v)); + BOOST_CHECK(result == 'A'); + v = TestB{}; + BOOST_CHECK_NO_THROW(std::visit(Opm::VisitorOverloadSet{mh, rD}, v)); + BOOST_CHECK(result == 'B'); +} + +// Test that overload set visitor throws expected exceptions +BOOST_AUTO_TEST_CASE(VariantThrow) +{ + Variant v{}; + Opm::MonoThrowHandler mh{"Mono state"}; + auto rD = [](auto& param) + { + param.testThrow(); + }; + BOOST_CHECK_THROW(std::visit(Opm::VisitorOverloadSet{mh, rD}, v), std::logic_error); + v = TestA{}; + BOOST_CHECK_THROW(std::visit(Opm::VisitorOverloadSet{mh, rD}, v), std::runtime_error); + v = TestB{}; + BOOST_CHECK_THROW(std::visit(Opm::VisitorOverloadSet{mh, rD}, v), std::range_error); +}