# SPECIFIC_HEAT_MODEL

Specifies a specific heat at constant pressure model.

AcuSolve Command

## Syntax

SPECIFIC_HEAT_SOURCE("name") {parameters...}

User-given name.

## Parameters

type (enumerated) [=none]
Type of the specific heat model.
constant or const
Constant specific heat. Requires specific_heat.
piecewise_linear_enthalpy
Piecewise linear curve fit for enthalpy. Requires curve_fit_values and curve_fit_variable.
piecewise_polynomial_enthalpy
Piecewise polynomial curve fit for enthalpy. Requires piecewise_polynomial_values and piecewise_polynomial variables.
piecewise_bilinear_enthalpy
Piecewise bilinear curve fit for enthalpy. Requires bilinear_curve_fit_values, bilinear_curve_fit_row_variable and bilinear_curve_fit_column_variable.
cubic_spline_enthalpy
Cubic spline curve fit for enthalpy. Requires curve_fit_values and curve_fit_variable.
user_function_enthalpy
User-defined function for enthalpy. Requires user_function, user_values and user_strings.
specific_heat or cp (real) >0 [=1]
Constant value of the specific heat. Used with constant type.
curve_fit_values or curve_values (array) [={0,1}]
A two-column array of independent-variable/enthalpy data values. Used with piecewise_linear_enthalpy and cubic_spline_enthalpy types.
curve_fit_variable or curve_var (enumerated) [=temperature]
Independent variable of the curve fit. Used with piecewise_linear_enthalpy and cubic_spline_enthalpy types.
temperature or temp
Temperature.
piecewise_polynomial_values (array) [={}]
Array of values to specify a piecewise polynomial equation. Used with piecewise_polynomial_enthalpy type.
piecewise_polynomial_variable (enumerated) [=temperature]
Independent variable of the piecewise polynomial curve fit. Used with piecewise_polynomial_enthalpy type.
bilinear_curve_fit_values (array) [={}]
Array of values to specify a piecewise polynomial equation. Used with piecewise_bilinear_enthalpy type.
bilinear_curve_fit_row_variable (enumerated) [=temperature]
Independent variable of the rows of the bilinear curve fit table. Used with piecewise_bilinear_enthalpy type.
bilinear_curve_fit_column_variable (enumerated) [no default]
Independent variable of the columns of the bilinear curve fit table. Variable can be either pressure or species. Used with piecewise_bilinear_enthalpy type.
user_function or user
User-defined function. Requires user_function, user_values and user_strings.
user_values (array) [={}]
Array of values to be passed to the user-defined function. Used with user_function_enthalpy type.
user_strings (list) [={}]
Array of strings to be passed to the user-defined function. Used with user_function_enthalpy type.
latent_heat_type (enumerated) [=none]
Type of the latent heat.
none
No latent heat present.
constant or const
Constant latent heat. Requires latent_heat, latent_heat_temperature and latent_heat_temperature_interval.
latent_heat (real) [=0]
Constant value of latent heat. Used with constant latent heat type.
latent_heat_temperature (real) [=0]
Temperature at which the latent heat is released. Used with constant latent heat type.
latent_heat_temperature_interval (real) >=0 [=0]
Temperature interval over which the latent heat takes effect. Also referred to as the mushy interval. Used with constant latent heat type.

## Description

This command specifies a specific heat model for the energy equation. This model is applicable to fluid, solid, and shell element sets.

SPECIFIC_HEAT_MODEL commands are referenced by MATERIAL_MODEL commands, which in turn are referenced by ELEMENT_SET commands:
SPECIFIC_HEAT_MODEL( "my cp model" ) {
type                                = constant
specific_heat                       = 1005
}
MATERIAL_MODEL( "my material model" ) {
specific_heat_model                 = "my cp model"
...
}
ELEMENT_SET( "fluid elements" ) {
material_model                      = "my material model"
...
}

A constant specific heat model uses a constant value for the entire element set, as in the above example.

When specific heat is not constant, piecewise linear specific heat models of types piecewise_linear_enthalpy or cubic_spline_enthalpy can be used to define enthalpy (or specific enthalpy) as a function of temperature. Enthalpy is given by:(1)
${h}_{2}={h}_{1}+{\int }_{{T}_{1}}^{{T}_{2}}{C}_{p}\left(T\right)\text{\hspace{0.17em}}dT$

where $T$ is temperature, ${C}_{p}$ is specific heat capacity and $h$ is specific enthalpy.

