# Heating models
The heating model is responsible for describing the various terms in the
energy equation {math:numref}`eq:temperature`, using the coefficients provided
by the material model. These can be source terms such as radiogenic heat
production or shear heating, they can be terms on the left-hand side of the
equation, such as part of the latent heating terms, or they can be heating
processes related to reactions. Each of these terms is described by a
"heating model," and a simulation can have none, one, or many
heating models that are active throughout a simulation, with each heating
model usually only implementing the terms for one specific heating process.
One can then decide in the input file which heating processes should be
included in the computation by providing a list of heating models in the input
file.
When the equations are assembled and solved, the heating terms from all
heating models used in the computation are added up.
To implement a new heating model, you need to overload the
[aspect::HeatingModel::Interface](https://aspect.geodynamics.org/doc/doxygen/namespaceaspect_1_1HeatingModel.html)
class and use the `ASPECT_REGISTER_HEATING_MODEL` macro to register your new class. The
implementation of the new class should be in namespace `aspect::HeatingModel`.
Specifically, your new class needs to implement the following basic interface:
```{code-block} c++
template
class aspect::HeatingModel::Interface
{
public:
// compute heating terms used in the energy equation
virtual
void
evaluate (const MaterialModel::MaterialModelInputs &material_model_inputs,
const MaterialModel::MaterialModelOutputs &material_model_outputs,
HeatingModel::HeatingModelOutputs &heating_model_outputs) const;
// All the following functions are optional:
virtual
void
initialize ();
virtual
void
update ();
// Functions used in dealing with run-time parameters
static
void
declare_parameters (ParameterHandler &prm);
virtual
void
parse_parameters (ParameterHandler &prm);
// Allow the heating model to attach additional material model outputs in case it needs
// them to compute the heating terms
virtual
void
create_additional_material_model_outputs(MaterialModel::MaterialModelOutputs &) const;
};
```
The main properties of the material are computed in the function `evaluate()`
that takes references to `MaterialModelInputs` and `MaterialModelOutputs`
objects and is supposed to fill the `HeatingModelOutputs` structure. As in the
material model, this function is handling lookups at an arbitrary number of
positions, so for each heating term (for example the heating source terms), a
`std::vector` is returned. The following members of `HeatingModelOutputs` need
to be filled:
```{code-block} c++
struct HeatingModelOutputs
{
std::vector heating_source_terms;
std::vector lhs_latent_heat_terms;
// optional:
std::vector rates_of_temperature_change;
}
```
Heating source terms are terms on the right-hand side of the equations, such
as the adiabatic heating $\alpha T \left( \mathbf u \cdot \nabla p \right)$ in
equation {math:numref}`eq:temperature`. An example for a left-hand side heating term
is the temperature-derivative term
$\rho T \Delta S \frac{\partial X}{\partial T}$ that is part of latent heat
production (see equation {math:numref}`eq:temperature-reformulated`).[^footnote1] Rates of
temperature change[^footnote2] are used when the heating term is related to a reaction
process, happening on a faster time scale than the temperature advection. All
of these terms can depend on any of the material model inputs or outputs.
Implementations of `evaluate()` may of course choose to ignore dependencies on
any of these arguments.
The remaining functions are used in postprocessing as well as handling
run-time parameters. The exact meaning of these member functions is documented
in the [aspect::HeatingModel::Interface](https://aspect.geodynamics.org/doc/doxygen/namespaceaspect_1_1HeatingModel.html)
class documentation. Note that some of the
functions listed above have a default implementation, as discussed on the
documentation page just mentioned.
Just like for material models, the functions `initialize()` and `update()` can
be implemented if desired (the default implementation does nothing) and are
useful if the heating model has an internal state. The function `initialize()`
is called once during the initialization of
ASPECT and can be used to allocate memory for the
heating model, initialize state, or read information from an external file.
The function `update()` is called at the beginning of every time step.
[^footnote1]: Whether a term should go on the left or right hand side of the equation is, in some sense, a choice one can make. Putting
a term onto the right hand side makes it an explicit term as far as time stepping is concerned, and so may imply a time step
restriction if its dynamics are too fast. On the other hand, it does not introduce a nonlinearity if it depends on more than just
a multiple of the temperature (such as the term $\alpha T\left( \textbf{u}\cdot \nabla p\right)$). In practice, whether one wants to put a specific term on one side
or the other may be a judgment call based on experience with numerical methods.
[^footnote2]: Or, more correctly: Rates of *thermal energy change*