Components

Creating components

Component creation is a trivial task with AuChimiste. All you need to do is call component with one of the available composition specification methods and a list of keyword arguments representing the element amounts to use. For instance, to create aluminum oxide from its stoichiometry one does:

A = component(:stoichiometry; Al=2, O=3)
AuChimiste.ChemicalComponent([:Al, :O], [2.0, 3.0], [0.4, 0.6], [0.5292569257852893, 0.47074307421471057], 101.9600768, 0)

The above is a syntactic sugar to providing a stoichiometry as argument. Please notice that this form requires the overall charge of the component to be specified.

A = component(stoichiometry(Al=2, O=3), 0)
AuChimiste.ChemicalComponent([:Al, :O], [2.0, 3.0], [0.4, 0.6], [0.5292569257852893, 0.47074307421471057], 101.9600768, 0)

The other composition specification methods are mass_proportions and mole_proportions. Let' s see their use in a more elaborate example with naphthalene $C_{10}H_{8}$:

naphtalene = component(:stoichiometry; C=10, H=8)
AuChimiste.ChemicalComponent([:C, :H], [10.0, 8.0], [0.5555555555555556, 0.4444444444444444], [0.937085524365316, 0.06291447563468411], 128.17399999999998, 0)

So far nothing new. We can use mass_fractions_map and mole_fractions_map to retrieve the named-tuples of compositions in the units provided by these functions:

Y = mass_fractions_map(naphtalene)
X = mole_fractions_map(naphtalene)
Y, X
((C = 0.937085524365316, H = 0.06291447563468411), (C = 0.5555555555555556, H = 0.4444444444444444))

Using the mass fractions Y one can create the equivalent compound from this sort of input. Notice here that a scale is provided to enforce the stoichiometric coefficient of carbon in the species (there is no way to infer it simply from elemental mass fractions).

m_y = component(:mass_proportions; Y..., scale=:C=>10)
AuChimiste.ChemicalComponent([:C, :H], [10.0, 8.0], [0.5555555555555556, 0.4444444444444444], [0.937085524365316, 0.06291447563468411], 128.17399999999998, 0)

The same can be done using mole fractions, as follows:

m_x = component(:mole_proportions; X..., scale=:C=>10)
AuChimiste.ChemicalComponent([:C, :H], [10.0, 8.0], [0.5555555555555556, 0.4444444444444444], [0.937085524365316, 0.06291447563468411], 128.17399999999998, 0)

If scaling is not provided, the default behavior is enforced, applying unit content to the first element provided in the composition tuple. Notice that these constructors do not sort arguments. This behavior is intended so that compounds can be easily understood by the user in the case a standard formula format exists (as for the oxides above).

component(:mole_proportions; X...)
AuChimiste.ChemicalComponent([:C, :H], [1.0, 0.7999999999999998], [0.5555555555555556, 0.4444444444444444], [0.937085524365316, 0.06291447563468411], 12.8174, 0)

Finally, by proportions instead of fractions in the name of the composition specification methods we mean that internal normalization is performed. That might be useful, for instance, for reverse-engineering a compound formula from an analysis report.

Often in the field of combustion of heavy-fuel oils one is confronted with empirical fuel compositions given in mass percentages. Assume the following composition; playing with the scaling factor an engineer could infer a candidate composition and identify the family of the fuel [2].

component(:mass_proportions; C = 93.2, H = 6.3, O = 0.3, scale=:C=>10)
AuChimiste.ChemicalComponent([:C, :H, :O], [10.0, 8.054586909871242, 0.024165271059054916], [0.5531355206333394, 0.445527812387811, 0.001336666978849611], [0.9338677354709419, 0.06312625250501001, 0.003006012024048096], 128.61564377682402, 0)

Combining components

Some algebraic manipulation is also possible with AuChimiste.ChemicalComponent instances. Let's see a practical case from cement industry, where compositions are often expressed with a jargon that makes use of multiple of component oxides to represent complex phases such as $C_{12}A_7$.

Below we create a component C for calcium oxide (notice that C here was chosen as per industry jargon, it has nothing to do with carbon) and create the multiples of the base oxides (using an extension of Base.:*) before combining them through addition (again, by extending Base.:+ operator).

A = component(:stoichiometry; Al=2, O=3)
C = component(:stoichiometry; Ca=1, O=1)

C12A7 = 12C + 7A
AuChimiste.ChemicalComponent([:Al, :Ca, :O], [14.0, 12.0, 33.0], [0.23728813559322035, 0.2033898305084746, 0.559322033898305], [0.2724141100024047, 0.3468343810969771, 0.38075150890061815], 1386.6445376000001, 0)
Meaning of operations

