Getting started with Glenn.jl
This tutorial walks through the essential workflow of the Glenn.jl library:
- Connect to the thermochemical database (bundled, no manual setup);
- Look up a chemical species;
- Compute $C_p(T)$, $H^\circ(T)$ and $S^\circ(T)$ at a given temperature.
The thermo.db database ships inside the package — just instantiate Calculator() with no arguments.
Import and connect
julia> using Glennjulia> calc = Calculator()Calculator("thermo.db")
Looking up a species
Use get_available_species with exact_match=true for case-insensitive exact lookup — "O2" returns only O₂, not Al₂O₂ or Be₃N₂.
julia> # Substring search (legacy) — shows all species containing "CH4" species = get_available_species(calc, "CH4")1-element Vector{SpeciesInfo}: SpeciesInfo(296, "CH4", nothing, "gas", 16.04246, -74600.0, 2)julia> for s in species[1:min(5, end)] println("id=", lpad(s.id, 5), " ", rpad(s.name, 12), " phase=", s.phase) endid= 296 CH4 phase=gasjulia> # Exact match (recommended) — returns only O2 o2_species = get_available_species(calc, "O2", exact_match = true)1-element Vector{SpeciesInfo}: SpeciesInfo(931, "O2", nothing, "gas", 31.9988, 0.0, 3)julia> for s in o2_species println("id=", lpad(s.id, 5), " ", rpad(s.name, 12), " phase=", s.phase, " MW=", round(something(s.molecular_weight, 0.0), digits=4)) endid= 931 O2 phase=gas MW=31.9988
Computing thermochemical properties
With the id in hand, calculate_properties(species_id, temperature) returns a ThermoProperties struct with $C_p$, $H^\circ$ (relative to 0 K) and $S^\circ$.
julia> species_ch4 = only(get_available_species(calc, "CH4", exact_match = true))SpeciesInfo(296, "CH4", nothing, "gas", 16.04246, -74600.0, 2)julia> result = calculate_properties(calc, species_ch4.id, 298.15)ThermoProperties(298.15, 35.69112257609566, -74599.57486219832, 186.3700100998424, 200.0, 1000.0, "CH4", "gas")julia> println("Species: ", result.species_name, " (", result.phase, ")")Species: CH4 (gas)julia> println("T: ", round(result.temperature, digits=2), " K")T: 298.15 Kjulia> println("Cp: ", round(result.cp, digits=3), " J/(mol·K)")Cp: 35.691 J/(mol·K)julia> println("H°: ", round(result.h_relative, digits=3), " J/mol")H°: -74599.575 J/moljulia> println("S°: ", round(result.s, digits=3), " J/(mol·K)")S°: 186.37 J/(mol·K)
Sweeping a temperature range
A common task is to evaluate $C_p$ across several temperatures.
julia> temperatures = [300.0, 500.0, 800.0, 1000.0, 1500.0]5-element Vector{Float64}: 300.0 500.0 800.0 1000.0 1500.0julia> species_id = species_ch4.id296julia> println(rpad("T (K)", 8), " | ", "Cp (J/mol·K)")T (K) | Cp (J/mol·K)julia> println("-"^27)---------------------------julia> for T in temperatures r = calculate_properties(calc, species_id, T) @printf("%8.1f | %14.3f\n", T, r.cp) endERROR: LoadError: UndefVarError: `@printf` not defined in `Main` Suggestion: check for spelling errors or missing imports. Hint: a global variable of this name also exists in Printf. in expression starting at REPL[5]:3
Enthalpy of formation
julia> for name in ["CH4", "O2", "CO2", "H2O"] sp = only(get_available_species(calc, name, exact_match = true)) h_f = calculate_formation_enthalpy(calc, sp.id) if h_f !== nothing @printf("%-8s ΔH°f(298.15 K) = %12.1f J/mol (%8.3f kJ/mol)\n", name, h_f, h_f / 1000.0) end endERROR: LoadError: UndefVarError: `@printf` not defined in `Main` Suggestion: check for spelling errors or missing imports. Hint: a global variable of this name also exists in Printf. in expression starting at REPL[1]:5
julia> close(calc)