When specific heat does not vary with respect to temperature, it is often useful to treat it as constant. If so,(2)
${h}_{2}={h}_{1}+{C}_{p}\left({T}_{2}-{T}_{1}\right)$
In cases where the specific heat is a function of temperature, the integral above can be numerically evaluated. One possible integration scheme is the trapezoidal rule:(3)
${h}_{2}={h}_{1}+\frac{\left({C}_{p1}+{C}_{p2}\right)}{2}\left({T}_{2}-{T}_{1}\right)$
Note: This integration (irrespective of the method use) must be performed prior to the CFD calculation as AcuSolve does not currently offer any capabilities in this regard.

The curve_fit_values is a two-column array corresponding to the independent variable (temperature in this case) and enthalpy. The independent variable values must be in ascending order. The limit point values of the curve fit are used when curve_fit_variable falls outside of the curve fit limits.

The curve_fit_values data may be read from a file. For the above example, the curve fit values may be placed in a file, say enthalpy.fit, and read by:
SPECIFIC_HEAT_MODEL( "ice" ) {
type                  = piecewise_linear_enthalpy
curve_fit_variable    = temperature
}
The piecewise_polynomial_enthalpy type is used to specify the high-order multiple polynomial temperature functions for specific heat capacity in different temperature ranges. For example,(4)
${c}_{p1}={a}_{6}\text{​}\text{​}\text{​}{T}^{5}+\text{\hspace{0.17em}}{a}_{5}\text{​}\text{​}\text{​}{T}^{4}+\text{\hspace{0.17em}}{a}_{4}\text{​}\text{​}\text{​}{T}^{3}+\text{\hspace{0.17em}}{a}_{3}\text{​}\text{​}\text{​}{T}^{2}+{a}_{2}\text{​}\text{​}\text{​}T+{a}_{1}$
for (5)
${T}_{a_\mathrm{min}}<\text{​}\text{​}\text{​}T<{T}_{a_\mathrm{max}}$
(6)
${c}_{p2}={b}_{5}\text{​}\text{​}\text{​}{T}^{4}+\text{\hspace{0.17em}}{b}_{4}\text{​}\text{​}\text{​}{T}^{3}+\text{\hspace{0.17em}}{b}_{3}\text{​}\text{​}\text{​}{T}^{2}+{b}_{2}\text{​}\text{​}\text{​}T+{b}_{1}$
for (7)
${T}_{b_\mathrm{min}}<\text{​}\text{​}\text{​}T<{T}_{b_\mathrm{max}}$
SPECIFIC_HEAT_MODEL( "H" ) {
type                                        = piecewise_polynomial_enthalpy
piecewise_polynomial_variable               = temperature
piecewise_polynomial_values                 = {
Ta_min, Ta_max, a1, a2, a3, a4, a5, a6;
Tb_min, Tb_max, b1, b2, b3, b4,  b5}
}

The first entry of piecewise_polynomial_values is the minimum temperature, followed by the maximum temperature to indicate the applicable temperature range. Next, the polynomial coefficients are entered to define the first polynomial equation. The second set of piecewise_polynomial_values is separated with the semi-colon. The order of polynomial coefficient in piecewise_polynomial_values is from lower to higher.

A piecewise_bilinear_enthalpy type defines a piecewise bilinear curve fit as a function of two independent variables. bilinear_curve_fit_row_variable and bilinear_curve_fit_column_variable define the two independent variables.

The format of the interpolation table is as follows:
bilinear_curve_fit_data =
{   0,         cVal1,    cVal2,    cVal3,    ... ;
Temperature 1, h(T1,c1), h(T1,c2), h(T1,c3), ... ;
Temperature 2, h(T2,c1), h(T2,c2), h(T2,c3), ... ;
Temperature 3, h(T3,c1), h(T3,c2), h(T3,c3), ... ;
...,           ...,      ...,      ... ,     ... ;
}

The first entry in the table must be 0, then followed by the values of the column independent variable. The first entry of each row must be the temperature value followed by the corresponding enthalpy. The row entries are comma separated with the semi-colon separating each of the rows.

A specific heat of type user_function_enthalpy may be used to model more complex behaviors; see the AcuSolve User-Defined Functions Manual for a detailed description of user-defined functions.

