Example Usage

One way you can use this library is for evaluating the derivatives needed for a 0D plasma species model. Below shows how you would access all of the data required for a simple 0D model.


#include <stdlib.h>
#include "prism/prism.h"
#include "fmt/core.h"
#include "yaml-cpp/yaml.h"

using namespace std;

int
main()
// main(int /*argc*/, char**argv[]*/)
{
  auto & np = prism::NetworkParser::instance();
  np.parseNetwork("example/simple_argon_rate.yaml");
  np.writeReactionTable("example/table.tex");
  np.writeSpeciesSummary("example/summary.yaml");

  const auto & rate_rxns = np.rateBasedReactions();
  const auto & transient_species = np.transientSpecies();
  const auto & species_names = np.speciesNames();

  cout << endl;

  for (const auto & r : rate_rxns)
  {
    cout << fmt::format("id: {:d}", r->id()) << " " << r->expression() << endl;
  }

  cout << endl;

  for (const auto & s : transient_species)
  {
    cout << "Species: " << s->name() << " id: " << s->id() << endl;
    for (const auto & r : s->unbalancedRateBasedReactionData())
    {

      cout << fmt::format(" {:4d} {:>12.4e} ", r.stoic_coeff, rate_rxns[r.id]->sampleData(10));

      for (const auto & s_data : rate_rxns[r.id]->reactantData())
      {
        cout << fmt::format("({:s})^{:d} ", species_names[s_data.id], s_data.occurances);
      }
      cout << endl;
    }
    cout << endl;
  }

  const YAML::Node network = YAML::LoadFile("example/summary.yaml");
  cout << network << endl;
  return EXIT_SUCCESS;
}
(../main.C)

An important thing to note in this example is that we are iterating over all of the rate based reactions. This file includes rate based reactions which have rates that come from an arrhenius form and ones that come from data read in from a tabulated data file. Sampling this data is handled with different methods based on your input but there is a single API for ease of use. Reactions which have data from an arrhenius form call a function which evaluates this function and for Reactions which have data read from a file we use linear interpolation to sample data from the file.

commentnote

Ensure that the data is in tabulated data file encompasses the entire sample space you will be probing. Extrapolatory sampling is not supported.

The way this single API is enabled is by assigning the correct sampling function to a function pointer when the Reaction is created and then this function pointer is called on every evaluation, so overhead for the generality of this API should be minimal.

Example Input File

data-path: test/inputs/data/
bibliography: test/inputs/argon_works.bib
data-delimiter: ","
constant-species: Ar

latex-overrides:
  - species: [Ar(a), Ar(b), Ar^r]
    latex: [Ar$\left(\alpha\right)$, Ar$\left(\beta\right)$, Ar$^r$]

lumped-species:
  - lumped: Ar*
    actual: [Ar(a), Ar(b)]

rate-based:

  - reaction: Ar + e -> Ar(a) + e
    delta-eps-e: 11.56
    file: ar_excitation.txt
    references: lymberopoulos1993fluid
    notes: This is a test

  - reaction: Ar + e -> Ar+ + 2e
    delta-eps-e: 15.7
    file: ar_ionization.txt
    references: lymberopoulos1993fluid
    notes: [this one, has 2 notes]

  - reaction: Ar(b) + e -> Ar+ + 2e
    delta-eps-e: 4.14
    file: ar_excited_ionization.txt
    references: lymberopoulos1993fluid

  - reaction: Ar(a) + e -> Ar + e
    delta-eps-e: -11.56
    file: ar_deexcitation.txt
    references: lymberopoulos1993fluid

  - reaction: Ar(b) + e -> Ar^r + e
    params: 2.0e-7
    references: lymberopoulos1993fluid

  - reaction: 2Ar(a) -> Ar+ + Ar + e
    params: 6.2e-10
    references: lymberopoulos1993fluid

  - reaction: Ar(b) + Ar -> 2Ar
    params: 3.0e-15
    references: lymberopoulos1993fluid

  - reaction: Ar(a) + 2Ar -> Ar2 + Ar
    params: 1.1e-31
    references: lymberopoulos1993fluid

  - reaction: Ar + e -> Ar + e
    elastic: true
    file: ar_elastic.txt
    references: lymberopoulos1993fluid
(../example/simple_argon_rate.yaml)

Example Program Output

Starting to parse 'rate-based' reaction block

Reaction Validated: Ar + e -> Ar(a) + e
Reaction Validated: Ar + e -> Ar+ + 2e
Reaction Validated: Ar(b) + e -> Ar+ + 2e
Reaction Validated: Ar(a) + e -> Ar + e
Reaction Validated: Ar(b) + e -> Ar^r + e
Reaction Validated: 2Ar(a) -> Ar+ + Ar + e
Reaction Validated: Ar(b) + Ar -> 2Ar
Reaction Validated: Ar(a) + 2Ar -> Ar2 + Ar
Reaction Validated: Ar + e -> Ar + e

