diff --git a/modules/doc/content/newsletter/2024/2024_09.md b/modules/doc/content/newsletter/2024/2024_09.md index 1169934a8f36..64efc847b999 100644 --- a/modules/doc/content/newsletter/2024/2024_09.md +++ b/modules/doc/content/newsletter/2024/2024_09.md @@ -7,6 +7,13 @@ for a complete description of all MOOSE changes. ## MOOSE Improvements +### Specific internal energy added to Solid Properties objects + +The [ThermalSolidProperties.md] objects from the [Solid properties module](modules/solid_properties/index.md) +now provide interfaces to compute the specific internal energy as a function of +temperature. This new interface is useful, for example, in measuring the +internal energy in solids for energy conservation verification. + ## libMesh-level Changes ## PETSc-level Changes diff --git a/modules/solid_properties/doc/content/modules/solid_properties/index.md b/modules/solid_properties/doc/content/modules/solid_properties/index.md index ee61b3c638f8..e6b750015ffc 100644 --- a/modules/solid_properties/doc/content/modules/solid_properties/index.md +++ b/modules/solid_properties/doc/content/modules/solid_properties/index.md @@ -63,17 +63,19 @@ Userobjects available in the Solid Properties module that provide thermal proper An example will be provided later on this page for creating a new solid userobject. On their own, these userobjects do not execute; their functions must be called from other -objects. The most common use case is to compute material properties with these -userobjects, which can be accomplished with -[ThermalSolidPropertiesMaterial](/materials/ThermalSolidPropertiesMaterial.md); -its `computeQpProperties` method evaluates the thermal conductivity, isobaric specific heat, and density at -the quadrature points using the values of a coupled variable representing temperature -plus the functions provided by the selected userobject: - -!listing modules/solid_properties/src/materials/ThermalSolidPropertiesMaterial.C start=computeQpProperties - -Another use case is to get a single property into a post-processor, -which is accomplished with [ThermalSolidPropertiesPostprocessor.md]. +objects. Some potentially useful classes that call them are: + +- [ThermalSolidPropertiesFunctorMaterial.md]: A functor material that declares + functor material properties for density, thermal conductivity, isobaric specific heat, + and specific internal energy. An option is provided for using a constant density. + This functor material can have its functor material properties converted to + regular AD or non-AD material properties by using it in conjunction with + [(AD)MaterialFunctorConverter](MaterialFunctorConverter.md). +- [ThermalSolidPropertiesMaterial.md] and [ConstantDensityThermalSolidPropertiesMaterial.md], + which declare AD or non-AD material properties for density, thermal conductivity, and isobaric specific heat, + using variable density and constant density, respectively. +- [ThermalSolidPropertiesPostprocessor.md] evaluates density, thermal conductivity, + or isobaric specific heat at a single temperature value. ## Usage diff --git a/modules/solid_properties/doc/content/source/functormaterials/ThermalSolidPropertiesFunctorMaterial.md b/modules/solid_properties/doc/content/source/functormaterials/ThermalSolidPropertiesFunctorMaterial.md index 5957060ad60a..1ca3e401f3ee 100644 --- a/modules/solid_properties/doc/content/source/functormaterials/ThermalSolidPropertiesFunctorMaterial.md +++ b/modules/solid_properties/doc/content/source/functormaterials/ThermalSolidPropertiesFunctorMaterial.md @@ -2,17 +2,14 @@ ## Description -The `ThermalSolidPropertiesFunctorMaterial` material declares -density, specific heat, and thermal -conductivity as functor material properties. They are evaluated on-the-fly -on every query. +`ThermalSolidPropertiesFunctorMaterial` declares functor material properties for +density, specific heat, and thermal conductivity, and specific internal energy. -!alert warning title=Conservation on fixed-sized domains -Using a variable density can lead to mass/energy conservation errors if using -a fixed-size domain. If this is a concern, it is recommended to use -a constant density, specified independently using a [GenericFunctorMaterial.md] for example. -For the density parameter of `ThermalSolidPropertiesFunctorMaterial` you may then use a -placeholder dummy name. +The parameter [!param](/FunctorMaterials/ThermalSolidPropertiesFunctorMaterial/use_constant_density) +can be used to specify that the density should be constant, evaluated at the temperature +[!param](/FunctorMaterials/ThermalSolidPropertiesFunctorMaterial/T_ref). This is +useful because for fixed-sized domains, mass/energy conservation errors result +from using a variable density. !syntax parameters /FunctorMaterials/ThermalSolidPropertiesFunctorMaterial diff --git a/modules/solid_properties/doc/content/source/solidproperties/ThermalSolidProperties.md b/modules/solid_properties/doc/content/source/solidproperties/ThermalSolidProperties.md index aef4cad16bc5..b681525f4a9c 100644 --- a/modules/solid_properties/doc/content/source/solidproperties/ThermalSolidProperties.md +++ b/modules/solid_properties/doc/content/source/solidproperties/ThermalSolidProperties.md @@ -2,21 +2,68 @@ This is the base class for providing thermal solid properties as a function of temperature. -This class defines functions to compute the following thermal properties -as a function of temperature: +This class defines functions to compute the following thermal properties, +which are all assumed to be functions of temperature only: -- compute isobaric specific heat - `Real cp_from_T(const Real & T)` -- compute thermal conductivity - `Real k_from_T(const Real & T)` -- compute density - `Real rho_from_T(const Real & T)` +- `cp`: isobaric specific heat, $c_p$ +- `e`: specific internal energy, $e$ +- `k`: thermal conductivity, $k$ +- `rho`: density, $\rho$ -Functions to compute derivatives of these properties as a function of temperature -are also available: +For each of these, the following methods are available, where `y` should be +replaced by the respective property name given in the list above: -- compute isobaric specific heat and its temperature derivative - `void cp_from_T(const Real & T, Real & cp, Real & dcp_dT)` -- compute thermal conductivity and its temperature derivative - `void k_from_T(const Real & T, Real & k, Real & dk_dT)` -- compute density and its temperature derivative - `void rho_from_T(const Real & T, Real & rho, Real & drho_dT)` +``` +Real y_from_T(const Real & T) const +``` -To create a new userobject providing thermal properties, derive from this -userobject and specify implementations of the above functions. +provides the value $y(T)$ using a `Real` input value for $T$. + +``` +void y_from_T(const Real & T, Real & y, Real & dy_dT) const +``` + +provides the value $y(T)$ and its derivative $y'(T)$ using a `Real` input value for $T$. + +``` +ADReal y_from_T(const ADReal & T) const +``` + +provides the value $y(T)$ and its derivative $y'(T)$ using an `ADReal` input value for $T$. + +Thus both AD and non-AD interfaces are available. Derived classes are only responsible +for overriding the non-AD interfaces for each property. The AD interfaces are +implemented by default by combining the two non-AD interfaces. + +Note that the `e_from_T` interfaces should not be overridden because they have +generic implementations, and the non-AD interfaces are not even virtual. +Instead, derived classes must override the following: + +``` +Real cp_integral(const Real & T) const +``` + +which corresponds to the indefinite integral $C(T)$ of $c_p(T)$, minus the +constant of integration: + +!equation +C(T) = \int c_p(T) dT \,. + +Due to the definition of the isobaric specific heat capacity, + +!equation +c_p \equiv \left.\frac{\partial e}{\partial T}\right|_v \,, + +the specific internal energy can be expressed as + +!equation +e(T) - e(T_0) = \int\limits_{T_0}^T c_p(T') dT' = C(T) - C(T_0) \,, + +where $T_0$ is the temperature at which the specific internal energy is assumed +to be zero. This is a convention supplied by the user using the parameter +[!param](/SolidProperties/ThermalSS316Properties/T_zero_e). By default, this +is taken to be at standard temperature, 273.15 K. Note that this is important +for comparing specific internal energy values to external sources, which may +be based on different reference temperatures. !bibtex bibliography diff --git a/modules/solid_properties/include/base/SolidPropertiesNames.h b/modules/solid_properties/include/base/SolidPropertiesNames.h index 4f79d0ba0b99..9fb59167f723 100644 --- a/modules/solid_properties/include/base/SolidPropertiesNames.h +++ b/modules/solid_properties/include/base/SolidPropertiesNames.h @@ -16,4 +16,5 @@ namespace SolidPropertiesNames static const std::string thermal_conductivity = "thermal_conductivity"; static const std::string density = "density"; static const std::string specific_heat = "specific_heat"; +static const std::string specific_internal_energy = "specific_internal_energy"; } diff --git a/modules/solid_properties/include/solidproperties/ThermalCompositeSiCProperties.h b/modules/solid_properties/include/solidproperties/ThermalCompositeSiCProperties.h index c6a673c5affc..daa137cb4b57 100644 --- a/modules/solid_properties/include/solidproperties/ThermalCompositeSiCProperties.h +++ b/modules/solid_properties/include/solidproperties/ThermalCompositeSiCProperties.h @@ -32,6 +32,8 @@ class ThermalCompositeSiCProperties : public ThermalSolidProperties virtual void cp_from_T(const Real & T, Real & cp, Real & dcp_dT) const override; + virtual Real cp_integral(const Real & T) const override; + virtual Real rho_from_T(const Real & T) const override; virtual void rho_from_T(const Real & T, Real & rho, Real & drho_dT) const override; @@ -39,6 +41,12 @@ class ThermalCompositeSiCProperties : public ThermalSolidProperties protected: /// (constant) density const Real & _rho_const; + + // Constants used in specific heat relation + const Real _c1; + const Real _c2; + const Real _c3; + const Real _c4; }; #pragma GCC diagnostic pop diff --git a/modules/solid_properties/include/solidproperties/ThermalGraphiteProperties.h b/modules/solid_properties/include/solidproperties/ThermalGraphiteProperties.h index 3cbf96f87b3f..c836f792b4b4 100644 --- a/modules/solid_properties/include/solidproperties/ThermalGraphiteProperties.h +++ b/modules/solid_properties/include/solidproperties/ThermalGraphiteProperties.h @@ -32,6 +32,8 @@ class ThermalGraphiteProperties : public ThermalSolidProperties virtual void cp_from_T(const Real & T, Real & cp, Real & dcp_dT) const override; + virtual Real cp_integral(const Real & T) const override; + virtual Real rho_from_T(const Real & T) const override; virtual void rho_from_T(const Real & T, Real & rho, Real & drho_dT) const override; @@ -45,6 +47,15 @@ class ThermalGraphiteProperties : public ThermalSolidProperties /// constant density const Real & _rho_const; + + // Constants used in specific heat relation + const Real _c1; + const Real _c2; + const Real _c3; + const Real _c4; + const Real _c5; + const Real _c6; + const Real _c7; }; #pragma GCC diagnostic pop diff --git a/modules/solid_properties/include/solidproperties/ThermalMonolithicSiCProperties.h b/modules/solid_properties/include/solidproperties/ThermalMonolithicSiCProperties.h index d6f46f497734..07f11e59eb15 100644 --- a/modules/solid_properties/include/solidproperties/ThermalMonolithicSiCProperties.h +++ b/modules/solid_properties/include/solidproperties/ThermalMonolithicSiCProperties.h @@ -32,6 +32,8 @@ class ThermalMonolithicSiCProperties : public ThermalSolidProperties virtual void cp_from_T(const Real & T, Real & cp, Real & dcp_dT) const override; + virtual Real cp_integral(const Real & T) const override; + virtual Real rho_from_T(const Real & T) const override; virtual void rho_from_T(const Real & T, Real & rho, Real & drho_dT) const override; @@ -46,6 +48,12 @@ class ThermalMonolithicSiCProperties : public ThermalSolidProperties /// (constant) density const Real & _rho_const; + + // Constants used in specific heat relation + const Real _c1; + const Real _c2; + const Real _c3; + const Real _c4; }; #pragma GCC diagnostic pop diff --git a/modules/solid_properties/include/solidproperties/ThermalSS316Properties.h b/modules/solid_properties/include/solidproperties/ThermalSS316Properties.h index 1b303d8c075c..b09898f9aff4 100644 --- a/modules/solid_properties/include/solidproperties/ThermalSS316Properties.h +++ b/modules/solid_properties/include/solidproperties/ThermalSS316Properties.h @@ -33,9 +33,16 @@ class ThermalSS316Properties : public ThermalSolidProperties virtual void cp_from_T(const Real & T, Real & cp, Real & dcp_dT) const override; + virtual Real cp_integral(const Real & T) const override; + virtual Real rho_from_T(const Real & T) const override; virtual void rho_from_T(const Real & T, Real & rho, Real & drho_dT) const override; + +protected: + // Constants used in specific heat relation + const Real _c1; + const Real _c2; }; #pragma GCC diagnostic pop diff --git a/modules/solid_properties/include/solidproperties/ThermalSolidProperties.h b/modules/solid_properties/include/solidproperties/ThermalSolidProperties.h index a869ddf3e336..979816eaaad4 100644 --- a/modules/solid_properties/include/solidproperties/ThermalSolidProperties.h +++ b/modules/solid_properties/include/solidproperties/ThermalSolidProperties.h @@ -11,10 +11,31 @@ #include "SolidProperties.h" +/** + * Adds default error implementation for non-AD value, which should be overridden in child classes + */ +#define propfuncNonADValueOnly(want) \ + virtual Real want##_from_T(const Real &) const \ + { \ + mooseError(__PRETTY_FUNCTION__, " not implemented."); \ + } + +/** + * Adds default error implementation for non-AD value and derivatives, which should be overridden + * in child classes + */ +#define propfuncNonADDerivatives(want) \ + virtual void want##_from_T(const Real & T, Real & val, Real & d##want##dT) const \ + { \ + solidPropError(__PRETTY_FUNCTION__, " derivatives not implemented."); \ + d##want##dT = 0; \ + val = want##_from_T(T); \ + } + /** * Adds AD versions of each solid property. These functions use the Real versions of these methods * to compute the AD variables complete with derivatives. Typically, these do not need to be - * overriden in derived classes. + * overridden in derived classes. */ #define propfuncAD(want) \ virtual ADReal want##_from_T(const ADReal & T) const \ @@ -27,26 +48,13 @@ ADReal result = x; \ result.derivatives() = T.derivatives() * dxdT; \ return result; \ - } \ - \ -/** \ - * Adds function definitions with not implemented error. These functions should be overriden in \ - * derived classes where required. AD versions are constructed automatically using propfuncAD. \ + } + +/** + * Adds function definitions with not implemented error. These functions should be overridden in + * derived classes where required. AD versions are constructed automatically using propfuncAD. */ -#define propfunc(want) \ - virtual Real want##_from_T(const Real &) const \ - { \ - mooseError(__PRETTY_FUNCTION__, " not implemented."); \ - } \ - \ - virtual void want##_from_T(const Real & T, Real & val, Real & d##want##dT) const \ - { \ - solidPropError(__PRETTY_FUNCTION__, " derivatives not implemented."); \ - d##want##dT = 0; \ - val = want##_from_T(T); \ - } \ - \ - propfuncAD(want) +#define propfunc(want) propfuncNonADValueOnly(want) propfuncNonADDerivatives(want) propfuncAD(want) /** * Common class for solid properties that are a function of temperature @@ -84,6 +92,24 @@ class ThermalSolidProperties : public SolidProperties propfunc(k) propfunc(cp) propfunc(rho) + + /** + * Computes the integral of isobaric specific heat capacity w.r.t. temperature, + * from the zero-e reference temperature, provided by a user parameter. + * + * Note that the constant of integration is not included. This function is + * called in the \c e_from_T(T) method. + */ + virtual Real cp_integral(const Real & /*T*/) const + { + mooseError(__PRETTY_FUNCTION__, " not implemented."); + } + + // Specific internal energy methods; these designed to not be virtual; only + // cp_integral(T) needs to be implemented. + Real e_from_T(const Real & T) const; + void e_from_T(const Real & T, Real & val, Real & dedT) const; + propfuncAD(e) ///@} // clang-format on @@ -101,6 +127,10 @@ class ThermalSolidProperties : public SolidProperties else mooseError(std::forward(args)...); } + +protected: + /// Temperature at which the specific internal energy is assumed to be zero + const Real _T_zero_e; }; #pragma GCC diagnostic pop diff --git a/modules/solid_properties/include/solidproperties/ThermalUCProperties.h b/modules/solid_properties/include/solidproperties/ThermalUCProperties.h index c2aab49774e4..7d6566d96a5f 100644 --- a/modules/solid_properties/include/solidproperties/ThermalUCProperties.h +++ b/modules/solid_properties/include/solidproperties/ThermalUCProperties.h @@ -26,6 +26,9 @@ class ThermalUCProperties : public ThermalSolidProperties virtual Real cp_from_T(const Real & T) const override; virtual void cp_from_T(const Real & T, Real & cp, Real & dcp_dT) const override; + using ThermalSolidProperties::cp_integral; + virtual Real cp_integral(const Real & T) const override; + using ThermalSolidProperties::rho_from_T; virtual Real rho_from_T(const Real & T) const override; virtual void rho_from_T(const Real & T, Real & rho, Real & drho_dT) const override; @@ -33,4 +36,10 @@ class ThermalUCProperties : public ThermalSolidProperties protected: /// (constant) density const Real & _rho_const; + + // Constants used in specific heat relation + const Real _c1; + const Real _c2; + const Real _c3; + const Real _c4; }; diff --git a/modules/solid_properties/src/functormaterials/ThermalSolidPropertiesFunctorMaterial.C b/modules/solid_properties/src/functormaterials/ThermalSolidPropertiesFunctorMaterial.C index dfbf17a5d5dd..15bb218c330a 100644 --- a/modules/solid_properties/src/functormaterials/ThermalSolidPropertiesFunctorMaterial.C +++ b/modules/solid_properties/src/functormaterials/ThermalSolidPropertiesFunctorMaterial.C @@ -19,6 +19,10 @@ ThermalSolidPropertiesFunctorMaterial::validParams() InputParameters params = FunctorMaterial::validParams(); params.addRequiredParam("temperature", "Temperature"); params.addRequiredParam("sp", "The name of the user object for solid properties"); + params.addParam("use_constant_density", false, "Use constant density evaluated at 'T_ref'"); + params.addParam( + "T_ref", + "Temperature at which to evaluate density if 'use_constant_density' is set to 'true'"); params.addParam(SolidPropertiesNames::specific_heat, SolidPropertiesNames::specific_heat, "Name to be used for the isobaric specific heat"); @@ -28,6 +32,9 @@ ThermalSolidPropertiesFunctorMaterial::validParams() params.addParam(SolidPropertiesNames::density, SolidPropertiesNames::density, "Name to be used for the density"); + params.addParam(SolidPropertiesNames::specific_internal_energy, + SolidPropertiesNames::specific_internal_energy, + "Name to be used for the specific internal energy"); params.addClassDescription("Computes solid thermal properties as a function of temperature"); return params; } @@ -38,13 +45,38 @@ ThermalSolidPropertiesFunctorMaterial::ThermalSolidPropertiesFunctorMaterial( _temperature(getFunctor("temperature")), _sp(getUserObject("sp")) { + if (getParam("use_constant_density")) + { + if (isParamValid("T_ref")) + { + const Real T_ref = getParam("T_ref"); + addFunctorProperty(getParam(SolidPropertiesNames::density), + [this, T_ref](const auto & /*r*/, const auto & /*t*/) -> ADReal + { return _sp.rho_from_T(T_ref); }); + } + else + paramError("T_ref", + "The parameter 'T_ref' is required if 'use_constant_density' is set to 'true'."); + } + else + { + if (isParamValid("T_ref")) + paramError("T_ref", + "The parameter 'T_ref' may not be specified if 'use_constant_density' is set to " + "'false'."); + else + addFunctorProperty(getParam(SolidPropertiesNames::density), + [this](const auto & r, const auto & t) -> ADReal + { return _sp.rho_from_T(_temperature(r, t)); }); + } + addFunctorProperty(getParam(SolidPropertiesNames::specific_heat), [this](const auto & r, const auto & t) -> ADReal { return _sp.cp_from_T(_temperature(r, t)); }); addFunctorProperty(getParam(SolidPropertiesNames::thermal_conductivity), [this](const auto & r, const auto & t) -> ADReal { return _sp.k_from_T(_temperature(r, t)); }); - addFunctorProperty(getParam(SolidPropertiesNames::density), + addFunctorProperty(getParam(SolidPropertiesNames::specific_internal_energy), [this](const auto & r, const auto & t) -> ADReal - { return _sp.rho_from_T(_temperature(r, t)); }); + { return _sp.e_from_T(_temperature(r, t)); }); } diff --git a/modules/solid_properties/src/solidproperties/ThermalCompositeSiCProperties.C b/modules/solid_properties/src/solidproperties/ThermalCompositeSiCProperties.C index 0dc30ddbbebc..6350193ef014 100644 --- a/modules/solid_properties/src/solidproperties/ThermalCompositeSiCProperties.C +++ b/modules/solid_properties/src/solidproperties/ThermalCompositeSiCProperties.C @@ -23,21 +23,32 @@ ThermalCompositeSiCProperties::validParams() } ThermalCompositeSiCProperties::ThermalCompositeSiCProperties(const InputParameters & parameters) - : ThermalSolidProperties(parameters), _rho_const(getParam("density")) + : ThermalSolidProperties(parameters), + _rho_const(getParam("density")), + _c1(925.65), + _c2(0.3772), + _c3(7.9259e-5), + _c4(3.1946e7) { } Real ThermalCompositeSiCProperties::cp_from_T(const Real & T) const { - return 925.65 + 0.3772 * T - 7.9259e-5 * Utility::pow<2>(T) - 3.1946e7 / Utility::pow<2>(T); + return _c1 + _c2 * T - _c3 * Utility::pow<2>(T) - _c4 / Utility::pow<2>(T); } void ThermalCompositeSiCProperties::cp_from_T(const Real & T, Real & cp, Real & dcp_dT) const { cp = cp_from_T(T); - dcp_dT = 0.3772 - 1.58518e-4 * T + 6.3892e7 / Utility::pow<3>(T); + dcp_dT = _c2 - 2.0 * _c3 * T + 2.0 * _c4 / Utility::pow<3>(T); +} + +Real +ThermalCompositeSiCProperties::cp_integral(const Real & T) const +{ + return _c1 * T + 0.5 * _c2 * Utility::pow<2>(T) - _c3 / 3.0 * Utility::pow<3>(T) + _c4 / T; } Real diff --git a/modules/solid_properties/src/solidproperties/ThermalGraphiteProperties.C b/modules/solid_properties/src/solidproperties/ThermalGraphiteProperties.C index c5d0d3213c2a..8dc7feb11637 100644 --- a/modules/solid_properties/src/solidproperties/ThermalGraphiteProperties.C +++ b/modules/solid_properties/src/solidproperties/ThermalGraphiteProperties.C @@ -27,7 +27,14 @@ ThermalGraphiteProperties::validParams() ThermalGraphiteProperties::ThermalGraphiteProperties(const InputParameters & parameters) : ThermalSolidProperties(parameters), _grade(getParam("grade").getEnum()), - _rho_const(getParam("density")) + _rho_const(getParam("density")), + _c1(4184.0), + _c2(0.54212), + _c3(2.42667e-6), + _c4(90.2725), + _c5(43449.3), + _c6(1.59309e7), + _c7(1.43688e9) { } @@ -37,8 +44,8 @@ ThermalGraphiteProperties::cp_from_T(const Real & T) const switch (_grade) { case GraphiteGrade::H_451: - return 4184.0 * (0.54212 - 2.42667e-6 * T - 90.2725 / T - 43449.3 / Utility::pow<2>(T) + - 1.59309e7 / Utility::pow<3>(T) - 1.43688e9 / Utility::pow<4>(T)); + return _c1 * (_c2 - _c3 * T - _c4 / T - _c5 / Utility::pow<2>(T) + _c6 / Utility::pow<3>(T) - + _c7 / Utility::pow<4>(T)); default: mooseError("Unhandled GraphiteGrade enum!"); } @@ -53,8 +60,8 @@ ThermalGraphiteProperties::cp_from_T(const Real & T, Real & cp, Real & dcp_dT) c { case GraphiteGrade::H_451: { - dcp_dT = 4184.0 * (-2.42667e-6 + 90.2725 / Utility::pow<2>(T) + 86898.6 / Utility::pow<3>(T) - - 4.77927e7 / Utility::pow<4>(T) + 5.74752e9 / Utility::pow<5>(T)); + dcp_dT = _c1 * (-_c3 + _c4 / Utility::pow<2>(T) + 2.0 * _c5 / Utility::pow<3>(T) - + 3.0 * _c6 / Utility::pow<4>(T) + 4.0 * _c7 / Utility::pow<5>(T)); break; } default: @@ -62,6 +69,21 @@ ThermalGraphiteProperties::cp_from_T(const Real & T, Real & cp, Real & dcp_dT) c } } +Real +ThermalGraphiteProperties::cp_integral(const Real & T) const +{ + switch (_grade) + { + case GraphiteGrade::H_451: + { + return _c1 * (_c2 * T - 0.5 * _c3 * Utility::pow<2>(T) - _c4 * std::log(T) + _c5 / T - + 0.5 * _c6 / Utility::pow<2>(T) + _c7 / (3.0 * Utility::pow<3>(T))); + } + default: + mooseError("Unhandled GraphiteGrade enum!"); + } +} + Real ThermalGraphiteProperties::k_from_T(const Real & T) const { diff --git a/modules/solid_properties/src/solidproperties/ThermalMonolithicSiCProperties.C b/modules/solid_properties/src/solidproperties/ThermalMonolithicSiCProperties.C index f185d0fa9cae..39819003ada9 100644 --- a/modules/solid_properties/src/solidproperties/ThermalMonolithicSiCProperties.C +++ b/modules/solid_properties/src/solidproperties/ThermalMonolithicSiCProperties.C @@ -29,21 +29,31 @@ ThermalMonolithicSiCProperties::validParams() ThermalMonolithicSiCProperties::ThermalMonolithicSiCProperties(const InputParameters & parameters) : ThermalSolidProperties(parameters), _k_model(getParam("thermal_conductivity_model").getEnum()), - _rho_const(getParam("density")) + _rho_const(getParam("density")), + _c1(925.65), + _c2(0.3772), + _c3(7.9259e-5), + _c4(3.1946e7) { } Real ThermalMonolithicSiCProperties::cp_from_T(const Real & T) const { - return 925.65 + 0.3772 * T - 7.9259e-5 * Utility::pow<2>(T) - 3.1946e7 / Utility::pow<2>(T); + return _c1 + _c2 * T - _c3 * Utility::pow<2>(T) - _c4 / Utility::pow<2>(T); } void ThermalMonolithicSiCProperties::cp_from_T(const Real & T, Real & cp, Real & dcp_dT) const { cp = cp_from_T(T); - dcp_dT = 0.3772 - 1.58518e-4 * T + 6.3892e7 / Utility::pow<3>(T); + dcp_dT = _c2 - 2 * _c3 * T + 2 * _c4 / Utility::pow<3>(T); +} + +Real +ThermalMonolithicSiCProperties::cp_integral(const Real & T) const +{ + return _c1 * T + 0.5 * _c2 * Utility::pow<2>(T) - _c3 / 3.0 * Utility::pow<3>(T) + _c4 / T; } Real diff --git a/modules/solid_properties/src/solidproperties/ThermalSS316Properties.C b/modules/solid_properties/src/solidproperties/ThermalSS316Properties.C index caf8e3b0dea0..063e61b59b4c 100644 --- a/modules/solid_properties/src/solidproperties/ThermalSS316Properties.C +++ b/modules/solid_properties/src/solidproperties/ThermalSS316Properties.C @@ -21,21 +21,27 @@ ThermalSS316Properties::validParams() } ThermalSS316Properties::ThermalSS316Properties(const InputParameters & parameters) - : ThermalSolidProperties(parameters) + : ThermalSolidProperties(parameters), _c1(0.1816), _c2(428.46) { } Real ThermalSS316Properties::cp_from_T(const Real & T) const { - return 0.1816 * T + 428.46; + return _c1 * T + _c2; } void ThermalSS316Properties::cp_from_T(const Real & T, Real & cp, Real & dcp_dT) const { cp = cp_from_T(T); - dcp_dT = 0.1816; + dcp_dT = _c1; +} + +Real +ThermalSS316Properties::cp_integral(const Real & T) const +{ + return 0.5 * _c1 * T * T + _c2 * T; } Real diff --git a/modules/solid_properties/src/solidproperties/ThermalSolidProperties.C b/modules/solid_properties/src/solidproperties/ThermalSolidProperties.C index b9202cb0938b..4cf1878055c3 100644 --- a/modules/solid_properties/src/solidproperties/ThermalSolidProperties.C +++ b/modules/solid_properties/src/solidproperties/ThermalSolidProperties.C @@ -13,10 +13,30 @@ InputParameters ThermalSolidProperties::validParams() { InputParameters params = SolidProperties::validParams(); + + // There does not seem to be a conventional reference temperature, so STP was chosen. + params.addParam( + "T_zero_e", + 273.15, + "Temperature at which the specific internal energy is assumed to be zero [K]."); + return params; } ThermalSolidProperties::ThermalSolidProperties(const InputParameters & parameters) - : SolidProperties(parameters) + : SolidProperties(parameters), _T_zero_e(getParam("T_zero_e")) +{ +} + +Real +ThermalSolidProperties::e_from_T(const Real & T) const +{ + return cp_integral(T) - cp_integral(_T_zero_e); +} + +void +ThermalSolidProperties::e_from_T(const Real & T, Real & e, Real & de_dT) const { + e = e_from_T(T); + de_dT = cp_from_T(T); } diff --git a/modules/solid_properties/src/solidproperties/ThermalUCProperties.C b/modules/solid_properties/src/solidproperties/ThermalUCProperties.C index 2b40bb025155..a6214b9d9964 100644 --- a/modules/solid_properties/src/solidproperties/ThermalUCProperties.C +++ b/modules/solid_properties/src/solidproperties/ThermalUCProperties.C @@ -24,7 +24,12 @@ ThermalUCProperties::validParams() } ThermalUCProperties::ThermalUCProperties(const InputParameters & parameters) - : ThermalSolidProperties(parameters), _rho_const(getParam("density")) + : ThermalSolidProperties(parameters), + _rho_const(getParam("density")), + _c1(239.7), + _c2(5.068e-3), + _c3(1.7604e-5), + _c4(3488100) { } @@ -34,7 +39,7 @@ ThermalUCProperties::cp_from_T(const Real & T) const if ((T < 298) || (T > 2838)) flagInvalidSolution( "UC specific heat evaluated outside of UC cp temperature range [298, 2838] K"); - return 239.7 - 5.068e-3 * T + 1.7604e-5 * Utility::pow<2>(T) - 3488100 / Utility::pow<2>(T); + return _c1 - _c2 * T + _c3 * Utility::pow<2>(T) - _c4 / Utility::pow<2>(T); } void @@ -46,7 +51,13 @@ ThermalUCProperties::cp_from_T(const Real & T, Real & cp, Real & dcp_dT) const "UC specific heat evaluated outside of UC cp temperature range [298, 2838] K"); cp = cp_from_T(T); - dcp_dT = -5.068e-3 + 3.5208e-5 * T + 6976200 / Utility::pow<3>(T); + dcp_dT = -_c2 + 2 * _c3 * T + 2 * _c4 / Utility::pow<3>(T); +} + +Real +ThermalUCProperties::cp_integral(const Real & T) const +{ + return _c1 * T - 0.5 * _c2 * Utility::pow<2>(T) + _c3 / 3.0 * Utility::pow<3>(T) + _c4 / T; } Real diff --git a/modules/solid_properties/test/include/utils/SolidPropertiesTestUtils.h b/modules/solid_properties/test/include/utils/SolidPropertiesTestUtils.h index 9f2e29cc1d38..74196ce30cf3 100644 --- a/modules/solid_properties/test/include/utils/SolidPropertiesTestUtils.h +++ b/modules/solid_properties/test/include/utils/SolidPropertiesTestUtils.h @@ -55,3 +55,15 @@ { \ DERIV_TEST_CUSTOM_PERTURBATION(f, a, tol, REL_PERTURBATION); \ } + +// Macro for testing that the definition of the derivative of specific internal energy is +// consistent with the definition of the isobaric specific heat capacity +#define SPECIFIC_INTERNAL_ENERGY_TESTS(sp, T, dT, rel_tol) \ + { \ + const Real de_dT_fd = (sp->e_from_T(T + dT) - sp->e_from_T(T - dT)) / (2 * dT); \ + Real e, de_dT; \ + sp->e_from_T(T, e, de_dT); \ + REL_TEST(e, sp->e_from_T(T), REL_TOL_CONSISTENCY); \ + REL_TEST(de_dT, de_dT_fd, rel_tol); \ + REL_TEST(sp->cp_from_T(T), de_dT, rel_tol); \ + } diff --git a/modules/solid_properties/test/tests/materials/thermal_solid_functor_properties/test.i b/modules/solid_properties/test/tests/materials/thermal_solid_functor_properties/base.i similarity index 76% rename from modules/solid_properties/test/tests/materials/thermal_solid_functor_properties/test.i rename to modules/solid_properties/test/tests/materials/thermal_solid_functor_properties/base.i index d0ac3c7a6b55..67f7d99cc0ca 100644 --- a/modules/solid_properties/test/tests/materials/thermal_solid_functor_properties/test.i +++ b/modules/solid_properties/test/tests/materials/thermal_solid_functor_properties/base.i @@ -18,7 +18,7 @@ T_initial = 300 [] [] -[Materials] +[FunctorMaterials] [sp_mat] type = ThermalSolidPropertiesFunctorMaterial temperature = T @@ -26,6 +26,7 @@ T_initial = 300 specific_heat = cp density = rho thermal_conductivity = k + specific_internal_energy = e [] [] @@ -46,17 +47,21 @@ T_initial = 300 [Postprocessors] [cp] - type = ElementIntegralFunctorPostprocessor + type = ElementExtremeFunctorValue functor = 'cp' [] [k] - type = ElementIntegralFunctorPostprocessor + type = ElementExtremeFunctorValue functor = 'k' [] [density] - type = ElementIntegralFunctorPostprocessor + type = ElementExtremeFunctorValue functor = 'rho' [] + [e] + type = ElementExtremeFunctorValue + functor = 'e' + [] [] [Problem] diff --git a/modules/solid_properties/test/tests/materials/thermal_solid_functor_properties/constant_density.i b/modules/solid_properties/test/tests/materials/thermal_solid_functor_properties/constant_density.i new file mode 100644 index 000000000000..509cfea1a58a --- /dev/null +++ b/modules/solid_properties/test/tests/materials/thermal_solid_functor_properties/constant_density.i @@ -0,0 +1,12 @@ +!include base.i + +[FunctorMaterials] + [sp_mat] + use_constant_density = True + T_ref = 500 + [] +[] + +[Outputs] + file_base = constant_density +[] diff --git a/modules/solid_properties/test/tests/materials/thermal_solid_functor_properties/error_no_T_ref.i b/modules/solid_properties/test/tests/materials/thermal_solid_functor_properties/error_no_T_ref.i new file mode 100644 index 000000000000..99aca34f4a41 --- /dev/null +++ b/modules/solid_properties/test/tests/materials/thermal_solid_functor_properties/error_no_T_ref.i @@ -0,0 +1,7 @@ +!include base.i + +[FunctorMaterials] + [sp_mat] + use_constant_density = True + [] +[] diff --git a/modules/solid_properties/test/tests/materials/thermal_solid_functor_properties/error_provided_T_ref.i b/modules/solid_properties/test/tests/materials/thermal_solid_functor_properties/error_provided_T_ref.i new file mode 100644 index 000000000000..e7b876a38c70 --- /dev/null +++ b/modules/solid_properties/test/tests/materials/thermal_solid_functor_properties/error_provided_T_ref.i @@ -0,0 +1,7 @@ +!include base.i + +[FunctorMaterials] + [sp_mat] + T_ref = 500 + [] +[] diff --git a/modules/solid_properties/test/tests/materials/thermal_solid_functor_properties/gold/constant_density.csv b/modules/solid_properties/test/tests/materials/thermal_solid_functor_properties/gold/constant_density.csv new file mode 100644 index 000000000000..a758559a6161 --- /dev/null +++ b/modules/solid_properties/test/tests/materials/thermal_solid_functor_properties/gold/constant_density.csv @@ -0,0 +1,2 @@ +time,cp,density,e,k +0,482.94,7863.415,12901.479237,13.79891 diff --git a/modules/solid_properties/test/tests/materials/thermal_solid_functor_properties/gold/test_out.csv b/modules/solid_properties/test/tests/materials/thermal_solid_functor_properties/gold/test_out.csv deleted file mode 100644 index bacea3c59fb1..000000000000 --- a/modules/solid_properties/test/tests/materials/thermal_solid_functor_properties/gold/test_out.csv +++ /dev/null @@ -1,2 +0,0 @@ -time,cp,density,k -0,482.94,7956.4814,13.79891 diff --git a/modules/solid_properties/test/tests/materials/thermal_solid_functor_properties/gold/variable_density.csv b/modules/solid_properties/test/tests/materials/thermal_solid_functor_properties/gold/variable_density.csv new file mode 100644 index 000000000000..47ece37e8da9 --- /dev/null +++ b/modules/solid_properties/test/tests/materials/thermal_solid_functor_properties/gold/variable_density.csv @@ -0,0 +1,2 @@ +time,cp,density,e,k +0,482.94,7956.4814,12901.479237,13.79891 diff --git a/modules/solid_properties/test/tests/materials/thermal_solid_functor_properties/tests b/modules/solid_properties/test/tests/materials/thermal_solid_functor_properties/tests index 3e54bce5d69b..213c8a0a6f28 100644 --- a/modules/solid_properties/test/tests/materials/thermal_solid_functor_properties/tests +++ b/modules/solid_properties/test/tests/materials/thermal_solid_functor_properties/tests @@ -1,11 +1,31 @@ [Tests] + design = 'ThermalSolidPropertiesFunctorMaterial.md' + issues = '#21978' [test] - type = CSVDiff - input = 'test.i' - csvdiff = 'test_out.csv' - requirement = "The system shall provide the ability to use functors for solid material " - "properties." - design = 'ThermalSolidPropertiesFunctorMaterial.md' - issues = '#21978' + requirement = "The system shall provide the ability to use functors for solid material properties" + [variable_density] + type = CSVDiff + input = 'variable_density.i' + csvdiff = 'variable_density.csv' + detail = "with a temperature-dependent density." + [] + [constant_density] + type = CSVDiff + input = 'constant_density.i' + csvdiff = 'constant_density.csv' + detail = "with a constant density." + [] + [error_no_T_ref] + type = RunException + input = 'error_no_T_ref.i' + expect_err = "The parameter 'T_ref' is required if 'use_constant_density' is set to 'true'" + detail = "and report an error if no reference temperature is supplied for a constant density." + [] + [error_provided_T_ref] + type = RunException + input = 'error_provided_T_ref.i' + expect_err = "The parameter 'T_ref' may not be specified if 'use_constant_density' is set to 'false'" + detail = "and report an error if a reference temperature is supplied for a variable density." + [] [] [] diff --git a/modules/solid_properties/test/tests/materials/thermal_solid_functor_properties/variable_density.i b/modules/solid_properties/test/tests/materials/thermal_solid_functor_properties/variable_density.i new file mode 100644 index 000000000000..e4f7d14b36c9 --- /dev/null +++ b/modules/solid_properties/test/tests/materials/thermal_solid_functor_properties/variable_density.i @@ -0,0 +1,5 @@ +!include base.i + +[Outputs] + file_base = variable_density +[] diff --git a/modules/solid_properties/unit/src/ThermalCompositeSiCPropertiesTest.C b/modules/solid_properties/unit/src/ThermalCompositeSiCPropertiesTest.C index 56ccba3cc724..cccc10bed764 100644 --- a/modules/solid_properties/unit/src/ThermalCompositeSiCPropertiesTest.C +++ b/modules/solid_properties/unit/src/ThermalCompositeSiCPropertiesTest.C @@ -44,6 +44,17 @@ TEST_F(ThermalCompositeSiCPropertiesTest, cp) DERIV_TEST(_sp1->cp_from_T, T, REL_TOL_DERIVATIVE); } +/** + * Test that the specific internal energy and its derivatives are + * correctly computed. + */ +TEST_F(ThermalCompositeSiCPropertiesTest, e) +{ + const Real T = 800.0; + REL_TEST(_sp1->e_from_T(T), 504301.09074042423, REL_TOL_SAVED_VALUE); + SPECIFIC_INTERNAL_ENERGY_TESTS(_sp1, T, 1e-6, 1e-6); +} + /** * Test that the density and its derivatives are * correctly computed. diff --git a/modules/solid_properties/unit/src/ThermalGraphitePropertiesTest.C b/modules/solid_properties/unit/src/ThermalGraphitePropertiesTest.C index 8093368a1d8c..5af251c0b99d 100644 --- a/modules/solid_properties/unit/src/ThermalGraphitePropertiesTest.C +++ b/modules/solid_properties/unit/src/ThermalGraphitePropertiesTest.C @@ -44,6 +44,17 @@ TEST_F(ThermalGraphitePropertiesTest, cp) DERIV_TEST(_sp1->cp_from_T, T, REL_TOL_DERIVATIVE); } +/** + * Test that the specific internal energy and its derivatives are + * correctly computed. + */ +TEST_F(ThermalGraphitePropertiesTest, e) +{ + const Real T = 800.0; + REL_TEST(_sp1->e_from_T(T), 648167.7112224712, REL_TOL_SAVED_VALUE); + SPECIFIC_INTERNAL_ENERGY_TESTS(_sp1, T, 1e-6, 1e-6); +} + /** * Test that the density and its derivatives are * correctly computed. diff --git a/modules/solid_properties/unit/src/ThermalMonolithicSiCPropertiesTest.C b/modules/solid_properties/unit/src/ThermalMonolithicSiCPropertiesTest.C index e3190d842c9e..626a2a9cff68 100644 --- a/modules/solid_properties/unit/src/ThermalMonolithicSiCPropertiesTest.C +++ b/modules/solid_properties/unit/src/ThermalMonolithicSiCPropertiesTest.C @@ -54,6 +54,17 @@ TEST_F(ThermalMonolithicSiCPropertiesTest, cp) DERIV_TEST(_sp1->cp_from_T, T, REL_TOL_DERIVATIVE); } +/** + * Test that the specific internal energy and its derivatives are + * correctly computed. + */ +TEST_F(ThermalMonolithicSiCPropertiesTest, e) +{ + const Real T = 800.0; + REL_TEST(_sp1->e_from_T(T), 504301.09074042423, REL_TOL_SAVED_VALUE); + SPECIFIC_INTERNAL_ENERGY_TESTS(_sp1, T, 1e-6, 1e-6); +} + /** * Test that the density and its derivatives are * correctly computed. diff --git a/modules/solid_properties/unit/src/ThermalSS316PropertiesTest.C b/modules/solid_properties/unit/src/ThermalSS316PropertiesTest.C index 95bb84284107..193d563a974c 100644 --- a/modules/solid_properties/unit/src/ThermalSS316PropertiesTest.C +++ b/modules/solid_properties/unit/src/ThermalSS316PropertiesTest.C @@ -44,6 +44,17 @@ TEST_F(ThermalSS316PropertiesTest, cp) DERIV_TEST(_sp->cp_from_T, T, REL_TOL_DERIVATIVE); } +/** + * Test that the specific internal energy and its derivatives are + * correctly computed. + */ +TEST_F(ThermalSS316PropertiesTest, e) +{ + const Real T = 800.0; + REL_TEST(_sp->e_from_T(T), 277071.479237, REL_TOL_SAVED_VALUE); + SPECIFIC_INTERNAL_ENERGY_TESTS(_sp, T, 1e-6, 1e-6); +} + /** * Test that the density and its derivatives are * correctly computed. diff --git a/modules/solid_properties/unit/src/ThermalUCPropertiesTest.C b/modules/solid_properties/unit/src/ThermalUCPropertiesTest.C index 851e745cd2b6..01201953d7b7 100644 --- a/modules/solid_properties/unit/src/ThermalUCPropertiesTest.C +++ b/modules/solid_properties/unit/src/ThermalUCPropertiesTest.C @@ -44,6 +44,17 @@ TEST_F(ThermalUCPropertiesTest, cp) DERIV_TEST(_sp1->cp_from_T, T, REL_TOL_DERIVATIVE); } +/** + * Test that the specific internal energy and its derivatives are + * correctly computed. + */ +TEST_F(ThermalUCPropertiesTest, e) +{ + const Real T = 800.0; + REL_TEST(_sp1->e_from_T(T), 119328.29374852851, REL_TOL_SAVED_VALUE); + SPECIFIC_INTERNAL_ENERGY_TESTS(_sp1, T, 1e-6, 1e-6); +} + /** * Test that the density and its derivatives are * correctly computed.