diff --git a/Documentation/ProjectFile/properties/property/ClausiusClapeyron/c_ClausiusClapeyron.md b/Documentation/ProjectFile/properties/property/ClausiusClapeyron/c_ClausiusClapeyron.md new file mode 100644 index 0000000000000000000000000000000000000000..9a68c5f2ac3fdc6425dacb1b7c9ddee2f5a00c00 --- /dev/null +++ b/Documentation/ProjectFile/properties/property/ClausiusClapeyron/c_ClausiusClapeyron.md @@ -0,0 +1 @@ +\copydoc MaterialPropertyLib::ClausiusClapeyron diff --git a/Documentation/ProjectFile/properties/property/ClausiusClapeyron/t_critical_pressure.md b/Documentation/ProjectFile/properties/property/ClausiusClapeyron/t_critical_pressure.md new file mode 100644 index 0000000000000000000000000000000000000000..b14bd1aa224ebc065c86356cc855e92e45aa6ae0 --- /dev/null +++ b/Documentation/ProjectFile/properties/property/ClausiusClapeyron/t_critical_pressure.md @@ -0,0 +1 @@ +Pressure at the critical point. diff --git a/Documentation/ProjectFile/properties/property/ClausiusClapeyron/t_critical_temperature.md b/Documentation/ProjectFile/properties/property/ClausiusClapeyron/t_critical_temperature.md new file mode 100644 index 0000000000000000000000000000000000000000..57f849ee3fd22a7c3d406c7f1c935a29d783b121 --- /dev/null +++ b/Documentation/ProjectFile/properties/property/ClausiusClapeyron/t_critical_temperature.md @@ -0,0 +1 @@ +Temperature at the critical point. diff --git a/Documentation/ProjectFile/properties/property/ClausiusClapeyron/t_reference_pressure.md b/Documentation/ProjectFile/properties/property/ClausiusClapeyron/t_reference_pressure.md new file mode 100644 index 0000000000000000000000000000000000000000..1aed948592344d74d64903874a6b0d3b03401890 --- /dev/null +++ b/Documentation/ProjectFile/properties/property/ClausiusClapeyron/t_reference_pressure.md @@ -0,0 +1 @@ +Reference pressure. diff --git a/Documentation/ProjectFile/properties/property/ClausiusClapeyron/t_reference_temperature.md b/Documentation/ProjectFile/properties/property/ClausiusClapeyron/t_reference_temperature.md new file mode 100644 index 0000000000000000000000000000000000000000..ffadfa403befbdb4b81d4bda00bf576efbd50adf --- /dev/null +++ b/Documentation/ProjectFile/properties/property/ClausiusClapeyron/t_reference_temperature.md @@ -0,0 +1 @@ +Reference temperature. diff --git a/Documentation/ProjectFile/properties/property/ClausiusClapeyron/t_triple_pressure.md b/Documentation/ProjectFile/properties/property/ClausiusClapeyron/t_triple_pressure.md new file mode 100644 index 0000000000000000000000000000000000000000..2fb94e371822365a1f1757ee442ae9aab671dc17 --- /dev/null +++ b/Documentation/ProjectFile/properties/property/ClausiusClapeyron/t_triple_pressure.md @@ -0,0 +1 @@ +Pressure at the triple point. diff --git a/Documentation/ProjectFile/properties/property/ClausiusClapeyron/t_triple_temperature.md b/Documentation/ProjectFile/properties/property/ClausiusClapeyron/t_triple_temperature.md new file mode 100644 index 0000000000000000000000000000000000000000..9ddc00d69d8446bfe23845a00a10bbf9dcc126b7 --- /dev/null +++ b/Documentation/ProjectFile/properties/property/ClausiusClapeyron/t_triple_temperature.md @@ -0,0 +1 @@ +Temperature at the triple point. diff --git a/MaterialLib/MPL/CreateProperty.cpp b/MaterialLib/MPL/CreateProperty.cpp index b67c0f50d9a4431a6c93765379c447d8b06a16ff..ce18a18695db87268aba899ee8cdc2707ca00df5 100644 --- a/MaterialLib/MPL/CreateProperty.cpp +++ b/MaterialLib/MPL/CreateProperty.cpp @@ -66,6 +66,11 @@ std::unique_ptr<MaterialPropertyLib::Property> createProperty( return createAverageMolarMass(config); } + if (boost::iequals(property_type, "ClausiusClapeyron")) + { + return createClausiusClapeyron(config); + } + if (boost::iequals(property_type, "Dupuit")) { return createDupuitPermeability(config, parameters); diff --git a/MaterialLib/MPL/Properties/ClausiusClapeyron.cpp b/MaterialLib/MPL/Properties/ClausiusClapeyron.cpp new file mode 100644 index 0000000000000000000000000000000000000000..46fb49a970f6f8d965181baf9fce9d0efec7ec07 --- /dev/null +++ b/MaterialLib/MPL/Properties/ClausiusClapeyron.cpp @@ -0,0 +1,154 @@ +/** + * \file + * \author Norbert Grunwald + * \date Dec 07, 2020 + * \brief + * + * \file + * \copyright + * Copyright (c) 2012-2020, OpenGeoSys Community (http://www.opengeosys.org) + * Distributed under a Modified BSD License. + * See accompanying file LICENSE.txt or + * http://www.opengeosys.org/project/license + * + */ + +#include "MaterialLib/MPL/Properties/ClausiusClapeyron.h" + +#include "MaterialLib/MPL/Medium.h" +#include "MaterialLib/PhysicalConstant.h" + +namespace MaterialPropertyLib +{ +ClausiusClapeyron::ClausiusClapeyron(std::string name, + const double triple_temperature, + const double triple_pressure, + const double critical_temperature, + const double critical_pressure, + const double ref_temperature, + const double ref_pressure) + : T_triple_(triple_temperature), + p_triple_(triple_pressure), + T_critical_(critical_temperature), + p_critical_(critical_pressure), + T_ref_(ref_temperature), + p_ref_(ref_pressure) +{ + name_ = std::move(name); +} + +void ClausiusClapeyron::checkScale() const +{ + if (!(std::holds_alternative<Phase*>(scale_) || + std::holds_alternative<Component*>(scale_))) + { + OGS_FATAL( + "The property 'ClausiusClapeyron' is implemented on 'phase' and " + "'component' scales only."); + } +} + +double ClausiusClapeyron::molarMass( + std::variant<Medium*, Phase*, Component*> const scale, + VariableArray const& variable_array, + ParameterLib::SpatialPosition const& pos, double const t, + double const dt) const +{ + return std::visit( + [&variable_array, &pos, t, dt](auto&& s) -> double { + return s->property(PropertyType::molar_mass) + .template value<double>(variable_array, pos, t, dt); + }, + scale); +} + +double ClausiusClapeyron::dMolarMass( + std::variant<Medium*, Phase*, Component*> const scale, + VariableArray const& variable_array, Variable const primary_variable, + ParameterLib::SpatialPosition const& pos, double const t, + double const dt) const +{ + return std::visit( + [&variable_array, &primary_variable, &pos, t, dt](auto&& s) -> double { + return s->property(PropertyType::molar_mass) + .template dValue<double>(variable_array, primary_variable, pos, + t, dt); + }, + scale); +} + +PropertyDataType ClausiusClapeyron::value( + VariableArray const& variable_array, + ParameterLib::SpatialPosition const& pos, double const t, + double const dt) const +{ + const double T = std::get<double>( + variable_array[static_cast<int>(Variable::temperature)]); + + const double M = molarMass(scale_, variable_array, pos, t, dt); + + if (T >= T_critical_) + { + return p_critical_; + } + if (T <= T_triple_) + { + return p_triple_; + } + + const double dh = std::get<double>( + variable_array[static_cast<int>(Variable::enthalpy_of_evaporation)]); + const double R = MaterialLib::PhysicalConstant::IdealGasConstant; + + return p_ref_ * std::exp((1. / T_ref_ - 1. / T) * M * dh / R); +} + +PropertyDataType ClausiusClapeyron::dValue( + VariableArray const& variable_array, Variable const primary_variable, + ParameterLib::SpatialPosition const& pos, double const t, + double const dt) const +{ + const double T = std::get<double>( + variable_array[static_cast<int>(Variable::temperature)]); + + const double M = molarMass(scale_, variable_array, pos, t, dt); + const double dM = + dMolarMass(scale_, variable_array, primary_variable, pos, t, dt); + + if (T > T_critical_) + { + return 0.; + } + if (T < T_triple_) + { + return 0.; + } + + const double R = MaterialLib::PhysicalConstant::IdealGasConstant; + const double dh = std::get<double>( + variable_array[static_cast<int>(Variable::enthalpy_of_evaporation)]); + const double p_vap = std::get<double>(value(variable_array, pos, t, dt)); + + if (primary_variable == Variable::temperature) + { + return p_vap * dh / R * ((1. / T_ref_ - 1. / T) * dM + M / (T * T)); + } + if (primary_variable == Variable::phase_pressure) + { + return p_vap * dh / R * (1. / T_ref_ - 1. / T) * dM; + } + OGS_FATAL( + "ClausiusClapeyron::dValue is implemented for derivatives " + "with respect to phase pressure or temperature only."); +} + +PropertyDataType ClausiusClapeyron::d2Value( + VariableArray const& /*variable_array*/, + Variable const /*primary_variable1*/, Variable const /*primary_variable2*/, + ParameterLib::SpatialPosition const& /*pos*/, double const /*t*/, + double const /*dt*/) const +{ + OGS_FATAL("ClausiusClapeyron::d2Value is not implemented."); +} + +} // namespace MaterialPropertyLib diff --git a/MaterialLib/MPL/Properties/ClausiusClapeyron.h b/MaterialLib/MPL/Properties/ClausiusClapeyron.h new file mode 100644 index 0000000000000000000000000000000000000000..69453185f43aa4e8633b7659bd0851b6e26036e8 --- /dev/null +++ b/MaterialLib/MPL/Properties/ClausiusClapeyron.h @@ -0,0 +1,78 @@ +/** + * \file + * \author Norbert Grunwald + * \date Dec 07, 2020 + * + * \copyright + * Copyright (c) 2012-2020, OpenGeoSys Community (http://www.opengeosys.org) + * Distributed under a Modified BSD License. + * See accompanying file LICENSE.txt or + * http://www.opengeosys.org/project/license + * + */ +#pragma once + +#include "BaseLib/ConfigTree.h" +#include "MaterialLib/MPL/Property.h" + +namespace MaterialPropertyLib +{ +class Medium; +class Phase; +class Component; +/** + * Vapor pressure as function of temperature based on Clausius-Clapeyron + * equation. + * This property must be either a phase or a component + * property, it computes the saturation vapor pressure of a substance + */ +class ClausiusClapeyron final : public Property +{ +public: + explicit ClausiusClapeyron(std::string name, + const double triple_temperature, + const double triple_pressure, + const double critical_temperature, + const double critical_pressure, + const double ref_temperature, + const double ref_pressure); + + void checkScale() const override; + + PropertyDataType value(VariableArray const& variable_array, + ParameterLib::SpatialPosition const& pos, + double const t, + double const dt) const override; + PropertyDataType dValue(VariableArray const& variable_array, + Variable const primary_variable, + ParameterLib::SpatialPosition const& pos, + double const t, + double const dt) const override; + PropertyDataType d2Value(VariableArray const& variable_array, + Variable const primary_variable1, + Variable const primary_variable2, + ParameterLib::SpatialPosition const& pos, + double const t, + double const dt) const override; + +private: + double T_triple_; + double p_triple_; + double T_critical_; + double p_critical_; + double T_ref_; + double p_ref_; + + double molarMass(std::variant<Medium*, Phase*, Component*> const scale, + VariableArray const& variable_array, + ParameterLib::SpatialPosition const& pos, double const t, + double const dt) const; + + double dMolarMass(std::variant<Medium*, Phase*, Component*> const scale, + VariableArray const& variable_array, + Variable const primary_variable, + ParameterLib::SpatialPosition const& pos, double const t, + double const dt) const; +}; + +} // namespace MaterialPropertyLib diff --git a/MaterialLib/MPL/Properties/CreateClausiusClapeyron.cpp b/MaterialLib/MPL/Properties/CreateClausiusClapeyron.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4d92e0f4fb645460b30681ea202066c6ad2022b3 --- /dev/null +++ b/MaterialLib/MPL/Properties/CreateClausiusClapeyron.cpp @@ -0,0 +1,58 @@ +/** + * \file + * \author Norbert Grunwald + * \date Dec 07, 2020 + * + * \copyright + * Copyright (c) 2012-2020, OpenGeoSys Community (http://www.opengeosys.org) + * Distributed under a Modified BSD License. + * See accompanying file LICENSE.txt or + * http://www.opengeosys.org/project/license + */ + +#include "BaseLib/ConfigTree.h" +#include "ClausiusClapeyron.h" + +namespace MaterialPropertyLib +{ +std::unique_ptr<ClausiusClapeyron> createClausiusClapeyron( + BaseLib::ConfigTree const& config) +{ + //! \ogs_file_param{properties__property__type} + config.checkConfigParameter("type", "ClausiusClapeyron"); + + //! \ogs_file_param{properties__property__name} + auto property_name = config.peekConfigParameter<std::string>("name"); + + DBUG("Create ClausiusClapeyron property {:s}.", property_name); + + auto const triple_temperature = + //! \ogs_file_param{properties__property__ClausiusClapeyron__triple_temperature} + config.getConfigParameter<double>("triple_temperature"); + + auto const triple_pressure = + //! \ogs_file_param{properties__property__ClausiusClapeyron__triple_pressure} + config.getConfigParameter<double>("triple_pressure"); + + auto const critical_temperature = + //! \ogs_file_param{properties__property__ClausiusClapeyron__critical_temperature} + config.getConfigParameter<double>("critical_temperature"); + + auto const critical_pressure = + //! \ogs_file_param{properties__property__ClausiusClapeyron__critical_pressure} + config.getConfigParameter<double>("critical_pressure"); + + auto const ref_temperature = + //! \ogs_file_param{properties__property__ClausiusClapeyron__reference_temperature} + config.getConfigParameter<double>("reference_temperature"); + + auto const ref_pressure = + //! \ogs_file_param{properties__property__ClausiusClapeyron__reference_pressure} + config.getConfigParameter<double>("reference_pressure"); + + //! \ogs_file_param_special{properties__property__ClausiusClapeyron} + return std::make_unique<ClausiusClapeyron>( + std::move(property_name), triple_temperature, triple_pressure, + critical_temperature, critical_pressure, ref_temperature, ref_pressure); +} +} // namespace MaterialPropertyLib diff --git a/MaterialLib/MPL/Properties/CreateClausiusClapeyron.h b/MaterialLib/MPL/Properties/CreateClausiusClapeyron.h new file mode 100644 index 0000000000000000000000000000000000000000..b30976f9d626a476df6fa44e541690c4516adf78 --- /dev/null +++ b/MaterialLib/MPL/Properties/CreateClausiusClapeyron.h @@ -0,0 +1,31 @@ +/** + * \file + * \author Norbert Grunwald + * \date Dec 07, 2020 + * + * \copyright + * Copyright (c) 2012-2020, OpenGeoSys Community (http://www.opengeosys.org) + * Distributed under a Modified BSD License. + * See accompanying file LICENSE.txt or + * http://www.opengeosys.org/project/license + */ + +#pragma once + +#include <memory> + +namespace BaseLib +{ +class ConfigTree; +} + +namespace MaterialPropertyLib +{ +class ClausiusClapeyron; +} + +namespace MaterialPropertyLib +{ +std::unique_ptr<ClausiusClapeyron> createClausiusClapeyron( + BaseLib::ConfigTree const& config); +} // namespace MaterialPropertyLib diff --git a/MaterialLib/MPL/Properties/CreateProperties.h b/MaterialLib/MPL/Properties/CreateProperties.h index 06009127f00977a4d68460d1be2be5280e24129a..696c74bfdcef171d054ad4a65169bcc584567706 100644 --- a/MaterialLib/MPL/Properties/CreateProperties.h +++ b/MaterialLib/MPL/Properties/CreateProperties.h @@ -19,6 +19,7 @@ #include "CreateAverageMolarMass.h" #include "CreateBishopsPowerLaw.h" #include "CreateBishopsSaturationCutoff.h" +#include "CreateClausiusClapeyron.h" #include "CreateConstant.h" #include "CreateCurve.h" #include "CreateDupuitPermeability.h" diff --git a/MaterialLib/MPL/Properties/Properties.h b/MaterialLib/MPL/Properties/Properties.h index 2f5f09fabbb6780172b4a658b421dcff505e2b6b..9628c6ec4d59082437c33e51e74edaeabe60e690 100644 --- a/MaterialLib/MPL/Properties/Properties.h +++ b/MaterialLib/MPL/Properties/Properties.h @@ -17,6 +17,7 @@ #include "CapillaryPressureSaturation/SaturationBrooksCorey.h" #include "CapillaryPressureSaturation/SaturationLiakopoulos.h" #include "CapillaryPressureSaturation/SaturationVanGenuchten.h" +#include "ClausiusClapeyron.h" #include "Constant.h" #include "Curve.h" #include "DupuitPermeability.h" diff --git a/MaterialLib/MPL/PropertyType.h b/MaterialLib/MPL/PropertyType.h index e56a8bb48a692d30ec405ee438ffe48e56c2f774..92a6d6590aa6d9cb3721210763ca1fe4fc0a918c 100644 --- a/MaterialLib/MPL/PropertyType.h +++ b/MaterialLib/MPL/PropertyType.h @@ -16,6 +16,7 @@ #include <boost/algorithm/string/predicate.hpp> #include <memory> #include <string> + #include "BaseLib/Error.h" namespace MaterialPropertyLib @@ -51,6 +52,7 @@ enum PropertyType : int drhodT, effective_stress, entry_pressure, + evaporation_enthalpy, fredlund_parameters, heat_capacity, /// used to compute the hydrodynamic dispersion tensor. @@ -83,6 +85,7 @@ enum PropertyType : int transport_porosity, /// used to compute the hydrodynamic dispersion tensor. transversal_dispersivity, + vapor_pressure, viscosity, number_of_properties }; @@ -162,6 +165,10 @@ inline PropertyType convertStringToProperty(std::string const& inString) { return PropertyType::entry_pressure; } + if (boost::iequals(inString, "evaporation_enthalpy")) + { + return PropertyType::evaporation_enthalpy; + } if (boost::iequals(inString, "fredlund_parameters")) { return PropertyType::fredlund_parameters; @@ -274,6 +281,10 @@ inline PropertyType convertStringToProperty(std::string const& inString) { return PropertyType::transversal_dispersivity; } + if (boost::iequals(inString, "vapor_pressure")) + { + return PropertyType::vapor_pressure; + } if (boost::iequals(inString, "viscosity")) { return PropertyType::viscosity; @@ -305,6 +316,7 @@ static const std::array<std::string, PropertyType::number_of_properties> "drhodT", "effective_stress", "entry_pressure", + "evaporation_enthalpy", "fredlund_parameters", "heat_capacity", "longitudinal_dispersivity", @@ -333,6 +345,7 @@ static const std::array<std::string, PropertyType::number_of_properties> "thermal_transversal_dispersivity", "transport_porosity", "transversal_dispersivity", + "vapor_pressure", "viscosity"}}; /// This data type is based on a std::array. It can hold pointers to objects of diff --git a/MaterialLib/MPL/VariableType.h b/MaterialLib/MPL/VariableType.h index 963b99a88f7ae473d76bdfe0ea6e8edb894181ac..af952c54ce386a54379ea31d085603ba62430ee3 100644 --- a/MaterialLib/MPL/VariableType.h +++ b/MaterialLib/MPL/VariableType.h @@ -48,6 +48,7 @@ enum class Variable : int density, displacement, effective_pore_pressure, + enthalpy_of_evaporation, equivalent_plastic_strain, grain_compressibility, liquid_saturation, diff --git a/Tests/MaterialLib/TestMPLClausiusClapeyron.cpp b/Tests/MaterialLib/TestMPLClausiusClapeyron.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c09ec45186b80a9db2d17a8eaed6b3c0496977ff --- /dev/null +++ b/Tests/MaterialLib/TestMPLClausiusClapeyron.cpp @@ -0,0 +1,195 @@ +/** + * \file + * + * \copyright + * Copyright (c) 2012-2020, OpenGeoSys Community (http://www.opengeosys.org) + * Distributed under a Modified BSD License. + * See accompanying file LICENSE.txt or + * http://www.opengeosys.org/project/license + * + */ +#include <gtest/gtest.h> + +#include <sstream> +#include <string> + +#include "MaterialLib/MPL/Medium.h" +#include "MaterialLib/MPL/Properties/ClausiusClapeyron.h" +#include "TestMPL.h" +#include "Tests/TestTools.h" + +namespace MPL = MaterialPropertyLib; + +std::stringstream config(const double molar_mass, + const double T_triple, + const double T_critical, + const double T_ref, + const double p_triple, + const double p_critical, + const double p_ref, + const double dMdT, + const double dMdp) +{ + std::stringstream m; + m << std::setprecision(16); + m << "<medium>\n"; + m << " <phases>\n"; + m << " <phase>\n"; + m << " <type>Gas</type>\n"; + m << " <components>\n"; + m << " <component>\n"; + m << " <name>W</name>\n"; + m << " <properties>\n"; + m << " <property>\n"; + m << " <name>molar_mass</name>\n"; + m << " <type>Linear</type>\n"; + m << " <reference_value>" << molar_mass << " </reference_value>\n"; + m << " <independent_variable>\n"; + m << " <variable_name>temperature</variable_name>\n"; + m << " <reference_condition>0</reference_condition>\n"; + m << " <slope>" << dMdT << "</slope>\n"; + m << " </independent_variable>\n"; + m << " <independent_variable>\n"; + m << " <variable_name>phase_pressure</variable_name>\n"; + m << " <reference_condition>0.0</reference_condition>\n"; + m << " <slope>" << dMdp << "</slope>\n"; + m << " </independent_variable>\n"; + m << " </property>\n"; + m << " <property>\n"; + m << " <name>vapor_pressure</name>\n"; + m << " <type>ClausiusClapeyron</type>\n"; + m << "<triple_temperature>" << T_triple << "</triple_temperature>\n"; + m << "<critical_temperature>" << T_critical << "</critical_temperature>\n"; + m << "<reference_temperature>" << T_ref << "</reference_temperature>\n"; + m << "<triple_pressure>" << p_triple << "</triple_pressure>\n"; + m << "<critical_pressure>" << p_critical << "</critical_pressure>\n"; + m << "<reference_pressure>" << p_ref << "</reference_pressure>\n"; + m << " </property>\n"; + m << " </properties>\n"; + m << " </component>\n"; + m << " </components>\n"; + m << " <properties>\n"; + m << " </properties>\n"; + m << " </phase>\n"; + m << " </phases>\n"; + m << " <properties>\n"; + m << " </properties>\n"; + m << "</medium>\n"; + return m; +} + +const double molar_mass = 0.018015; +const double evaporation_enthalpy = 2.257e6; +const double T_triple = 273.16; +const double T_critical = 647.1; +const double T_ref = 373.15; +const double p_triple = 836.21849; +const double p_critical = 26016399.68391; +const double p_ref = 101325; +const double dMdT = 1.e-5; +const double dMdp = -1.e-8; + +std::array<double, 29> const ref_temperature = { + 2.70000E+02, 2.72000E+02, 2.73000E+02, 2.73150E+02, 2.73160E+02, + 2.75000E+02, 2.80000E+02, 3.00000E+02, 3.20000E+02, 3.40000E+02, + 3.60000E+02, 3.73150E+02, 4.00000E+02, 4.50000E+02, 5.00000E+02, + 5.50000E+02, 6.00000E+02, 6.47100E+02, 6.50000E+02, 2.70000E+02, + 3.00000E+02, 3.30000E+02, 3.60000E+02, 3.90000E+02, 4.20000E+02, + 2.70000E+02, 3.00000E+02, 3.30000E+02, 3.60000E+02}; + +std::array<double, 29> const ref_liquid_pressure = { + 1.01325E+05, 1.01325E+05, 1.01325E+05, 1.01325E+05, 1.01325E+05, + 1.01325E+05, 1.01325E+05, 1.01325E+05, 1.01325E+05, 1.01325E+05, + 1.01325E+05, 1.01325E+05, 1.01325E+05, 1.01325E+05, 1.01325E+05, + 1.01325E+05, 1.01325E+05, 1.01325E+05, 1.01325E+05, 1.01325E+05, + 1.50000E+05, 2.00000E+05, 5.00000E+05, 1.00000E+06, 5.00000E+06, + 1.01325E+05, 1.50000E+05, 2.00000E+05, 5.00000E+05}; + +std::array<double, 29> const ref_vapor_pressure = { + 8.36218490000000E+02, 8.36218490000000E+02, 8.36218490000000E+02, + 8.36218490000000E+02, 8.36218490000000E+02, 9.35003929341767E+02, + 1.28489641893467E+03, 4.12252674333030E+03, 1.14370551053552E+04, + 2.81490332971881E+04, 6.27015396656223E+04, 1.01325000000000E+05, + 2.44852602635238E+05, 9.57415384221067E+05, 2.85381686957823E+06, + 6.98277711336414E+06, 1.47345726218355E+07, 2.60163996839100E+07, + 2.60163996839100E+07, 8.36218490000000E+02, 4.12894398711138E+03, + 1.82193325072170E+04, 6.28213193519972E+04, 1.77877844206557E+05, + 4.08809303341452E+05, 8.36218490000000E+02, 4.12894398711138E+03, + 1.82193325072170E+04, 6.28213193519972E+04}; + +std::array<double, 29> const ref_d_vapor_pressure_dT = { + 0.00000000000000E+00, 0.00000000000000E+00, 0.00000000000000E+00, + 0.00000000000000E+00, 5.48586853887215E+01, 6.05228838489413E+01, + 8.02335271069103E+01, 2.24315684282508E+02, 5.47138176563398E+02, + 1.19327831787700E+03, 2.37176618859269E+03, 3.56829135217340E+03, + 7.50820659017266E+03, 2.32230679272202E+04, 5.61410287431912E+04, + 1.13685276471403E+05, 2.01883331325872E+05, 3.06935462457948E+05, + 0.00000000000000E+00, 0.00000000000000E+00, 2.24555657648407E+02, + 8.18907637521856E+02, 2.36684655384022E+03, 5.68517643381087E+03, + 1.08201481763584E+04, 0.00000000000000E+00, 2.24555657648407E+02, + 8.18907637521856E+02, 2.36684655384022E+03}; + +std::array<double, 29> const ref_d_vapor_pressure_dp = { + 0.00000000000000E+00, 0.00000000000000E+00, 0.00000000000000E+00, + 0.00000000000000E+00, 4.01150605544652E-05, 4.37340067538689E-05, + 5.60197502360705E-05, 1.31736092964623E-04, 2.48952060831370E-04, + 3.59680026912301E-04, 3.00157831341098E-04, -0.00000000000000E+00, + -2.15395807049717E-03, -2.14279182737438E-02, -9.48843943114251E-02, + -2.94251561405101E-01, -7.30084785980384E-01, -1.44342865427858E+00, + 0.00000000000000E+00, 0.00000000000000E+00, 1.31941157158491E-04, + 3.12210527929795E-04, 3.00731227322962E-04, -1.00717602020783E-03, + -5.97625743435430E-03, 0.00000000000000E+00, 1.31941157158491E-04, + 3.12210527929795E-04, 3.00731227322962E-04}; + +TEST(MaterialPropertyLib, ClausiusClapeyron) +{ + std::stringstream m; + + for (std::size_t i = 0; i < ref_temperature.size(); i++) + { + MaterialPropertyLib::VariableArray variable_array; + ParameterLib::SpatialPosition const pos; + double const t = std::numeric_limits<double>::quiet_NaN(); + double const dt = std::numeric_limits<double>::quiet_NaN(); + + std::stringstream m = config(molar_mass, T_triple, T_critical, T_ref, + p_triple, p_critical, p_ref, dMdT, dMdp); + + auto const& medium = Tests::createTestMaterial(m.str()); + auto const& gas_phase = medium->phase("Gas"); + + const double p_LR = ref_liquid_pressure[i]; + const double T = ref_temperature[i]; + + variable_array[static_cast<int>( + MaterialPropertyLib::Variable::phase_pressure)] = p_LR; + variable_array[static_cast<int>( + MaterialPropertyLib::Variable::temperature)] = T; + variable_array[static_cast<int>( + MaterialPropertyLib::Variable::enthalpy_of_evaporation)] = + evaporation_enthalpy; + + auto const p_vap = + gas_phase.component(0) + .property(MaterialPropertyLib::PropertyType::vapor_pressure) + .template value<double>(variable_array, pos, t, dt); + + auto const d_p_vap_dT = + gas_phase.component(0) + .property(MaterialPropertyLib::PropertyType::vapor_pressure) + .template dValue<double>( + variable_array, MaterialPropertyLib::Variable::temperature, + pos, t, dt); + + auto const d_p_vap_dp = + gas_phase.component(0) + .property(MaterialPropertyLib::PropertyType::vapor_pressure) + .template dValue<double>( + variable_array, + MaterialPropertyLib::Variable::phase_pressure, pos, t, dt); + + ASSERT_NEAR(p_vap, ref_vapor_pressure[i], 1.e-7); + ASSERT_NEAR(d_p_vap_dT, ref_d_vapor_pressure_dT[i], 1.e-7); + ASSERT_NEAR(d_p_vap_dp, ref_d_vapor_pressure_dp[i], 1.e-7); + } +}