diff --git a/MaterialLib/CMakeLists.txt b/MaterialLib/CMakeLists.txt index 1ab7d62edc00189ca5d04bb98d1d9cc2f5d80543..168f5af3ff0e1880634d70ad192ae184de8b9e2d 100644 --- a/MaterialLib/CMakeLists.txt +++ b/MaterialLib/CMakeLists.txt @@ -39,9 +39,10 @@ append_source_files( ogs_add_library(MaterialLib GENERATE_EXPORT_HEADER ${SOURCES}) target_link_libraries( - MaterialLib PUBLIC BaseLib Eigen3::Eigen MaterialLib_SolidModels - MaterialLib_FractureModels PRIVATE MathLib MeshLib - ParameterLib exprtk + MaterialLib + PUBLIC BaseLib Eigen3::Eigen MaterialLib_SolidModels + MaterialLib_FractureModels + PRIVATE MathLib MeshLib ParameterLib exprtk Boost::mp11 ) target_precompile_headers(MaterialLib PRIVATE [["BaseLib/Error.h"]] diff --git a/MaterialLib/MPL/Properties/ThermalConductivity/CreateSaturationWeightedThermalConductivity.cpp b/MaterialLib/MPL/Properties/ThermalConductivity/CreateSaturationWeightedThermalConductivity.cpp index ec9cc06469d4a9e15360a3d85e34b661d636ae1a..23f2045fd6f940a67672703655b8bbcc8f2fbce3 100644 --- a/MaterialLib/MPL/Properties/ThermalConductivity/CreateSaturationWeightedThermalConductivity.cpp +++ b/MaterialLib/MPL/Properties/ThermalConductivity/CreateSaturationWeightedThermalConductivity.cpp @@ -11,6 +11,7 @@ #include "CreateSaturationWeightedThermalConductivity.h" +#include <boost/mp11.hpp> #include <string> #include "BaseLib/Algorithm.h" @@ -21,6 +22,26 @@ #include "ParameterLib/Utils.h" #include "SaturationWeightedThermalConductivity.h" +namespace +{ +template <MaterialPropertyLib::MeanType MeanType, int Dim> +std::unique_ptr<MaterialPropertyLib::Property> +createSaturationWeightedThermalConductivity( + std::string name, + ParameterLib::Parameter<double> const& dry_thermal_conductivity, + ParameterLib::Parameter<double> const& wet_thermal_conductivity, + ParameterLib::CoordinateSystem const* const local_coordinate_system) +{ + return std::make_unique< + MaterialPropertyLib::SaturationWeightedThermalConductivity<MeanType, + Dim>>( + std::move(name), + dry_thermal_conductivity, + wet_thermal_conductivity, + local_coordinate_system); +} +} // namespace + namespace MaterialPropertyLib { std::unique_ptr<Property> createSaturationWeightedThermalConductivity( @@ -62,125 +83,57 @@ std::unique_ptr<Property> createSaturationWeightedThermalConductivity( mean_type_map, mean_type_str, "Specified mean type for the thermal conductivity could not be found."); - switch (geometry_dimension) + std::map< + std::pair<MeanType, int>, + std::unique_ptr<Property> (*)( + std::string /*name*/, + ParameterLib::Parameter<double> const& /*dry_thermal_conductivity*/, + ParameterLib::Parameter<double> const& /*wet_thermal_conductivity*/, + ParameterLib::CoordinateSystem const* const + /*local_coordinate_system*/)> + map_dim_and_mean_to_creator; + + // initialize the map { - case 1: - { - switch (mean_type) - { - case MeanType::ARITHMETIC_LINEAR: - { - return std::make_unique<SaturationWeightedThermalConductivity< - MeanType::ARITHMETIC_LINEAR, 1>>( - std::move(property_name), - dry_thermal_conductivity, - wet_thermal_conductivity, - local_coordinate_system); - } - case MeanType::ARITHMETIC_SQUAREROOT: - { - return std::make_unique<SaturationWeightedThermalConductivity< - MeanType::ARITHMETIC_SQUAREROOT, 1>>( - std::move(property_name), - dry_thermal_conductivity, - wet_thermal_conductivity, - local_coordinate_system); - } - case MeanType::GEOMETRIC: - { - return std::make_unique<SaturationWeightedThermalConductivity< - MeanType::GEOMETRIC, 1>>( - std::move(property_name), - dry_thermal_conductivity, - wet_thermal_conductivity, - local_coordinate_system); - } - default: - { - OGS_FATAL("The requested MeanType is not implemented."); - } - } - } - case 2: - { - switch (mean_type) - { - case MeanType::ARITHMETIC_LINEAR: - { - return std::make_unique<SaturationWeightedThermalConductivity< - MeanType::ARITHMETIC_LINEAR, 2>>( - std::move(property_name), - dry_thermal_conductivity, - wet_thermal_conductivity, - local_coordinate_system); - } - case MeanType::ARITHMETIC_SQUAREROOT: - { - return std::make_unique<SaturationWeightedThermalConductivity< - MeanType::ARITHMETIC_SQUAREROOT, 2>>( - std::move(property_name), - dry_thermal_conductivity, - wet_thermal_conductivity, - local_coordinate_system); - } - case MeanType::GEOMETRIC: - { - return std::make_unique<SaturationWeightedThermalConductivity< - MeanType::GEOMETRIC, 2>>( - std::move(property_name), - dry_thermal_conductivity, - wet_thermal_conductivity, - local_coordinate_system); - } - default: - { - OGS_FATAL("The requested MeanType is not implemented."); - } - } - - } - case 3: - { - switch (mean_type) + using namespace boost::mp11; + using Dims = mp_list<mp_int<1>, mp_int<2>, mp_int<3>>; + using Means = mp_list< + std::integral_constant<MeanType, MeanType::ARITHMETIC_LINEAR>, + std::integral_constant<MeanType, MeanType::ARITHMETIC_SQUAREROOT>, + std::integral_constant<MeanType, MeanType::GEOMETRIC>>; + using DimsAndMeanTypes = + mp_product<mp_list, Dims, + Means>; // Cartesian product of Dims and Means. + + mp_for_each<DimsAndMeanTypes>( + [&map_dim_and_mean_to_creator]<typename Dim, typename Mean>( + mp_list<Dim, Mean>) { - case MeanType::ARITHMETIC_LINEAR: - { - return std::make_unique<SaturationWeightedThermalConductivity< - MeanType::ARITHMETIC_LINEAR, 3>>( - std::move(property_name), - dry_thermal_conductivity, - wet_thermal_conductivity, - local_coordinate_system); - } - case MeanType::ARITHMETIC_SQUAREROOT: - { - return std::make_unique<SaturationWeightedThermalConductivity< - MeanType::ARITHMETIC_SQUAREROOT, 3>>( - std::move(property_name), - dry_thermal_conductivity, - wet_thermal_conductivity, - local_coordinate_system); - } - case MeanType::GEOMETRIC: - { - return std::make_unique<SaturationWeightedThermalConductivity< - MeanType::GEOMETRIC, 3>>( - std::move(property_name), - dry_thermal_conductivity, - wet_thermal_conductivity, - local_coordinate_system); - } - default: - { - OGS_FATAL("The requested MeanType is not implemented."); - } - } - } - default: - { - OGS_FATAL("Dimension doesn't exist."); - } + constexpr int dim = Dim::value; + constexpr MeanType mean_type = Mean::value; + + map_dim_and_mean_to_creator.emplace( + std::pair{mean_type, dim}, + &::createSaturationWeightedThermalConductivity<mean_type, + dim>); + }); + } + + auto const it = map_dim_and_mean_to_creator.find( + std::pair{mean_type, geometry_dimension}); + + if (it == map_dim_and_mean_to_creator.end()) + { + OGS_FATAL( + "Cannot create a SaturationWeightedThermalConductivity model for " + "dimension {} and mean type {}", + geometry_dimension, mean_type_str); } + auto* creator = it->second; + return creator(std::move(property_name), + dry_thermal_conductivity, + wet_thermal_conductivity, + local_coordinate_system); } } // namespace MaterialPropertyLib