Commit a8de229c authored by Kilian Weishaupt's avatar Kilian Weishaupt Committed by Dennis Gläser
Browse files

[componentes][base] Throw "not implemented" error during compile time

parent 3b8cfef0
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*****************************************************************************
* See the file COPYING for full copying permissions. *
* *
* This program 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. *
* *
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>. *
*****************************************************************************/
/*!
* \file
* \ingroup Common
* \ingroup TypeTraits
*/
#ifndef DUMUX_TYPE_TRAITS_HH
#define DUMUX_TYPE_TRAITS_HH
#include <type_traits>
namespace Dumux
{
/*!
* \brief template which always yields a false value
* \tparam T Some type.
*/
template<typename T>
struct AlwaysFalse : public std::false_type {};
}
#endif
......@@ -34,6 +34,8 @@
#include <dune/common/exceptions.hh>
#include <dune/common/stdstreams.hh>
#include <dumux/common/typetraits/typetraits.hh>
namespace Dumux {
namespace Components {
......@@ -63,38 +65,62 @@ public:
* \brief A human readable name for the component.
* \note Mandatory for all components
*/
template<class C = Implementation>
static std::string name()
{ return Implementation::name(); }
{
static_assert(AlwaysFalse<C>::value, "Mandatory function not implemented: name()");
DUNE_THROW(Dune::NotImplemented, "name()");
}
/*!
* \brief The molar mass in \f$\mathrm{[kg/mol]}\f$ of the component.
*/
template<class C = Implementation>
static Scalar molarMass()
{ DUNE_THROW(Dune::NotImplemented, "Component::molarMass()"); }
{
static_assert(AlwaysFalse<C>::value, "Mandatory function not implemented: molarMass()");
DUNE_THROW(Dune::NotImplemented, "molarMass()");
}
/*!
* \brief Returns the critical temperature in \f$\mathrm{[K]}\f$ of the component.
*/
template<class C = Implementation>
static Scalar criticalTemperature()
{ DUNE_THROW(Dune::NotImplemented, "Component::criticalTemperature()"); }
{
static_assert(AlwaysFalse<C>::value, "Mandatory function not implemented: criticalTemperature()");
DUNE_THROW(Dune::NotImplemented, "criticalTemperature()");
}
/*!
* \brief Returns the critical pressure in \f$\mathrm{[Pa]}\f$ of the component.
*/
template<class C = Implementation>
static Scalar criticalPressure()
{ DUNE_THROW(Dune::NotImplemented, "Component::criticalPressure()"); }
{
static_assert(AlwaysFalse<C>::value, "Mandatory function not implemented: criticalPressure()");
DUNE_THROW(Dune::NotImplemented, "criticalPressure()");
}
/*!
* \brief Returns the temperature in \f$\mathrm{[K]}\f$ at the component's triple point.
*/
template<class C = Implementation>
static Scalar tripleTemperature()
{ DUNE_THROW(Dune::NotImplemented, "Component::tripleTemperature()"); }
{
static_assert(AlwaysFalse<C>::value, "Mandatory function not implemented: tripleTemperature()");
DUNE_THROW(Dune::NotImplemented, "tripleTemperature()");
}
/*!
* \brief Returns the pressure in \f$\mathrm{[Pa]}\f$ at the component's triple point.
*/
template<class C = Implementation>
static Scalar triplePressure()
{ DUNE_THROW(Dune::NotImplemented, "Component::triplePressure()"); }
{
static_assert(AlwaysFalse<C>::value, "Mandatory function not implemented: triplePressure()");
DUNE_THROW(Dune::NotImplemented, "triplePressure()");
}
/*!
* \brief The vapor pressure in \f$\mathrm{[Pa]}\f$ of the component at a given
......@@ -102,8 +128,12 @@ public:
*
* \param T temperature of the component in \f$\mathrm{[K]}\f$
*/
static Scalar vaporPressure(Scalar T)
{ DUNE_THROW(Dune::NotImplemented, "Component::vaporPressure()"); }
template<class C = Implementation>
static Scalar vaporPressure(Scalar t)
{
static_assert(AlwaysFalse<C>::value, "Mandatory function not implemented: vaporPressure(t)");
DUNE_THROW(Dune::NotImplemented, "vaporPressure(t)");
}
};
......
......@@ -49,6 +49,12 @@ public:
static std::string name()
{ return "benzene"; }
/*!
* \brief The molar mass in \f$\mathrm{[kg/mol]}\f$ of benzene
*/
static Scalar molarMass()
{ return 0.07811; }
/*!
* \brief The density of benzene steam at a given pressure and temperature \f$\mathrm{[kg/m^3]}\f$.
*
......
......@@ -27,6 +27,8 @@
#include <dune/common/exceptions.hh>
#include <dumux/common/typetraits/typetraits.hh>
namespace Dumux {
namespace Components {
......@@ -43,20 +45,32 @@ public:
/*!
* \brief Returns true if the gas phase is assumed to be compressible
*/
template<class C = Component>
static constexpr bool gasIsCompressible()
{ return Component::gasIsCompressible(); }
{
static_assert(AlwaysFalse<C>::value, "Mandatory function not implemented: gasIsCompressible()");
DUNE_THROW(Dune::NotImplemented, "gasIsCompressible()");
}
/*!
* \brief Returns true if the gas phase viscostiy is constant
*/
template<class C = Component>
static constexpr bool gasViscosityIsConstant()
{ return Component::gasViscosityIsConstant(); }
{
static_assert(AlwaysFalse<C>::value, "Mandatory function not implemented: gasViscosityIsConstant()");
DUNE_THROW(Dune::NotImplemented, "gasViscosityIsConstant()");
}
/*!
* \brief Returns true if the gas phase is assumed to be ideal
*/
template<class C = Component>
static constexpr bool gasIsIdeal()
{ return Component::gasIsCompressible(); }
{
static_assert(AlwaysFalse<C>::value, "Mandatory function not implemented: gasIsIdeal()");
DUNE_THROW(Dune::NotImplemented, "gasIsIdeal()");
}
/*!
* \brief The density in \f$\mathrm{[kg/m^3]}\f$ of the component at a given pressure in
......@@ -65,8 +79,12 @@ public:
* \param temperature temperature of component in \f$\mathrm{[K]}\f$
* \param pressure pressure of component in \f$\mathrm{[Pa]}\f$
*/
template<class C = Component>
static Scalar gasDensity(Scalar temperature, Scalar pressure)
{ DUNE_THROW(Dune::NotImplemented, "Component::gasDensity()"); }
{
static_assert(AlwaysFalse<C>::value, "Mandatory function not implemented: gasDensity(t,p)");
DUNE_THROW(Dune::NotImplemented, "gasDensity(t,p)");
}
/*!
* \brief Specific enthalpy \f$\mathrm{[J/kg]}\f$ of the pure component in gas.
......@@ -74,8 +92,12 @@ public:
* \param temperature temperature of component in \f$\mathrm{[K]}\f$
* \param pressure pressure of component in \f$\mathrm{[Pa]}\f$
*/
template<class C = Component>
static const Scalar gasEnthalpy(Scalar temperature, Scalar pressure)
{ DUNE_THROW(Dune::NotImplemented, "Component::gasEnthalpy()"); }
{
static_assert(AlwaysFalse<C>::value, "Mandatory function not implemented: gasEnthalpy(t,p)");
DUNE_THROW(Dune::NotImplemented, "gasEnthalpy(t,p)");
}
/*!
* \brief Specific internal energy \f$\mathrm{[J/kg]}\f$ of the pure component in gas.
......@@ -83,8 +105,12 @@ public:
* \param temperature temperature of component in \f$\mathrm{[K]}\f$
* \param pressure pressure of component in \f$\mathrm{[Pa]}\f$
*/
template<class C = Component>
static const Scalar gasInternalEnergy(Scalar temperature, Scalar pressure)
{ DUNE_THROW(Dune::NotImplemented, "Component::gasInternalEnergy()"); }
{
static_assert(AlwaysFalse<C>::value, "Mandatory function not implemented: gasInternalEnergy(t,p)");
DUNE_THROW(Dune::NotImplemented, "gasInternalEnergy(t,p)");
}
/*!
* \brief The dynamic viscosity \f$\mathrm{[Pa*s]}\f$ of the pure component at a given pressure in
......@@ -93,24 +119,36 @@ public:
* \param temperature temperature of component in \f$\mathrm{[K]}\f$
* \param pressure pressure of component in \f$\mathrm{[Pa]}\f$
*/
template<class C = Component>
static Scalar gasViscosity(Scalar temperature, Scalar pressure)
{ DUNE_THROW(Dune::NotImplemented, "Component::gasViscosity()"); }
{
static_assert(AlwaysFalse<C>::value, "Mandatory function not implemented: gasViscosity(t,p)");
DUNE_THROW(Dune::NotImplemented, "gasViscosity(t,p)");
}
/*!
* \brief Thermal conductivity of the component \f$\mathrm{[W/(m*K)]}\f$ as a gas.
* \param temperature temperature of component in \f$\mathrm{[K]}\f$
* \param pressure pressure of component in \f$\mathrm{[Pa]}\f$
*/
template<class C = Component>
static Scalar gasThermalConductivity(Scalar temperature, Scalar pressure)
{ DUNE_THROW(Dune::NotImplemented, "Component::gasThermalConductivity()"); }
{
static_assert(AlwaysFalse<C>::value, "Mandatory function not implemented: gasThermalConductivity(t,p)");
DUNE_THROW(Dune::NotImplemented, "gasThermalConductivity(t,p)");
}
/*!
* \brief Specific isobaric heat capacity of the component \f$\mathrm{[J/(kg*K)]}\f$ as a gas.
* \param temperature temperature of component in \f$\mathrm{[K]}\f$
* \param pressure pressure of component in \f$\mathrm{[Pa]}\f$
*/
template<class C = Component>
static Scalar gasHeatCapacity(Scalar temperature, Scalar pressure)
{ DUNE_THROW(Dune::NotImplemented, "Component::gasHeatCapacity()"); }
{
static_assert(AlwaysFalse<C>::value, "Mandatory function not implemented: gasHeatCapacity(t,p)");
DUNE_THROW(Dune::NotImplemented, "gasHeatCapacity(t,p)");
}
};
......
......@@ -27,6 +27,8 @@
#include <dune/common/exceptions.hh>
#include <dumux/common/typetraits/typetraits.hh>
namespace Dumux {
namespace Components {
......@@ -43,14 +45,22 @@ public:
/*!
* \brief Returns true if the liquid phase is assumed to be compressible
*/
template<class C = Component>
static constexpr bool liquidIsCompressible()
{ return Component::liquidIsCompressible(); }
{
static_assert(AlwaysFalse<C>::value, "Mandatory function not implemented: liquidIsCompressible()");
DUNE_THROW(Dune::NotImplemented, "liquidIsCompressible()");
}
/*!
* \brief Returns true if the liquid phase viscostiy is constant
*/
template<class C = Component>
static constexpr bool liquidViscosityIsConstant()
{ return Component::liquidViscosityIsConstant(); }
{
static_assert(AlwaysFalse<C>::value, "Mandatory function not implemented: liquidViscosityIsConstant()");
DUNE_THROW(Dune::NotImplemented, "liquidViscosityIsConstant()");
}
/*!
* \brief The density \f$\mathrm{[kg/m^3]}\f$ of the liquid component at a given pressure in
......@@ -59,8 +69,12 @@ public:
* \param temperature temperature of component in \f$\mathrm{[K]}\f$
* \param pressure pressure of component in \f$\mathrm{[Pa]}\f$
*/
template<class C = Component>
static Scalar liquidDensity(Scalar temperature, Scalar pressure)
{ DUNE_THROW(Dune::NotImplemented, "Component::liquidDensity(t,p)"); }
{
static_assert(AlwaysFalse<C>::value, "Mandatory function not implemented: liquidDensity(t,p)");
DUNE_THROW(Dune::NotImplemented, "liquidDensity(t,p)");
}
/*!
* \brief The dynamic liquid viscosity \f$\mathrm{[Pa*s]}\f$ of the pure component.
......@@ -68,8 +82,12 @@ public:
* \param temperature temperature of component in \f$\mathrm{[K]}\f$
* \param pressure pressure of component in \f$\mathrm{[Pa]}\f$
*/
template<class C = Component>
static Scalar liquidViscosity(Scalar temperature, Scalar pressure)
{ DUNE_THROW(Dune::NotImplemented, "Component::liquidViscosity(t,p)"); }
{
static_assert(AlwaysFalse<C>::value, "Mandatory function not implemented: liquidViscosity(t,p)");
DUNE_THROW(Dune::NotImplemented, "liquidViscosity(t,p)");
}
/*!
* \brief Specific enthalpy \f$\mathrm{[J/kg]}\f$ of the pure component in liquid.
......@@ -77,8 +95,12 @@ public:
* \param temperature temperature of component in \f$\mathrm{[K]}\f$
* \param pressure pressure of component in \f$\mathrm{[Pa]}\f$
*/
template<class C = Component>
static const Scalar liquidEnthalpy(Scalar temperature, Scalar pressure)
{ DUNE_THROW(Dune::NotImplemented, "Component::liquidEnthalpy()"); }
{
static_assert(AlwaysFalse<C>::value, "Mandatory function not implemented: liquidEnthalpy(t,p)");
DUNE_THROW(Dune::NotImplemented, "liquidEnthalpy(t,p)");
}
/*!
* \brief Specific internal energy \f$\mathrm{[J/kg]}\f$ of pure the pure component in liquid.
......@@ -86,24 +108,36 @@ public:
* \param temperature temperature of component in \f$\mathrm{[K]}\f$
* \param pressure pressure of component in \f$\mathrm{[Pa]}\f$
*/
template<class C = Component>
static const Scalar liquidInternalEnergy(Scalar temperature, Scalar pressure)
{ DUNE_THROW(Dune::NotImplemented, "Component::liquidInternalEnergy()"); }
{
static_assert(AlwaysFalse<C>::value, "Mandatory function not implemented: liquidInternalEnergy(t,p)");
DUNE_THROW(Dune::NotImplemented, "liquidInternalEnergy(t,p)");
}
/*!
* \brief Thermal conductivity of the component \f$\mathrm{[W/(m*K)]}\f$ as a liquid.
* \param temperature temperature of component in \f$\mathrm{[K]}\f$
* \param pressure pressure of component in \f$\mathrm{[Pa]}\f$
*/
template<class C = Component>
static Scalar liquidThermalConductivity(Scalar temperature, Scalar pressure)
{ DUNE_THROW(Dune::NotImplemented, "Component::liquidThermalConductivity()"); }
{
static_assert(AlwaysFalse<C>::value, "Mandatory function not implemented: liquidThermalConductivity(t,p)");
DUNE_THROW(Dune::NotImplemented, "liquidThermalConductivity(t,p)");
}
/*!
* \brief Specific isobaric heat capacity of the component \f$\mathrm{[J/(kg*K)]}\f$ as a liquid.
* \param temperature temperature of component in \f$\mathrm{[K]}\f$
* \param pressure pressure of component in \f$\mathrm{[Pa]}\f$
*/
template<class C = Component>
static Scalar liquidHeatCapacity(Scalar temperature, Scalar pressure)
{ DUNE_THROW(Dune::NotImplemented, "Component::liquidHeatCapacity()"); }
{
static_assert(AlwaysFalse<C>::value, "Mandatory function not implemented: liquidHeatCapacity(t,p)");
DUNE_THROW(Dune::NotImplemented, "liquidHeatCapacity(t,p)");
}
};
} // end namespace Components
......
......@@ -322,6 +322,17 @@ public:
return 0.025;
}
/*!
* \brief Specific isobaric heat capacity of water steam \f$\mathrm{[J/(kg*K)}\f$.
* source: http://webbook.nist.gov/cgi/fluid.cgi?ID=C7732185&Action=Page
* @ T= 372.76K (99.6°C) , p=0.1MPa)
* \param temperature temperature of component in \f$\mathrm{[K]}\f$
* \param pressure pressure of component in \f$\mathrm{[Pa]}\f$
*/
static Scalar gasHeatCapacity(Scalar temperature, Scalar pressure)
{
return 2.08e3;
}
};
......
......@@ -27,6 +27,8 @@
#include <dune/common/exceptions.hh>
#include <dumux/common/typetraits/typetraits.hh>
namespace Dumux {
namespace Components {
......@@ -43,8 +45,12 @@ public:
/*!
* \brief Returns true if the solid phase is assumed to be compressible
*/
template<class C = Component>
static constexpr bool solidIsCompressible()
{ return Component::solidIsCompressible(); }
{
static_assert(AlwaysFalse<C>::value, "Mandatory function not implemented: solidIsCompressible()");
DUNE_THROW(Dune::NotImplemented, "solidIsCompressible()");
}
/*!
* \brief The density in \f$\mathrm{[kg/m^3]}\f$ of the component at a given pressure in
......@@ -53,8 +59,12 @@ public:
* \param temperature temperature of component in \f$\mathrm{[K]}\f$
* \param pressure pressure of component in \f$\mathrm{[Pa]}\f$
*/
template<class C = Component>
static Scalar solidDensity(Scalar temperature, Scalar pressure)
{ DUNE_THROW(Dune::NotImplemented, "Component::solidDensity()"); }
{
static_assert(AlwaysFalse<C>::value, "Mandatory function not implemented: solidDensity(t,p)");
DUNE_THROW(Dune::NotImplemented, "solidDensity(t,p)");
}
/*!
* \brief Specific enthalpy \f$\mathrm{[J/kg]}\f$ of the pure component in solid.
......@@ -62,8 +72,12 @@ public:
* \param temperature temperature of component in \f$\mathrm{[K]}\f$
* \param pressure pressure of component in \f$\mathrm{[Pa]}\f$
*/
template<class C = Component>
static const Scalar solidEnthalpy(Scalar temperature, Scalar pressure)
{ DUNE_THROW(Dune::NotImplemented, "Component::solidEnthalpy()"); }
{
static_assert(AlwaysFalse<C>::value, "Mandatory function not implemented: solidEnthalpy(t,p)");
DUNE_THROW(Dune::NotImplemented, "solidEnthalpy(t,p)");
}
/*!
* \brief Specific internal energy \f$\mathrm{[J/kg]}\f$ of the pure component in solid.
......@@ -71,24 +85,36 @@ public:
* \param temperature temperature of component in \f$\mathrm{[K]}\f$
* \param pressure pressure of component in \f$\mathrm{[Pa]}\f$
*/
template<class C = Component>
static const Scalar solidInternalEnergy(Scalar temperature, Scalar pressure)
{ DUNE_THROW(Dune::NotImplemented, "Component::solidInternalEnergy()"); }
{
static_assert(AlwaysFalse<C>::value, "Mandatory function not implemented: solidInternalEnergy(t,p)");
DUNE_THROW(Dune::NotImplemented, "solidInternalEnergy(t,p)");
}
/*!
* \brief Thermal conductivity of the component \f$\mathrm{[W/(m*K)]}\f$ as a solid.
* \param temperature temperature of component in \f$\mathrm{[K]}\f$
* \param pressure pressure of component in \f$\mathrm{[Pa]}\f$
*/
template<class C = Component>
static Scalar solidThermalConductivity(Scalar temperature, Scalar pressure)
{ DUNE_THROW(Dune::NotImplemented, "Component::solidThermalConductivity()"); }
{
static_assert(AlwaysFalse<C>::value, "Mandatory function not implemented: solidThermalConductivity(t,p)");
DUNE_THROW(Dune::NotImplemented, "solidThermalConductivity(t,p)");
}
/*!
* \brief Specific isobaric heat capacity of the component \f$\mathrm{[J/(kg*K)]}\f$ as a solid.
* \param temperature temperature of component in \f$\mathrm{[K]}\f$
* \param pressure pressure of component in \f$\mathrm{[Pa]}\f$
*/
template<class C = Component>
static Scalar solidHeatCapacity(Scalar temperature, Scalar pressure)
{ DUNE_THROW(Dune::NotImplemented, "Component::solidHeatCapacity()"); }
{
static_assert(AlwaysFalse<C>::value, "Mandatory function not implemented: solidHeatCapacity(t,p)");
DUNE_THROW(Dune::NotImplemented, "solidHeatCapacity(t,p)");
}
};
......
......@@ -24,9 +24,12 @@
#include "config.h"
#include <array>
#include <algorithm>
#include <cstring>
#include <limits>
#include <vector>
#include <dumux/common/typetraits/isvalid.hh>
#include <dumux/common/typetraits/typetraits.hh>
#include <dumux/io/gnuplotinterface.hh>
#include <dumux/material/components/air.hh>
#include <dumux/material/components/benzene.hh>
......@@ -46,7 +49,186 @@
#include <dumux/material/components/xylene.hh>
using namespace std;
using namespace Dumux;
namespace Dumux {
//! Helper struct to deactivate static assertions in component's base classes.
struct DisableStaticAssert {};
/*!
* \brief Specialization of Dumux::AlwaysFalse for the struct defined
* above. This is done in order to deactivate the static_assert in
* the base classes of components. If the base class function is compiled
* we do not call it (see below).
*/
template<>
struct AlwaysFalse<DisableStaticAssert> : public std::true_type {};
}
//! helper structs for detecting if a component has certain functions overloaded
struct checkLiqDen { template<class C> auto operator()(C&& c) -> decltype(C::template liquidDensity<DisableStaticAssert>(0.0, 0.0)) {}; };
struct checkLiqEnth { template<class C> auto operator()(C&& c) -> decltype(C::template liquidEnthalpy<DisableStaticAssert>(0.0, 0.0)) {}; };
struct checkLiqHeatCap { template<class C> auto operator()(C&& c) -> decltype(C::template liquidHeatCapacity<DisableStaticAssert>(0.0, 0.0)) {}; };
struct checkLiqVisc { template<class C> auto operator()(C&& c) -> decltype(C::template liquidViscosity<DisableStaticAssert>(0.0, 0.0)) {}; };
struct checkLiqThermCond { template<class C> auto operator()(C&& c) -> decltype(C::template liquidThermalConductivity<DisableStaticAssert>(0.0, 0.0)) {}; };
struct checkGasDen { template<class C> auto operator()(C&& c) -> decltype(C::template gasDensity<DisableStaticAssert>(0.0, 0.0)) {}; };
struct checkGasEnth { template<class C> auto operator()(C&& c) -> decltype(C::template gasEnthalpy<DisableStaticAssert>(0.0, 0.0)) {}; };
struct checkGasHeatCap { template<class C> auto operator()(C&& c) -> decltype(C::template gasHeatCapacity<DisableStaticAssert>(0.0, 0.0)) {}; };
struct checkGasVisc { template<class C> auto operator()(C&& c) -> decltype(C::template gasViscosity<DisableStaticAssert>(0.0, 0.0)) {}; };
struct checkGasThermCond { template<class C> auto operator()(C&& c) -> decltype(C::template gasThermalConductivity<DisableStaticAssert>(0.0, 0.0)) {}; };
//! plot given values
template<class Functor>
void plot(Functor&& f,
const vector<double>& T,
const double pressure,
const std::string& compName,
const std::string& phaseName,
const std::string& propName,
const std::string& unit,
bool openPlot)
{
vector<double> values(T.size());
for (int i = 0; i < T.size(); ++i)
values[i] = f(T[i], pressure);
const auto minMax = minmax_element(values.begin(), values.end());
Dumux::GnuplotInterface<double> gnuplot(true);
gnuplot.setOpenPlotWindow(openPlot);
gnuplot.setCreateImage(true);
gnuplot.setXRange(T[0], T[T.size()-1]);
gnuplot.setYRange(*(minMax.first)*0.999, *(minMax.second)*1.001);
gnuplot.setXlabel("temperature [K]");
gnuplot.setYlabel(phaseName + " " + propName + " " + unit);
gnuplot.setDatafileSeparator(',');
gnuplot.addDataSetToPlot(T, values, compName + "_" + phaseName + "_" + propName + ".csv");
gnuplot.plot(compName + "_" + phaseName + "_" + propName);
}
//! Plot properties if overloads compile
template<class C, class hasNoDensityOverload = checkLiqDen>
auto plotLiquidDensity(const vector<double>& T, double p, bool openPlot)
-> typename std::enable_if_t<!decltype(isValid(hasNoDensityOverload{})(declval<C>()))::value, void>
{
auto f = [] (auto T, auto p) { return C::liquidDensity(T, p); };
plot(f, T, p, C::name(), "liquid", "density", "[kg/^3]", openPlot);
}
template<class C, class hasNoEnthalpyOverload = checkLiqEnth>
auto plotLiquidEnthalpy(const vector<double>& T, double p, bool openPlot)
-> typename std::enable_if_t<!decltype(isValid(hasNoEnthalpyOverload{})(declval<C>()))::value, void>
{
auto f = [] (auto T, auto p) { return C::liquidEnthalpy(T, p); };
plot(f, T, p, C::name(), "liquid", "enthalpy", "[J/(kg)]", openPlot);
}
template<class C, class hasNoHeatCapOverload = checkLiqHeatCap>
auto plotLiquidHeatCapacity(const vector<double>& T, double p, bool openPlot)
-> typename std::enable_if_t<!decltype(isValid(hasNoHeatCapOverload{})(declval<C>()))::value, void>
{
auto f = [] (auto T, auto p) { return C::liquidHeatCapacity(T, p); };
plot(f, T, p, C::name(), "liquid", "heat capacity", "[J/(kg*K)]", openPlot);
}
template<class C, class hasNoViscOverload = checkLiqVisc>
auto plotLiquidViscosity(const vector<double>& T, double p, bool openPlot)
-> typename std::enable_if_t<!decltype(isValid(hasNoViscOverload{})(declval<C>()))::value, void>
{
auto f = [] (auto T, auto p) { return C::liquidViscosity(T, p); };
plot(f, T, p, C::name(), "liquid", "viscosity", "[Pa*s]", openPlot);
}
template<class C, class hasNoThermCondOverload = checkLiqThermCond>
auto plotLiquidThermalConductivity(const vector<double>& T, double p, bool openPlot)
-> typename std::enable_if_t<!decltype(isValid(hasNoThermCondOverload{})(declval<C>()))::value, void>
{
auto f = [] (auto T, auto p) { return C::liquidThermalConductivity(T, p); };
plot(f, T, p, C::name(), "liquid", "thermal conductivity", "[J/(kg*K)]", openPlot);