For example, consider a version of the piecewise linear latent heat model discussed above. The model below improves on this one by adding two "buffer" regions on either side of the latent heat transition. These are used to smooth the transition and make the specific heat continuous with temperature. Unlike for the curve fit types AcuSolve has no way of calculating the specific heat from the enthalpy, so both must be supplied by the user defined function. The specific heat is needed to form the appropriate contribution to the left-hand side matrix. An error is issued if it is not returned. Only Jacobians with respect to temperature are supported currently. The enthalpy may also be a function of pressure and species, but extreme caution must be taken since Jacobians with respect to these variables are not supported. The input command may be given by:
SPECIFIC_HEAT_MODEL( "UDF ice" ) {
type                = user_function_enthalpy
user_function       = "usrSpecHeat"
user_values          = { 3000,         # reference density
3.33e5,    # reference temperature
273,         # expansivity
2 }        # temperature interval
}
where the user-defined function "usrSpecHeat" may be implemented as follows:
#include "acusim.h"
#include "udf.h"
UDF_PROTOTYPE( usrSpecHeat ) ;                                        /* function prototype               */
Void usrSpecHeat (
UdfHd                 udfHd,                                     /* Opaque handle for accessing data */
Real*                 outVec,                                    /* Output vector                    */
Integer               nItems,                                    /* Number of elements               */
Integer               vecDim                                     /* = 1                              */
) {
Integer               elem ;                                     /* element index                    */
Real                  cp0 ;                                      /* specific heat                    */
Real                  delTemp ;                                  /* temperature interval             */
Real                  dt2 ;                                      /* delTemp / 2                      */
Real                  enpy ;                                     /* partial enthalpy                 */
Real                  latentHeat ;                               /* latent heat                      */
Real                  lh2 ;                                      /* latent heat / 2                  */
Real                  lh4 ;                                      /* latent heat / 4                  */
Real                  lhDt ;                                     /* latent heat /delTemp             */
Real                  refTemp ;                                  /* reference temperature            */
Real                  tmp ;                                      /* a temporary temperature          */
Real*                 temp ;                                     /* a temperature                    */
Real*                 cp ;                                       /* specific heat                    */
Real*                 usrVals ;                                  /* user supplied values             */

udfCheckNumUsrVals( udfHd, 4 ) ;                                     /* check for error                  */
usrVals               = udfGetUsrVals( udfHd ) ;
cp0                   = usrVals[0] ;
latentheat            = usrVals[1] ;
refTemp               = usrVals[2] ;
delTemp               = usrVals[3] ;
if ( delTemp <= 0 ) {
udfSetError( udfHd,
"temperature interval <%g> is not positive", delTemp ) ;
}
dt2                   = delTemp / 2 ;
lh2                   = latentHeat / 2 ;
lh4                   = latentHeat / 4 ;
lhDt                  = latentHeat / delTemp ;
temp                  = udfGetElmData( udfHd, UDF_ELM_TEMPERATURE ) ;

/* Jacobian of enthalpy with respect to temp (same as specific heat) */
cp      = udfGetElmJac( udfHd, UDF_ELM_JAC_TEMPERATURE ) ;
for ( elem = 0 ; elem < nItems ; elem++ ) {
tmp               = (temp[elem] - refTemp) / dt2 ;
if ( tmp < -1.5 ) tmp = -1.5 ;
if ( tmp > +1.5 ) tmp = +1.5 ;
if ( tmp < -0.5 ) {
tmp           = 1.5 + tmp ;
enpy          = cp0 * temp[elem] + lh4 * tmp * tmp ;
cp[elem]      = cp0 + lhDt * tmp ;
} else if ( tmp <= 0.5 ) {
tmp           = 0.5 + tmp ;
enpy          = cp0 * temp[elem] + lh2 * tmp + lh4 ;
cp[elem]      = cp0 + lhDt ;
} else {
tmp           = 1.5 - tmp ;
enpy          = cp0 * temp[elem] + latentHeat - lh4 * tmp * tmp ;
cp[elem]      = cp0 + lhDt * tmp ;
}
outVec[elem]      = enpy ;
}
} /* end of usrSpecHeat() */

The dimensions of the returned enthalpy vector, outVec, and the Jacobian vector, cp, are the number of elements.

A latent heat of formation may be added directly to any specific heat model. For example,
SPECIFIC_HEAT_MODEL( "ice" ) {
type                               = constant
specific_heat                      = 3000
latent_heat_type                   = constant
latent_heat                        = 3.33e5
latent_heat_temperature            = 273
latent_heat_temperature_interval   = 2
}

Here, a constant specific heat of 3000 is used except at a temperature of 273, where the enthalpy is increased by 3.33x105. The jump in enthalpy is spread over two degrees, centered at 273. This example models the same material as the piecewise_linear_enthalpy type example above. One advantage of using the latent heat parameters is that a more stable transition form is internally implemented for the jump in the enthalpy. This form uses extra buffer regions like in the user-defined function above.