id: 0 Ar + e -> Ar(a) + e
id: 1 Ar + e -> Ar+ + 2e
id: 2 Ar(b) + e -> Ar+ + 2e
id: 3 Ar(a) + e -> Ar + e
id: 4 Ar(b) + e -> Ar^r + e
id: 5 2Ar(a) -> Ar+ + Ar + e
id: 6 Ar(b) + Ar -> 2Ar
id: 7 Ar(a) + 2Ar -> Ar2 + Ar
id: 8 Ar + e -> Ar + e

Species: Ar* id: 0
    1   9.9736e+08 (Ar)^1 (e)^1
   -1   7.5471e+10 (Ar*)^1 (e)^1
   -1   1.1882e+09 (Ar*)^1 (e)^1
   -1   2.0000e-07 (Ar*)^1 (e)^1
   -2   6.2000e-10 (Ar*)^2
   -1   3.0000e-15 (Ar*)^1 (Ar)^1
   -1   1.1000e-31 (Ar*)^1 (Ar)^2

Species: e id: 1
    1   1.8670e+09 (Ar)^1 (e)^1
    1   7.5471e+10 (Ar*)^1 (e)^1
    1   6.2000e-10 (Ar*)^2

Species: Ar+ id: 2
    1   1.8670e+09 (Ar)^1 (e)^1
    1   7.5471e+10 (Ar*)^1 (e)^1
    1   6.2000e-10 (Ar*)^2

Species: Ar2 id: 3
    1   1.1000e-31 (Ar*)^1 (Ar)^2

Species: Ar^r id: 4
    1   2.0000e-07 (Ar*)^1 (e)^1

lumped-species:
  - lumped: Ar*
    actual: [Ar(a), Ar(b)]
all-sources:
  - species: [Ar+, Ar2, Ar^r]
constant-species:
  - species: [Ar]
all-sinks:
  - species: []
unique-species:
  - count: 6
  - name: Ar*
    id: 0
  - name: e
    id: 1
  - name: Ar+
    id: 2
  - name: Ar2
    id: 3
  - name: Ar^r
    id: 4
  - name: Ar
    id: 5
reacion-summary:
  - Ar*:
      - rate-based: 7
        sources:
          - count: 1
          - Ar + e -> Ar(a) + e
        balanced:
          - count: 0
        sinks:
          - count: 6
          - Ar(b) + e -> Ar+ + 2e
          - Ar(a) + e -> Ar + e
          - Ar(b) + e -> Ar^r + e
          - 2Ar(a) -> Ar+ + Ar + e
          - Ar(b) + Ar -> 2Ar
          - Ar(a) + 2Ar -> Ar2 + Ar
      - xsec-based: 0
        sources:
          - count: 0
        balanced:
          - count: 0
        sinks:
          - count: 0
  - e:
      - rate-based: 7
        sources:
          - count: 3
          - Ar + e -> Ar+ + 2e
          - Ar(b) + e -> Ar+ + 2e
          - 2Ar(a) -> Ar+ + Ar + e
        balanced:
          - count: 4
          - Ar + e -> Ar(a) + e
          - Ar(a) + e -> Ar + e
          - Ar(b) + e -> Ar^r + e
          - Ar + e -> Ar + e
        sinks:
          - count: 0
      - xsec-based: 0
        sources:
          - count: 0
        balanced:
          - count: 0
        sinks:
          - count: 0
  - Ar+:
      - rate-based: 3
        sources:
          - count: 3
          - Ar + e -> Ar+ + 2e
          - Ar(b) + e -> Ar+ + 2e
          - 2Ar(a) -> Ar+ + Ar + e
        balanced:
          - count: 0
        sinks:
          - count: 0
      - xsec-based: 0
        sources:
          - count: 0
        balanced:
          - count: 0
        sinks:
          - count: 0
  - Ar2:
      - rate-based: 1
        sources:
          - count: 1
          - Ar(a) + 2Ar -> Ar2 + Ar
        balanced:
          - count: 0
        sinks:
          - count: 0
      - xsec-based: 0
        sources:
          - count: 0
        balanced:
          - count: 0
        sinks:
          - count: 0
  - Ar^r:
      - rate-based: 1
        sources:
          - count: 1
          - Ar(b) + e -> Ar^r + e
        balanced:
          - count: 0
        sinks:
          - count: 0
      - xsec-based: 0
        sources:
          - count: 0
        balanced:
          - count: 0
        sinks:
          - count: 0
  - Ar:
      - rate-based: 7
        sources:
          - count: 3
          - Ar(a) + e -> Ar + e
          - 2Ar(a) -> Ar+ + Ar + e
          - Ar(b) + Ar -> 2Ar
        balanced:
          - count: 1
          - Ar + e -> Ar + e
        sinks:
          - count: 3
          - Ar + e -> Ar(a) + e
          - Ar + e -> Ar+ + 2e
          - Ar(a) + 2Ar -> Ar2 + Ar
      - xsec-based: 0
        sources:
          - count: 0
        balanced:
          - count: 0
        sinks:
          - count: 0
