# Using Cantera from C++

One of the main reasons to use the Cantera C++ interface directly is to be able to
couple it with a higher-level simulation code, where Cantera is used to calculate
thermodynamic properties, reaction rates, and transport properties for the host code.
This tutorial demonstrates how to initialize Cantera objects from
[YAML input files](/userguide/input-tutorial) and use those objects to calculate
properties for mixtures with different thermodynamic states.

## A very simple C++ program

A short C++ program that uses Cantera is shown below. This program reads in a
specification of a gas mixture from an input file, and then builds a new object
representing the mixture. It then sets the thermodynamic state and composition of the
gas mixture, and prints out a summary of its properties.

```{literalinclude} demo1a.cpp
:language: c++
```

:::{tip}
Before you can run this program, it first needs to be compiled. On a Linux system using
the GCC compiler, a typical command line for compiling this program might look like
this:

```bash
g++ combustor.cpp -o combustor -O3 $(pkg-config --cflags --libs cantera)
```

This example relies on the `pkg-config` tool to determine the appropriate compiler
flags, such as those specifying the Cantera header and library files. For more advanced
and flexible methods of compiling programs that use the Cantera C++ library, see
[](compiling-cxx).
:::

Running this program produces the output below:

```{literalinclude} ../../../../test_problems/cxx_userguide/demo1a_blessed.txt
:language: none
```

As C++ programs go, this one is quite short. It is the Cantera equivalent of the "Hello,
World" program most programming textbooks begin with. But it illustrates some important
points in writing Cantera C++ programs.

### Making Cantera classes and functions available

Cantera provides several header files designed for use in C++ application programs.
These are designed to include those portions of Cantera needed for particular types of
calculations. The headers and their functions are:

`core.h`
: Base classes and functions for creating {ct}`Solution` and {ct}`Interface` objects
  from input files, as well as associated classes accessed through these objects such as
  {ct}`ThermoPhase`, {ct}`Kinetics`, and {ct}`Transport`. *(New in Cantera 3.0)*.

`zerodim.h`
: Zero-dimensional reactor networks.

`onedim.h`
: One-dimensional reacting flows.

`reactionpaths.h`
: Reaction path diagrams.

`thermo.h`
: Base thermodynamic classes and functions for creating {ct}`ThermoPhase` objects from
  input files *(Superseded by `core.h` in Cantera 3.0)*.

`kinetics.h`
: Base kinetics classes and functions for creating {ct}`Kinetics` objects from input
  files *(Superseded by `core.h` in Cantera 3.0)*.

`transport.h`
: Base transport property classes and functions for creating {ct}`Transport` objects
  from input files *(Superseded by `core.h` in Cantera 3.0)*.

### Creating a `Solution` object from an input file

Here, {ct}`newSolution` imports all information held by a YAML input file into a Cantera
{ct}`Solution` object, which is accessed by the pointer `sol`. The thermodynamic
information is accessible via `sol->thermo()`, which itself returns a pointer to a
{ct}`ThermoPhase` object.

Class {ct}`ThermoPhase` is the base class for Cantera classes that represent phases of
matter. It defines the public interface for all classes that represent phases. For
example, it specifies that they all have a method `temperature()` that returns the current
temperature, a method `setTemperature(double T)` that sets the temperature, a method
`getChemPotentials(double* mu)` that writes the species chemical potentials into array
`mu`, and so on.

{ct}`ThermoPhase` objects can represent the intensive state of any single-phase solution
of multiple species. The phase may be a bulk, three-dimensional phase (a gas, a liquid,
or a solid), or it may be a two-dimensional surface phase, or even a one-dimensional
"edge" phase. Many different [phase thermodynamic models](/reference/thermo/phase-thermo)
are implemented as classes derived from {ct}`ThermoPhase`.

### The `report` function

The {ct}`ThermoPhase::report` method generates a nicely-formatted report of the
properties of a phase, including its composition in both mole (X) and mass (Y) units.
For each species present, the non-dimensional chemical potential is also printed. This
is handy particularly when doing equilibrium calculations. This function is very useful
to see at a glance the state of some phase.

### Handling errors

The entire body of the program is put inside a function that is invoked within a `try`
block in the main program. In this way, exceptions thrown in the function or in any
procedure it calls may be caught. In this program, a `catch` block is defined for
exceptions of type {ct}`CanteraError`. Cantera throws exceptions of this type, so it is
always a good idea to catch them.

## Accessing thermodynamic properties

In the program below, a gas mixture object is created, and a few thermodynamic
properties are computed and printed out:

```{literalinclude} thermodemo.cpp
:language: c++
```

Methods that compute scalar properties take no input parameters. The properties are
computed for the state that has been previously set and stored internally within the
object. Methods that return *molar* properties have names that end in `_mole`, while
methods that return properties *per unit mass* have names that end in `_mass`.

Methods that compute an array of values have names beginning with `get` and write the
computed values into an array provided as an input argument. For example, the method
`getChemPotentials(double* mu)` writes the species chemical potentials into the output
array `mu`.

All thermodynamic property methods are declared in class {ct}`ThermoPhase`, which is the
base class from which all classes that represent any type of phase of matter derive. See
the documentation for class {ct}`ThermoPhase` for the full list of available
thermodynamic properties.

## Computing chemical equilibrium

In the program below, the {ct}`ThermoPhase::equilibrate` method is called to set a gas
to a state of chemical equilibrium, holding the temperature and pressure fixed.

```{literalinclude} demoequil.cpp
:language: c++
```

The program output is:

```{literalinclude} ../../../../test_problems/cxx_userguide/demoequil_blessed.txt
:language: none
```

How can we tell that this is really a state of chemical equilibrium? Well, by applying
the equation of reaction equilibrium to formation reactions from the elements, it is
straightforward to show that

$$  \mu_k = \sum_m \lambda_m a_{km}  $$

where $\mu_k$ is the chemical potential of species $k$, $a_{km}$ is the number of atoms
of element $m$ in species $k$, and $\lambda_m$ is the chemical potential of the
elemental species per atom (the so-called "element potential"). In other words, the
chemical potential of each species in an equilibrium state is a linear sum of
contributions from each atom. We can see that this is true in the output above---the
chemical potential of H2 is exactly twice that of H, the chemical potential for OH is
the sum of the values for H and O, the value for H2O2 is twice as large as the value for
OH, and so on.

## Computing reaction rates and transport properties

The following program demonstrates the typical method for accessing the following object
types from a {ct}`Solution` object:

- {ct}`ThermoPhase`: Represents the thermodynamic properties of mixtures containing one
  or more species. Accessed using {ct}`Solution::thermo` method.
- {ct}`Kinetics`: Represents a kinetic mechanism involving one or more phases. Accessed
  using the {ct}`Solution::kinetics`.
- {ct}`Transport`: Computes transport properties for a phase. Accessed using the
  {ct}`Solution::transport` method.

```{literalinclude} kinetics_transport.cpp
:language: c++
```

This program produces the output below:

```{literalinclude} ../../../../test_problems/cxx_userguide/kinetics_transport_blessed.txt
:language: none
```

## Examples of additional C++ functionality

- [`combustor.cpp`](/examples/cxx/combustor): An example that shows how to set up a
  reactor network model, using classes {ct}`Reactor`, {ct}`ReactorNet`, {ct}`Reservoir`,
  {ct}`MassFlowController`, and {ct}`Valve`.
- [`flamespeed.cpp`](/examples/cxx/flamespeed): An example simulating a freely
  propagating laminar flame using the {ct}`Sim1D` solver.
