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);
+}