-
Notifications
You must be signed in to change notification settings - Fork 4
Description
The Problem
When using the ChemicalFun::FormulaProperties
to obtain the properties of some compounds, the charge is incorrectly calculated. For example, if we use Calcium carbide (CaC2) as input compound and run:
ChemicalFun::FormulaToken token("CaC2");
ChemicalFun::DBElements all_elements;
ChemicalFun::FormulaProperties properties = token.properties(all_elements.elements());
Then we receive the following output:
{"atomic_mass":64.09959983825681,"atoms_formula_unit":3.0,"charge":10.0,"elemental_entropy":53.06999969482422,"formula":"CaC2"}
Note the "charge":10.0
, which should be 0. Technically one could also write Ca(C2)
which could indicate that Carbon forms a triple bond in this case and the species generated would have to be Ca2+ and (C2)2-. However, the parser is simply a tokenizer, not a chemical interpreter.
The atomic mass is calculated correctly and the atoms_formula_unit
as well, but the charge is derived from valances and it is assumed that (C)arbon has a valence of 4 and (Ca)lcium of 2, which is then simply calculated as 1 * 2 + 4 * 2 = 10 (see double FormulaToken::calculate_charge
). The valences are static and stored in map_elements_valences
. This is not the expected behaviour for a chemist like myself. Therefore, this issue should at least be pointed out somewhere as a limitation.
Further Examples
Obviously, because of the static valence calculation, the abovementioned problem is not restricted to corner cases. Other common examples would be:
- Na2S (i.e. Sodium sulfide:
{"atomic_mass":78.0466003417968,"atoms_formula_unit":3.0,"charge":8.0,"elemental_entropy":134.3979988098144,"formula":"Na2S"}
) - Na2SO3 (i.e. Sodium sulfite:
{"atomic_mass":126.04480075836182,"atoms_formula_unit":6.0,"charge":2.0,"elemental_entropy":442.1049995422374,"formula":"Na2SO3"}
) - Mn2O3 (i.e. Manganese(III) oxide:
{"atomic_mass":157.8741998672486,"atoms_formula_unit":5.0,"charge":-2.0,"elemental_entropy":371.7269973754894,"formula":"Mn2O3"}
) - MnO2 (i.e. Manganese(IV) oxide:
{"atomic_mass":86.9368000030518,"atoms_formula_unit":3.0,"charge":-2.0,"elemental_entropy":237.1479988098152,"formula":"MnO2"}
) - Mn2O7 (i.e. Manganese(VII) oxide:
{"atomic_mass":221.8718004226686,"atoms_formula_unit":9.0,"charge":-10.0,"elemental_entropy":782.0029983520534,"formula":"Mn2O7"}
)
Proposition for a Solution
The only possible solution for this problem is to explicitly define the valence like so CaC|-1|2
, which assigns the (C)arbon atom a valence of -1. This would need to be mentioned somewhere and is only a suboptimal solution.
Better Solution: The program should not derive the (molecular) charge from valence calculation at all, but from charge indicators. If no charge indicators are present, the given formula should be electroneutral and the program could forget the valences altogether. However, I fear (although I haven't checked) that the reaction algorithm uses the valence information to calculate charged ions in solution.