All operations performed over AuChimiste.ChemicalComponent instances are defined on stoichiometric coefficients, i.e. the scaling provided by multiplication acts directly on those coefficients, while combining will add coefficients for corresponding elements.

Subtraction operation (Base.:-) is also possible, but there are many conditions under which it could fail and it was chosen by design that a negative composition should return the mass imbalance instead, i.e. what lacks in A to be subtracted C and still return a valid component.

A = component(:stoichiometry; Al=2, O=3)
C = component(:stoichiometry; Ca=1, O=1)
A - C
AuChimiste.ChemicalComponent([:Ca], [1.0], [1.0], [1.0], 40.078, 0)

On the other hand, if the left component has enough of what is being subtracted by the right component, then the actual resulting component is returned:

C12A7 - C
AuChimiste.ChemicalComponent([:Al, :Ca, :O], [14.0, 11.0, 32.0], [0.24561403508771928, 0.19298245614035087, 0.5614035087719298], [0.2838950499884795, 0.3313307949742964, 0.3847741550372241], 1330.5675376000002, 0)

Charged components

For the sake of generality, charged components are also supported. This is required so that ions can be considered in reactions. For instance, to create a sodium chloride formula one can proceed as follows:

Na₊ = component(:stoichiometry; charge=+1, Na=1)
Cl₋ = component(:stoichiometry; charge=-1, Cl=1)

NaCl = Na₊ + Cl₋
AuChimiste.ChemicalComponent([:Cl, :Na], [1.0, 1.0], [0.5, 0.5], [0.6066074598985822, 0.3933925401014177], 58.43976928000001, 0)

The user must be aware of a few caveats; first, molecular mass is not corrected for the missing/extra electrons. Electron and mass balance are handled separately, as this makes more sense from a physical standpoint. Scaling of a component also scales its charge. This is required for proper balance of chemical equations.

(3Na₊).charge
3

So the formation of calcium hydroxide can be stated as:

Ca₊₂ = component(:stoichiometry; charge=+2, Ca=1)
OH₋ = component(:stoichiometry; charge=-1, O=1, H=1)

Ca₊₂ + 2OH₋
AuChimiste.ChemicalComponent([:Ca, :H, :O], [1.0, 2.0, 2.0], [0.2, 0.4, 0.4], [0.5409220968525618, 0.027209415321492198, 0.4318684878259461], 74.092, 0)

Quantities of matter

An arbitrary amount of matter can be constructed with quantity. The resulting AuChimiste.ComponentQuantity object supports both scaling (multiplication) and additive (summation) operations. A trivial example would be:

3quantity(A, 1.0)
AuChimiste.ComponentQuantity(3.0, AuChimiste.ChemicalComponent([:Al, :O], [2.0, 3.0], [0.4, 0.6], [0.5292569257852893, 0.47074307421471057], 101.9600768, 0))
Meaning of operations

On the other hand, operations performed on AuChimiste.ComponentQuantity entities are scaled by the elemental mass fractions. That is mostly intuitive in the context of application of this structure.

Well, there is nothing special there, the mass was scaled by three with no composition change. The next example is maybe more instructive: we mix one mole of A with one mole of C by providing their molar masses as the mass of each component. This is interesting because one can quickly verify the correctness of the results.

ma = quantity(A, 0.001A.molar_mass)
mc = quantity(C, 0.001C.molar_mass)
ma + mc
AuChimiste.ComponentQuantity(0.1580370768, AuChimiste.ChemicalComponent([:Al, :Ca, :O], [1.0, 0.5000000000000001, 2.0], [0.2857142857142857, 0.14285714285714288, 0.5714285714285714], [0.34145833302327955, 0.2535987175384151, 0.4049429494383055], 79.01853840000001, 0))

Because in many situations one may be interested in mixing quantities directly, a wrapper is provided for eliminating the need of and explicit creation of a component.

ma = quantity(:stoichiometry, 1.0; Al=2, O=3)
mc = quantity(:stoichiometry, 1.0; Ca=1, O=1)
ma + mc
AuChimiste.ComponentQuantity(2.0, AuChimiste.ChemicalComponent([:Al, :Ca, :O], [0.9999999999999999, 0.9091078053390873, 2.409107805339087], [0.2315771351312748, 0.21052858108590652, 0.5578942837828187], [0.2646284628926447, 0.3573479323073631, 0.37802360479999225], 101.9600768, 0))
Charge operations

Operations on electrical charges of quantities of matter are currently not supported. This functionality was initially conceived for balancing macroscopic amounts of matter and may in the future be extended for ionic substances.