Using ThermoFun from C++ and Python

The main ThermoFun class for doing calculations is the Engine class.

Attention

When using the engine class calculations can only be done using the default units (e.g. Pa for pressure and K for temperature), for one given substance, temperature and pressure point at a time.

The Batch class is useful for doing batch calculations for a given list of substances, reactions, properties, and temperature and pressure grid. Options to set the input and output properties units are available.

An equivalent interface built using Pybnd11 is available to use from Python

Engine class

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
#include "ThermoFun.h"
using namespace std;
using namespace ThermoFun;

int main()
{
  // Create the batch object using a database file in JSON
  ThermoFun::Engine engine("aq17.json");
  double T       = 398.15; double P = 1e7; // in K and Pa
  auto propAl    = engine.thermoPropertiesSubstance(T, P, "Al+3");
  // extracting values from results for the Gibbs energy
  double G0      = propAl.gibbs_energy.val; // value
  double G0dT    = propAl.gibbs_energy.ddt; // derivative with T = -S0
  double G0error = propAl.gibbs_energy.err; // propagated error

  return 0;
}

Batch class

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include "ThermoFun.h"
using namespace std;
using namespace ThermoFun;

int main()
{
    // Create the batch object using a database file in JSON
    ThermoFun::Batch batch("aq17.json");

    // Optional: set the solvent symbol used for calculating properties of aqueous species
    batch.setSolventSymbol("H2O@");

    // Optional: change default units
    batch.setPropertiesUnits({"temperature", "pressure"},{"degC","bar"});

    // Optional: change default digits
    batch.setPropertiesDigits({"gibbs_energy","entropy", "volume", "enthalpy", "temperature", "pressure"}, {0, 1, 2, 0, 0, 0});

    // Retrieve the entropy of H2O
    double H2Oentropy = batch.thermoPropertiesSubstance( 300, 2000, "H2O@", "entropy").toDouble();

    // Retrieve the derivative of G with respect to T
    double H2OdGdT = batch.thermoPropertiesSubstance( 300, 2000, "H2O", "entropy").toThermoScalar().ddt;

    // Write results to a comma separate files for a list of T-P pairs, substances, and properties
    batch.thermoPropertiesSubstance({{25, 1},{40, 1},{70, 100},{90, 100},{100, 100}}, // list of T-P pairs
                                    {"Al+3", "OH-", "SiO2@"},                         // list of substance symbols
                                    {"gibbs_energy","entropy", "volume", "enthalpy"}  // list of properties
                                  ).toCSV("results.csv");                            // output
    return 0;
}

Using data from ThermoHub

Example of retrieveing a thermodynamic dataset from ThermoHub for initializing a ThermoFun batch calculation.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include "ThermoFun.h"
using namespace std;
using namespace ThermoFun;

int main()
{
    // Set the file path to the database connection and preferences file (provided in the Resources/ folder)
    setDatabaseConnectionFilePath("fun-dbclient-config.json");

    // Initialize a database client object
    ThermoFun::DatabaseClient dbc;

    // Retrieve list of records given a ThermoDataSet symbol
    auto records = dbc.recordsFromThermoDataSet("PSI-Nagra-12-07");

    // Create a ThermoFun database using the records list
    ThermoFun::Database db = databaseFromRecordList(dbc, records);

    // Initialize an batch object using the database
    ThermoFun::Batch batch (db);

    // Optional: set the solvent symbol used for calculating properties of aqueous species
    batch.setSolventSymbol("H2O@");

    // Optional set calculation and output preferences
    ThermoFun::BatchPreferences op;
    op.isFixed = true;
    op.outSolventProp       = true;
    op.calcReactFromSubst   = false;
    op.calcSubstFromReact   = false;
    batch.setBatchPreferences(op);

    // Optional set units and significant digits
    batch.setPropertiesUnits({"temperature", "pressure"},{"degC","bar"});
    batch.setPropertiesDigits({ "reaction_gibbs_energy","reaction_entropy", "reaction_volume",
                                "reaction_enthalpy","logKr", "temperature", "pressure"}, {0, 4, 4, 4, 4, 0, 0});

    batch.thermoPropertiesReaction({{25,1}}, {"AmSO4+", "MgSiO3@"}, {"reaction_gibbs_energy", "reaction_entropy",
                                    "reaction_volume", "reaction_enthalpy", "logKr"}).toCSV("results.csv");

    batch.thermoPropertiesReaction({0,20,50,75},{0,0,0,0},{"AmSO4+", "MgSiO3@"}, {"reaction_gibbs_energy", "reaction_entropy",
                                    "reaction_volume", "reaction_enthalpy", "logKr"}).toCSV("results.csv");
}

Python interface

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import PyThermoFun

PyThermoFun.setDatabaseConnectionFilePath("Resources/fun-dbclient-config.json")

print("\n# Initialize a database client object\n")
dbc = PyThermoFun.DatabaseClient()

print("\n# Retrieve list of records given a ThermoDataSet symbol\n")
records = dbc.recordsFromThermoDataSet("Cemdata18")

print("\n# Create a ThermoFun database using the records list\n")
db = PyThermoFun.databaseFromRecordList(dbc, records)

print("\n# Initialize an interface object using the database\n")
batch = PyThermoFun.ThermoBatch(db)

print("\n# Optional: set the solvent symbol used for calculating properties of aqueous species\n")
batch.setSolventSymbol("H2O@")

print("\n# Optional set calculation and output preferences\n")
op = PyThermoFun.BatchPreferences()
op.isFixed = True
op.outSolventProp       = True
op.calcReactFromSubst   = False
op.calcSubstFromReact   = False
batch.setBatchPreferences(op)

print("\n# Optional set units and significant digits\n")
batch.setPropertiesUnits(["temperature", "pressure"],["degC","bar"])

batch.setPropertiesDigits(["gibbs_energy","entropy", "volume",
                            "enthalpy","logKr", "temperature", "pressure"], [0, 4, 4, 4, 4, 0, 0])

print("\n# Do calculations and write output\n")
batch.thermoPropertiesSubstance([[25,1]], ["Na(CO3)-", "Mg+2"], ["gibbs_energy", "entropy",
                                "volume", "enthalpy"]).toCSV("results_dbc.csv")