(../example/output.txt)

In the output from the example program you can first see that the reactions are validated by the parser. After this there are 3 main columns under each species section. The first column is the stoichiometric coefficient for the reactions. The second column is the reaction rate sampled at a value of 10. The third column is a list of all of the reactants for each reaction which is either a source a sink for the given species where each species name is raised to the power corrisponding to the number of times it appears on the left hand side of the reaction.

Example table

One of the capabilities of this program is that a for the reaction mechanism is automatically generated. This is generated by calling the writeReactionTable method of the NetworkParser. There is a default implementation for this table generation which is available for customization if needed. In this system we generate a footnote for each unique note in the input file and every reaction that has notes references these footnotes in sorted order. This table will compile in a project so long as your project is configured with the proper bib files and you have provided overrides for all species whose names cannot be directly used in a table. To view the compiled version of this table please click here to open the table in Overleaf

\documentclass{article}
\usepackage{tabu}
\usepackage{float}
\usepackage{graphicx}
\usepackage{amsmath}
\usepackage[top=1cm]{geometry}
\tabulinesep = 1.5mm

\usepackage[
  backend=biber,
  style=numeric,
  sorting=nty,
]{biblatex}

\addbibresource{argon_works.bib}

\begin{document}

\newpage
\section{Rate Reactions}
\begin{table}[H]
  \centering
  \resizebox{\columnwidth}{!}{
    \begin{tabu}{clcccccccc}
      No. & Reaction & $A$ & $n_g$ & $E_g$ & $n_e$ & $E_e$ & $\Delta \varepsilon_e$ & $\Delta \varepsilon_g$ & Ref.\\
      \hline
      \hline
      1 & Ar$\left(\beta\right)$ + e $\rightarrow$ Ar$^r$ + e & 2.00$\times 10^{-7}$ & 0.00 & 0.00 & 0.00 & 0.00 & 0.00 & 0.00 & \cite{lymberopoulos1993fluid} \footnotemark[1]\\
      2 & 2Ar$\left(\alpha\right)$ $\rightarrow$ Ar$^{+}$ + Ar + e & 6.20$\times 10^{-10}$ & 0.00 & 0.00 & 0.00 & 0.00 & 0.00 & 0.00 & \cite{lymberopoulos1993fluid} \footnotemark[2]\\
      3 & Ar$\left(\beta\right)$ + Ar $\rightarrow$ 2Ar & 3.00$\times 10^{-15}$ & 0.00 & 0.00 & 0.00 & 0.00 & 0.00 & 0.00 & \cite{lymberopoulos1993fluid} \\
      4 & Ar$\left(\alpha\right)$ + 2Ar $\rightarrow$ Ar$_{2}$ + Ar & 1.10$\times 10^{-31}$ & 0.00 & 0.00 & 0.00 & 0.00 & 0.00 & 0.00 & \cite{lymberopoulos1993fluid} \\
    \end{tabu}
  }
\end{table}

\begin{table}[H]
  \centering
  \resizebox{\columnwidth}{!}{
    \begin{tabu}{clcccccccc}
      No. & Reaction & $A$ & $n_g$ & $E_g$ & $n_e$ & $E_e$ & $\Delta \varepsilon_e$ & $\Delta \varepsilon_g$ & Ref.\\
      \hline
      \hline
      5 & Ar + e $\rightarrow$ Ar$\left(\alpha\right)$ + e &  & & EEDF & & & 1.16$\times 10^{1}$ & 0.00 & \cite{lymberopoulos1993fluid} \footnotemark[3]\\
      6 & Ar + e $\rightarrow$ Ar$^{+}$ + 2e &  & & EEDF & & & 1.57$\times 10^{1}$ & 0.00 & \cite{lymberopoulos1993fluid} \footnotemark[4]$^{,}$\footnotemark[5]\\
      7 & Ar$\left(\beta\right)$ + e $\rightarrow$ Ar$^{+}$ + 2e &  & & EEDF & & & 4.14 & 0.00 & \cite{lymberopoulos1993fluid} \\
      8 & Ar$\left(\alpha\right)$ + e $\rightarrow$ Ar + e &  & & EEDF & & & -1.16$\times 10^{1}$ & 0.00 & \cite{lymberopoulos1993fluid} \\
      9 & Ar + e $\rightarrow$ Ar + e &  & & EEDF & & & 0.00 & 0.00 & \cite{lymberopoulos1993fluid} \\
    \end{tabu}
  }
