Using ThermoFun from C++ and Python
The main ThermoFun class for doing calculations is the Engine class. With ThermoEngine you can do one calculaiton at a time.
Attention
When using the engine
class calculations can only be done using the default S.I. 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 Pybind11 is available to use from Python
Engine class
Properties of substance
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #include "Thermofun/ThermoFun.h" using namespace std; int main() { // Create the engine object using a database file in JSON format // Examples of such files can be found in /Resources/databases/ folder or can be // retrieved from ThermoHub database using ThermoHubClient ThermoFun::Engine engine("aq17-thermofun.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; } |
Properties of reaction
1 2 3 | reaction_properties = engine.thermoPropertiesReaction(298.15, 1e5, "Cal = Ca+2 + CO3-2"); logK = reaction_properties.log_equilibrium_constant.val; drG0 = reaction_properties.reaction_gibbs_energy.val; |
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 | #include "Thermofun/ThermoFun.h" using namespace std; 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 retrieving 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 | #include "Thermofun/ThermoFun.h" #include "ThermoHubClient/ThermoHubClient.h" using namespace std; int main() { // database connection (local or remote) using a configuration file // ThermoHubClient::DatabaseClient dbc("hub-connection-config.json"); // default connection (remote) to db.thermohub.net ThermoHubClient::DatabaseClient dbc; // retrieve a database from ThermoHub server as a JSON file dbc.saveDatabase("psinagra-12-07") // this will save the database file psinagra-12-07-thermofun.json // Initialize an batch object using the database file ThermoFun::Batch batch("psinagra-12-07-thermofun.json"); // 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.reactionPropertiesFromReactants = false; op.substancePropertiesFromReaction = 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 | import ThermoHubClient as client Import ThermoFun as fun print("\n# Initialize a database client object\n") dbc = client.DatabaseClient() print("\n# Retrieve a JSON database given a ThermoDataSet symbol\n") db = dbc.getDatabase("cemdata18") print("\n# Initialize an interface object using the database\n") batch = fun.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 = fun.BatchPreferences() op.isFixed = True op.reactionPropertiesFromReactants = False op.substancePropertiesFromReaction = 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") reaction_properties = engine.thermoPropertiesReaction(298.15, 1e5, "Cal = Ca+2 + CO3-2") logK = reaction_properties.log_equilibrium_constant f'logK (Cal = Ca+2 + CO3-2) is {logK.val}' |