///|
pub(all) struct ElementInfo {
symbol : String
name : String
atomic_number : Int
atomic_weight : Double
} derive(Debug, Eq)
///|
pub(all) struct ElementMass {
symbol : String
count : Int
atomic_weight : Double
total_mass : Double
mass_fraction : Double
} derive(Debug, Eq)
///|
fn element_info_or_none(symbol : String) -> ElementInfo? {
match symbol {
"H" =>
Some({ symbol, name: "hydrogen", atomic_number: 1, atomic_weight: 1.008 })
"He" =>
Some({ symbol, name: "helium", atomic_number: 2, atomic_weight: 4.002602 })
"Li" =>
Some({ symbol, name: "lithium", atomic_number: 3, atomic_weight: 6.94 })
"Be" =>
Some({
symbol,
name: "beryllium",
atomic_number: 4,
atomic_weight: 9.0121831,
})
"B" =>
Some({ symbol, name: "boron", atomic_number: 5, atomic_weight: 10.81 })
"C" =>
Some({ symbol, name: "carbon", atomic_number: 6, atomic_weight: 12.011 })
"N" =>
Some({ symbol, name: "nitrogen", atomic_number: 7, atomic_weight: 14.007 })
"O" =>
Some({ symbol, name: "oxygen", atomic_number: 8, atomic_weight: 15.999 })
"F" =>
Some({
symbol,
name: "fluorine",
atomic_number: 9,
atomic_weight: 18.998403163,
})
"Ne" =>
Some({ symbol, name: "neon", atomic_number: 10, atomic_weight: 20.1797 })
"Na" =>
Some({
symbol,
name: "sodium",
atomic_number: 11,
atomic_weight: 22.98976928,
})
"Mg" =>
Some({
symbol,
name: "magnesium",
atomic_number: 12,
atomic_weight: 24.305,
})
"Al" =>
Some({
symbol,
name: "aluminium",
atomic_number: 13,
atomic_weight: 26.9815385,
})
"Si" =>
Some({ symbol, name: "silicon", atomic_number: 14, atomic_weight: 28.085 })
"P" =>
Some({
symbol,
name: "phosphorus",
atomic_number: 15,
atomic_weight: 30.973761998,
})
"S" =>
Some({ symbol, name: "sulfur", atomic_number: 16, atomic_weight: 32.06 })
"Cl" =>
Some({ symbol, name: "chlorine", atomic_number: 17, atomic_weight: 35.45 })
"Ar" =>
Some({ symbol, name: "argon", atomic_number: 18, atomic_weight: 39.948 })
"K" =>
Some({
symbol,
name: "potassium",
atomic_number: 19,
atomic_weight: 39.0983,
})
"Ca" =>
Some({ symbol, name: "calcium", atomic_number: 20, atomic_weight: 40.078 })
"Sc" =>
Some({
symbol,
name: "scandium",
atomic_number: 21,
atomic_weight: 44.955908,
})
"Ti" =>
Some({
symbol,
name: "titanium",
atomic_number: 22,
atomic_weight: 47.867,
})
"V" =>
Some({
symbol,
name: "vanadium",
atomic_number: 23,
atomic_weight: 50.9415,
})
"Cr" =>
Some({
symbol,
name: "chromium",
atomic_number: 24,
atomic_weight: 51.9961,
})
"Mn" =>
Some({
symbol,
name: "manganese",
atomic_number: 25,
atomic_weight: 54.938044,
})
"Fe" =>
Some({ symbol, name: "iron", atomic_number: 26, atomic_weight: 55.845 })
"Co" =>
Some({
symbol,
name: "cobalt",
atomic_number: 27,
atomic_weight: 58.933194,
})
"Ni" =>
Some({ symbol, name: "nickel", atomic_number: 28, atomic_weight: 58.6934 })
"Cu" =>
Some({ symbol, name: "copper", atomic_number: 29, atomic_weight: 63.546 })
"Zn" =>
Some({ symbol, name: "zinc", atomic_number: 30, atomic_weight: 65.38 })
"Ga" =>
Some({ symbol, name: "gallium", atomic_number: 31, atomic_weight: 69.723 })
"Ge" =>
Some({
symbol,
name: "germanium",
atomic_number: 32,
atomic_weight: 72.63,
})
"As" =>
Some({
symbol,
name: "arsenic",
atomic_number: 33,
atomic_weight: 74.921595,
})
"Se" =>
Some({
symbol,
name: "selenium",
atomic_number: 34,
atomic_weight: 78.971,
})
"Br" =>
Some({ symbol, name: "bromine", atomic_number: 35, atomic_weight: 79.904 })
"Kr" =>
Some({ symbol, name: "krypton", atomic_number: 36, atomic_weight: 83.798 })
"Rb" =>
Some({
symbol,
name: "rubidium",
atomic_number: 37,
atomic_weight: 85.4678,
})
"Sr" =>
Some({
symbol,
name: "strontium",
atomic_number: 38,
atomic_weight: 87.62,
})
"Y" =>
Some({
symbol,
name: "yttrium",
atomic_number: 39,
atomic_weight: 88.90584,
})
"Zr" =>
Some({
symbol,
name: "zirconium",
atomic_number: 40,
atomic_weight: 91.224,
})
"Nb" =>
Some({
symbol,
name: "niobium",
atomic_number: 41,
atomic_weight: 92.90637,
})
"Mo" =>
Some({
symbol,
name: "molybdenum",
atomic_number: 42,
atomic_weight: 95.95,
})
"Tc" =>
Some({
symbol,
name: "technetium",
atomic_number: 43,
atomic_weight: 98.0,
})
"Ru" =>
Some({
symbol,
name: "ruthenium",
atomic_number: 44,
atomic_weight: 101.07,
})
"Rh" =>
Some({
symbol,
name: "rhodium",
atomic_number: 45,
atomic_weight: 102.9055,
})
"Pd" =>
Some({
symbol,
name: "palladium",
atomic_number: 46,
atomic_weight: 106.42,
})
"Ag" =>
Some({
symbol,
name: "silver",
atomic_number: 47,
atomic_weight: 107.8682,
})
"Cd" =>
Some({
symbol,
name: "cadmium",
atomic_number: 48,
atomic_weight: 112.414,
})
"In" =>
Some({ symbol, name: "indium", atomic_number: 49, atomic_weight: 114.818 })
"Sn" =>
Some({ symbol, name: "tin", atomic_number: 50, atomic_weight: 118.71 })
"Sb" =>
Some({
symbol,
name: "antimony",
atomic_number: 51,
atomic_weight: 121.76,
})
"Te" =>
Some({
symbol,
name: "tellurium",
atomic_number: 52,
atomic_weight: 127.6,
})
"I" =>
Some({
symbol,
name: "iodine",
atomic_number: 53,
atomic_weight: 126.90447,
})
"Xe" =>
Some({ symbol, name: "xenon", atomic_number: 54, atomic_weight: 131.293 })
"Cs" =>
Some({
symbol,
name: "caesium",
atomic_number: 55,
atomic_weight: 132.90545196,
})
"Ba" =>
Some({ symbol, name: "barium", atomic_number: 56, atomic_weight: 137.327 })
"La" =>
Some({
symbol,
name: "lanthanum",
atomic_number: 57,
atomic_weight: 138.90547,
})
"Ce" =>
Some({ symbol, name: "cerium", atomic_number: 58, atomic_weight: 140.116 })
"Pr" =>
Some({
symbol,
name: "praseodymium",
atomic_number: 59,
atomic_weight: 140.90766,
})
"Nd" =>
Some({
symbol,
name: "neodymium",
atomic_number: 60,
atomic_weight: 144.242,
})
"Pm" =>
Some({
symbol,
name: "promethium",
atomic_number: 61,
atomic_weight: 145.0,
})
"Sm" =>
Some({
symbol,
name: "samarium",
atomic_number: 62,
atomic_weight: 150.36,
})
"Eu" =>
Some({
symbol,
name: "europium",
atomic_number: 63,
atomic_weight: 151.964,
})
"Gd" =>
Some({
symbol,
name: "gadolinium",
atomic_number: 64,
atomic_weight: 157.25,
})
"Tb" =>
Some({
symbol,
name: "terbium",
atomic_number: 65,
atomic_weight: 158.92535,
})
"Dy" =>
Some({
symbol,
name: "dysprosium",
atomic_number: 66,
atomic_weight: 162.5,
})
"Ho" =>
Some({
symbol,
name: "holmium",
atomic_number: 67,
atomic_weight: 164.93033,
})
"Er" =>
Some({ symbol, name: "erbium", atomic_number: 68, atomic_weight: 167.259 })
"Tm" =>
Some({
symbol,
name: "thulium",
atomic_number: 69,
atomic_weight: 168.93422,
})
"Yb" =>
Some({
symbol,
name: "ytterbium",
atomic_number: 70,
atomic_weight: 173.045,
})
"Lu" =>
Some({
symbol,
name: "lutetium",
atomic_number: 71,
atomic_weight: 174.9668,
})
"Hf" =>
Some({ symbol, name: "hafnium", atomic_number: 72, atomic_weight: 178.49 })
"Ta" =>
Some({
symbol,
name: "tantalum",
atomic_number: 73,
atomic_weight: 180.94788,
})
"W" =>
Some({
symbol,
name: "tungsten",
atomic_number: 74,
atomic_weight: 183.84,
})
"Re" =>
Some({
symbol,
name: "rhenium",
atomic_number: 75,
atomic_weight: 186.207,
})
"Os" =>
Some({ symbol, name: "osmium", atomic_number: 76, atomic_weight: 190.23 })
"Ir" =>
Some({
symbol,
name: "iridium",
atomic_number: 77,
atomic_weight: 192.217,
})
"Pt" =>
Some({
symbol,
name: "platinum",
atomic_number: 78,
atomic_weight: 195.084,
})
"Au" =>
Some({
symbol,
name: "gold",
atomic_number: 79,
atomic_weight: 196.966569,
})
"Hg" =>
Some({
symbol,
name: "mercury",
atomic_number: 80,
atomic_weight: 200.592,
})
"Tl" =>
Some({
symbol,
name: "thallium",
atomic_number: 81,
atomic_weight: 204.38,
})
"Pb" =>
Some({ symbol, name: "lead", atomic_number: 82, atomic_weight: 207.2 })
"Bi" =>
Some({
symbol,
name: "bismuth",
atomic_number: 83,
atomic_weight: 208.9804,
})
"Po" =>
Some({ symbol, name: "polonium", atomic_number: 84, atomic_weight: 209.0 })
"At" =>
Some({ symbol, name: "astatine", atomic_number: 85, atomic_weight: 210.0 })
"Rn" =>
Some({ symbol, name: "radon", atomic_number: 86, atomic_weight: 222.0 })
"Fr" =>
Some({ symbol, name: "francium", atomic_number: 87, atomic_weight: 223.0 })
"Ra" =>
Some({ symbol, name: "radium", atomic_number: 88, atomic_weight: 226.0 })
"Ac" =>
Some({ symbol, name: "actinium", atomic_number: 89, atomic_weight: 227.0 })
"Th" =>
Some({
symbol,
name: "thorium",
atomic_number: 90,
atomic_weight: 232.0377,
})
"Pa" =>
Some({
symbol,
name: "protactinium",
atomic_number: 91,
atomic_weight: 231.03588,
})
"U" =>
Some({
symbol,
name: "uranium",
atomic_number: 92,
atomic_weight: 238.02891,
})
"Np" =>
Some({
symbol,
name: "neptunium",
atomic_number: 93,
atomic_weight: 237.0,
})
"Pu" =>
Some({
symbol,
name: "plutonium",
atomic_number: 94,
atomic_weight: 244.0,
})
"Am" =>
Some({
symbol,
name: "americium",
atomic_number: 95,
atomic_weight: 243.0,
})
"Cm" =>
Some({ symbol, name: "curium", atomic_number: 96, atomic_weight: 247.0 })
"Bk" =>
Some({
symbol,
name: "berkelium",
atomic_number: 97,
atomic_weight: 247.0,
})
"Cf" =>
Some({
symbol,
name: "californium",
atomic_number: 98,
atomic_weight: 251.0,
})
"Es" =>
Some({
symbol,
name: "einsteinium",
atomic_number: 99,
atomic_weight: 252.0,
})
"Fm" =>
Some({ symbol, name: "fermium", atomic_number: 100, atomic_weight: 257.0 })
"Md" =>
Some({
symbol,
name: "mendelevium",
atomic_number: 101,
atomic_weight: 258.0,
})
"No" =>
Some({
symbol,
name: "nobelium",
atomic_number: 102,
atomic_weight: 259.0,
})
"Lr" =>
Some({
symbol,
name: "lawrencium",
atomic_number: 103,
atomic_weight: 266.0,
})
"Rf" =>
Some({
symbol,
name: "rutherfordium",
atomic_number: 104,
atomic_weight: 267.0,
})
"Db" =>
Some({ symbol, name: "dubnium", atomic_number: 105, atomic_weight: 268.0 })
"Sg" =>
Some({
symbol,
name: "seaborgium",
atomic_number: 106,
atomic_weight: 269.0,
})
"Bh" =>
Some({ symbol, name: "bohrium", atomic_number: 107, atomic_weight: 270.0 })
"Hs" =>
Some({ symbol, name: "hassium", atomic_number: 108, atomic_weight: 277.0 })
"Mt" =>
Some({
symbol,
name: "meitnerium",
atomic_number: 109,
atomic_weight: 278.0,
})
"Ds" =>
Some({
symbol,
name: "darmstadtium",
atomic_number: 110,
atomic_weight: 281.0,
})
"Rg" =>
Some({
symbol,
name: "roentgenium",
atomic_number: 111,
atomic_weight: 282.0,
})
"Cn" =>
Some({
symbol,
name: "copernicium",
atomic_number: 112,
atomic_weight: 285.0,
})
"Nh" =>
Some({
symbol,
name: "nihonium",
atomic_number: 113,
atomic_weight: 286.0,
})
"Fl" =>
Some({
symbol,
name: "flerovium",
atomic_number: 114,
atomic_weight: 289.0,
})
"Mc" =>
Some({
symbol,
name: "moscovium",
atomic_number: 115,
atomic_weight: 290.0,
})
"Lv" =>
Some({
symbol,
name: "livermorium",
atomic_number: 116,
atomic_weight: 293.0,
})
"Ts" =>
Some({
symbol,
name: "tennessine",
atomic_number: 117,
atomic_weight: 294.0,
})
"Og" =>
Some({
symbol,
name: "oganesson",
atomic_number: 118,
atomic_weight: 294.0,
})
_ => None
}
}
///|
pub fn element_info(symbol : String) -> ElementInfo raise ThermoError {
match element_info_or_none(symbol) {
Some(info) => info
None => raise ThermoError::UnknownElement(symbol~)
}
}
///|
pub fn atomic_weight(symbol : String) -> Double raise ThermoError {
element_info(symbol).atomic_weight
}
///|
pub fn atomic_number(symbol : String) -> Int raise ThermoError {
element_info(symbol).atomic_number
}
///|
pub fn element_name(symbol : String) -> String raise ThermoError {
element_info(symbol).name
}
///|
pub fn is_known_element(symbol : String) -> Bool {
match element_info_or_none(symbol) {
Some(_) => true
None => false
}
}
///|
pub fn Formula::molar_mass(self : Formula) -> Double raise ThermoError {
let mut total = 0.0
for element in self.elements {
total = total + atomic_weight(element.symbol) * element.count.to_double()
}
total
}
///|
pub fn Formula::element_mass(
self : Formula,
symbol : String,
) -> Double raise ThermoError {
let count = self.count(symbol)
if count == 0 {
return 0.0
}
atomic_weight(symbol) * count.to_double()
}
///|
pub fn Formula::mass_fraction(
self : Formula,
symbol : String,
) -> Double raise ThermoError {
let mass = self.element_mass(symbol)
if mass == 0.0 {
return 0.0
}
mass / self.molar_mass()
}
///|
pub fn Formula::element_masses(
self : Formula,
) -> Array[ElementMass] raise ThermoError {
let total = self.molar_mass()
let masses : Array[ElementMass] = []
for element in self.elements {
let weight = atomic_weight(element.symbol)
let mass = weight * element.count.to_double()
masses.push({
symbol: element.symbol,
count: element.count,
atomic_weight: weight,
total_mass: mass,
mass_fraction: mass / total,
})
}
masses
}
///|
pub fn Formula::to_formula_string(self : Formula) -> String {
let mut text = ""
for element in self.elements {
text = text + element.symbol
if element.count != 1 {
text = text + element.count.to_string()
}
}
text
}