\end{table}

\footnotemark[1]{Species \lq Ar$\left(\beta\right)$\rq{}  has been lumped into \lq Ar*\rq}\\ 
\footnotemark[2]{Species \lq Ar$\left(\alpha\right)$\rq{}  has been lumped into \lq Ar*\rq}\\ 
\footnotemark[3]{This is a test}\\ 
\footnotemark[4]{this one}\\ 
\footnotemark[5]{has 2 notes}\\ 
\newpage
\printbibliography

\end{document}
(../example/table.tex)

Example Species Summary

Another capability of this system is that we provide a species summary with some important information about the reactions that species are involved in. At the beginning of this file we list all the species that have been lumped and the state that they have been lumped into. Then a small summary of the species which: only have sources, sinks, or which are only involved in reactions which lead to no change in their population. After this a summary of the species and all the reactions which is listed. Finally, the summary that has been written to file is again read in. This demontrates that your are able load output from this summary for further analysis using any standard yaml reader tool.

# 2 species lumped into 1
lumped-species:
  - lumped: Ar*
    actual: [Ar(a), Ar(b)]

# species which are never consumed
all-sources:
  - species: [Ar+, Ar2, Ar^r]
# species which are only in balanced reactions
# or which have been explicitly marked as constant in the input file
constant-species:
  - species: [Ar]
# species which are only consumed
all-sinks:
  - species: []

unique-species:
  - count: 6
  - name: Ar*
    id: 0
  - name: e
    id: 1
  - name: Ar+
    id: 2
  - name: Ar2
    id: 3
  - name: Ar^r
    id: 4
  - name: Ar
    id: 5

reacion-summary:
  - Ar*:
    - rate-based: 7
      sources:
        - count: 1
        - Ar + e -> Ar(a) + e

      balanced:
        - count: 0

      sinks:
        - count: 6
        - Ar(b) + e -> Ar+ + 2e
        - Ar(a) + e -> Ar + e
        - Ar(b) + e -> Ar^r + e
        - 2Ar(a) -> Ar+ + Ar + e
        - Ar(b) + Ar -> 2Ar
        - Ar(a) + 2Ar -> Ar2 + Ar

    - xsec-based: 0
      sources:
        - count: 0

      balanced:
        - count: 0

      sinks:
        - count: 0

  - e:
    - rate-based: 7
      sources:
        - count: 3
        - Ar + e -> Ar+ + 2e
        - Ar(b) + e -> Ar+ + 2e
        - 2Ar(a) -> Ar+ + Ar + e

      balanced:
        - count: 4
        - Ar + e -> Ar(a) + e
        - Ar(a) + e -> Ar + e
        - Ar(b) + e -> Ar^r + e
        - Ar + e -> Ar + e

      sinks:
        - count: 0

    - xsec-based: 0
      sources:
        - count: 0

      balanced:
        - count: 0

      sinks:
        - count: 0

  - Ar+:
    - rate-based: 3
      sources:
        - count: 3
        - Ar + e -> Ar+ + 2e
        - Ar(b) + e -> Ar+ + 2e
        - 2Ar(a) -> Ar+ + Ar + e

      balanced:
        - count: 0

      sinks:
        - count: 0

    - xsec-based: 0
      sources:
        - count: 0

      balanced:
        - count: 0

      sinks:
        - count: 0

  - Ar2:
    - rate-based: 1
      sources:
        - count: 1
        - Ar(a) + 2Ar -> Ar2 + Ar

      balanced:
        - count: 0

      sinks:
        - count: 0

    - xsec-based: 0
      sources:
        - count: 0

      balanced:
        - count: 0

      sinks:
        - count: 0

  - Ar^r:
    - rate-based: 1
      sources:
        - count: 1
        - Ar(b) + e -> Ar^r + e

      balanced:
        - count: 0

      sinks:
        - count: 0

    - xsec-based: 0
      sources:
        - count: 0

      balanced:
        - count: 0

      sinks:
        - count: 0

# This species was requested to be constant in the mechanism
# As a result it is not included in the transient species list
  - Ar:
    - rate-based: 7
      sources:
        - count: 3
        - Ar(a) + e -> Ar + e
        - 2Ar(a) -> Ar+ + Ar + e
        - Ar(b) + Ar -> 2Ar

      balanced:
        - count: 1
        - Ar + e -> Ar + e

      sinks:
        - count: 3
        - Ar + e -> Ar(a) + e
        - Ar + e -> Ar+ + 2e
        - Ar(a) + 2Ar -> Ar2 + Ar

    - xsec-based: 0
      sources:
        - count: 0

      balanced:
        - count: 0

      sinks:
        - count: 0
(../example/summary.yaml)