Bogue Calculation

The way in which species and cementitious species are constructed in ChemistryLab and expressed as a linear combination of reference species opens the door to equilibrium calculations. It also makes it quite natural to retrieve Bogue's formulas and use them simply.

Bogue's formulas allow us to find the masses of C3S, C2S, C3A and C4AF as a function of the oxides (CaO, SiO2, Al2O3 and Fe2O3) that are regularly found in manufacturers' cement data sheets. However, using the stoich_matrix functions performs a molar decomposition of the species that we wish to decompose as a function of reference species. It is therefore possible to express the anhydrous of the cement as a function of the oxides in a cement data sheet.

cemspecies = CemSpecies.(split("C3S C2S C3A C4AF"))
oxides = CemSpecies.(split("C S A F"))
A, indep_comp = stoich_matrix(cemspecies,oxides)
┌───┬─────┬─────┬─────┬──────┐
    C3S  C2S  C3A  C4AF 
├───┼─────┼─────┼─────┼──────┤
 C    3    2    3     4 
 S    1    1    0     0 
 A    0    0    1     1 
 F    0    0    0     1 
└───┴─────┴─────┴─────┴──────┘

Bogue's formulas are thus found by converting species into mass and inverting the matrix.

# Molar mass of anhdrous phases
Mw = map(x -> x.molar_mass, cemspecies)
# Molar mass of each oxide
Mwo = map(x -> x.molar_mass, oxides)
Aoa = Mwo .* A .* inv.(Mw)'

print_stoich_matrix(inv(Aoa), map(x -> x.name, cemspecies), map(x -> x.name, oxides))
┌──────┬──────────┬──────────┬──────────┬──────────┐
              C         S         A         F 
├──────┼──────────┼──────────┼──────────┼──────────┤
  C3S   4.07144  -7.59995  -6.71775  -1.42976 
  C2S  -3.07144   8.59995   5.06778   1.07859 
  C3A       0.0       0.0   2.64997    -1.692 
 C4AF       0.0       0.0       0.0   3.04317 
└──────┴──────────┴──────────┴──────────┴──────────┘

By taking a cement sheet with a classic percentages of oxides (CaO=65.6%; SiO2=21.5%; Al2O3=5.2% and Fe2O3=2.8%), we then obtain the anhydrous masses of the cementitious material.

inv(Aoa) *  [65.6, 21.5, 5.2, 2.8]
4-element Vector{Float64}:
 64.7516902377661
 12.78519820211983
  9.042228739095439
  8.520882821018617

Another, faster way to do this is to take advantage of the mass=true option of the canonical_stoich_matrix and stoich_matrix functions. This option allows species to be expressed as a linear combination of the reference species in mass rather than in moles.

A, indep_comp = canonical_stoich_matrix(cemspecies; mass=true)
([0.7368404916036687 0.651160900387257 0.6226371425453381 0.4615817607608128; 0.26315950839633134 0.34883909961274284 0.0 0.0; 0.0 0.0 0.3773628574546618 0.20981379075490705; 0.0 0.0 0.0 0.32860444848428016], [:C, :S, :A, :F])

Bogue's formulas are then immediate.

print_stoich_matrix(inv(A), map(x -> x.name, cemspecies), map(x -> x.name, oxides))
┌──────┬──────────┬──────────┬──────────┬──────────┐
              C         S         A         F 
├──────┼──────────┼──────────┼──────────┼──────────┤
  C3S   4.07144  -7.59995  -6.71775  -1.42976 
  C2S  -3.07144   8.59995   5.06778   1.07859 
  C3A       0.0       0.0   2.64997    -1.692 
 C4AF       0.0       0.0       0.0   3.04317 
└──────┴──────────┴──────────┴──────────┴──────────┘