Skip to content

Commit

Permalink
Add function that shows the reaction to turn a compound into its cons…
Browse files Browse the repository at this point in the history
…tituent elements in their standard state
  • Loading branch information
CalebBell committed Jun 6, 2023
1 parent 0afd762 commit 801cf54
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 3 deletions.
64 changes: 63 additions & 1 deletion chemicals/reaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
------------------
.. autofunction:: chemicals.reaction.balance_stoichiometry
.. autofunction:: chemicals.reaction.stoichiometric_matrix
.. autofunction:: chemicals.reaction.standard_formation_reaction
"""

__all__ = ['Hfg', 'Hfl', 'Hfs', 'S0g', 'S0l', 'S0s',
Expand All @@ -83,12 +84,13 @@
'Hfl_all_methods', 'Hfg_all_methods', 'Hfs_all_methods',
'S0l_all_methods', 'S0g_all_methods', 'S0s_all_methods',
'Gibbs_formation', 'entropy_formation', 'Hf_basis_converter',
'balance_stoichiometry', 'stoichiometric_matrix']
'balance_stoichiometry', 'stoichiometric_matrix', 'standard_formation_reaction']

from math import ceil, log10

from chemicals import data_reader as dr
from chemicals import heat_capacity, miscdata
from chemicals.elements import periodic_table, simple_formula_parser
from chemicals.data_reader import (
data_source,
database_constant_lookup,
Expand Down Expand Up @@ -1074,3 +1076,63 @@ def balance_stoichiometry(matrix, rounding=9, allow_fractional=False):
return d


def standard_formation_reaction(atoms):
r'''This function calculates the standard reaction to reduce a chemical
compound to its standard state elements. Any hydrogen in the compound
is transformed to H2; oxygen to O2; carbon to graphite (single C), calcium
to Ca, etc.
Parameters
----------
atoms : dict[(str, float)]
A dictionary of (element, element_count) pairs for the reacting
compound, [-]
Returns
-------
reactant_coeff : float
The coefficient of the reactant; for compounds like CO that do not
divide evenly, this will be something other than 1 [-]
elemental_counts : list[float]
Balanced coefficients of each of the products, [-]
product_atomss : list[dict[(str, float)]]
A list of dictionaries of the elements produced, and how many atoms
of each element are in one unit of the element in its
standard form. Each dictionary contains a single key:value, with the key
being the element and the value being either 1 or 2 depending on the
standard state [-]
Examples
--------
Methane
>>> standard_formation_reaction({'C': 1, 'H': 4})
(1.0, [1.0, 2.0], [{'C': 1}, {'H': 2}])
Carbon monoxide
>>> standard_formation_reaction({'C': 1, 'O': 1})
(2.0, [2.0, 1.0], [{'C': 1}, {'O': 2}])
Methylamine
>>> standard_formation_reaction({'C': 1, 'H': 5, 'N': 1})
(2.0, [2.0, 5.0, 1.0], [{'C': 1}, {'H': 2}, {'N': 2}])
'''

product_atomss = []
reactants = []
for atom in atoms:
ele = periodic_table[atom]
ele_atoms = simple_formula_parser(ele.formula_standard)
product_atomss.append(ele_atoms)
reactants.append(True)

atoms_to_process = product_atomss + [atoms]
reactants.append(False)
matrix = stoichiometric_matrix(atoms_to_process, reactants)
coeffs = balance_stoichiometry(matrix)
reactant_coeff = coeffs[-1]
elemental_counts = coeffs[:-1]
return reactant_coeff, elemental_counts, product_atomss
31 changes: 29 additions & 2 deletions tests/test_reaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
from chemicals.reaction import (Gibbs_formation, Hf_basis_converter, Hfg, Hfg_all_methods,
Hfg_methods, Hfl, Hfl_methods, Hfs, Hfs_methods, S0g,
S0g_all_methods, S0g_methods, S0l, S0l_methods, S0s, S0s_methods,
balance_stoichiometry, entropy_formation, stoichiometric_matrix)
balance_stoichiometry, entropy_formation, stoichiometric_matrix,
standard_formation_reaction)
from chemicals.heat_capacity import TRC_gas_data, CRC_standard_data
from chemicals.reaction import Hfg_API_TDB_data, Hfg_ATcT_data, Hfl_ATcT_data, Hfg_S0g_YAWS_data

Expand Down Expand Up @@ -205,4 +206,30 @@ def test_balance_stoichiometry():

def test_stoichiometric_matrix():
res = stoichiometric_matrix([{'Mg': 1, 'O': 1}, {'Mg': 1}, {'O': 2}], [True, False, False])
assert_close2d([[1, -1, 0], [1, 0, -2]], res)
assert_close2d([[1, -1, 0], [1, 0, -2]], res)


def test_standard_formation_reaction():
reactant_coeff, coeff_test, reactant_atomss_test = standard_formation_reaction({'C': 3, 'H': 8})
assert coeff_test == [3.0, 4.0]
assert reactant_atomss_test == [{'C': 1}, {'H': 2}]

reactant_coeff, coeff_test, reactant_atomss_test = standard_formation_reaction({'C': 3, 'H': 7, 'N': 1, 'O': 2, 'S': 1})
assert coeff_test == [6.0, 7.0, 1.0, 2.0, 2.0]
assert reactant_atomss_test == [{'C': 1}, {'H': 2}, {'N': 2}, {'O': 2}, {'S': 1}]

reactant_coeff, coeff_test, reactant_atomss_test = standard_formation_reaction({'C': 6, 'H': 7, 'B': 1, 'O': 2})
assert coeff_test == [12.0, 7.0, 2.0, 2.0]
assert reactant_atomss_test == [{'C': 1}, {'H': 2}, {'B': 1}, {'O': 2}]

reactant_coeff, coeff_test, reactant_atomss_test = standard_formation_reaction({'C': 4, 'H': 12, 'Si': 1})
assert coeff_test == [4.0, 6.0, 1.0]
assert reactant_atomss_test == [{'C': 1}, {'H': 2}, {'Si': 1}]

reactant_coeff, coeff_test, reactant_atomss_test = standard_formation_reaction({'C': 12, 'H': 10, 'Cl': 1, 'P': 1})
assert coeff_test == [24.0, 10.0, 1.0, 2.0]
assert reactant_atomss_test == [{'C': 1}, {'H': 2}, {'Cl': 2}, {'P': 1}]

reactant_coeff, coeff_test, reactant_atomss_test = standard_formation_reaction({'C': 2, 'H': 4, 'Br': 1, 'F': 1})
assert coeff_test == [4.0, 4.0, 1.0, 1.0]
assert reactant_atomss_test == [{'C': 1}, {'H': 2}, {'Br': 2}, {'F': 2}]

0 comments on commit 801cf54

Please sign in to comment.