Developers

Twin APIand command line

The same functions power this site, a JSON web API and the fctwin command. Every result carries its evidence status.

Web API

GET only, JSON, CORS open. Live endpoints run the parity-tested JavaScript port; curves for the SOFC model are precomputed at build time. Full spec: OpenAPI 3.1.

curl "https://fuelcell.vassalenterprises.com/api/v1/pem/point?j_A_cm2=1.0"
curl "https://fuelcell.vassalenterprises.com/api/v1/size?power_kW=600&cell_voltage_V=0.66&j_A_cm2=1"

Command line

pip install -e .            # from a clone of psperera/fuel-cell-digital-twin-lab
fctwin --help               # every command, with examples
fctwin pem curve --T 80 --csv > pem.csv
fctwin sofc point --voltage 0.8 --T 800
fctwin compare --power-kw 2000 --year 2035
fctwin evidence --chem sofc
fctwin nyquist > sofc-record-05.csv

Python

from archee import api
api.help()                       # overview; api.help('size_stack') for one function
api.compare_aviation(power_kW=2000, year='2035')
FunctionWhat it does
pem_point(j_A_cm2: 'float', T_C: 'float' = 75.0, pressure_bar: 'float' = 2.51325, rh: 'float' = 0.6, stoich: 'float' = 2.0, water_lambda: 'float | None' = None, calibration: 'str' = 'lab') -> 'dict'One PEM cell operating point from the frozen reduced-order model.
pem_curve(T_C: 'float' = 75.0, pressure_bar: 'float' = 2.51325, rh: 'float' = 0.6, stoich: 'float' = 2.0, n: 'int' = 40, j_max_A_cm2: 'float | None' = None, calibration: 'str' = 'lab') -> 'dict'PEM polarization and power-density curve over the model's valid domain (stops before the reactant limit).
pem_water_lambda(rh: 'float', j_A_cm2: 'float', T_C: 'float') -> 'float'Assumed equilibrium membrane water content, as in the measured-challenge protocol: lambda = 3 + 11 RH + 0.7 j - 0.025 (T - 70), clipped to [2, 20].
sofc_point(voltage_V: 'float', T_C: 'float' = 800.0, steam: 'float' = 0.03, fuel_ml_min: 'float' = 50.0, nodes: 'int' = 32, settle_s: 'float' = 600.0) -> 'dict'One steady SOFC state of the frozen tubular model at a fixed terminal voltage.
sofc_curve(T_C: 'float' = 800.0, v_high: 'float' = 1.0, v_low: 'float' = 0.55, n: 'int' = 10, **kw) -> 'dict'SOFC polarization curve: steady states from v_high down to v_low (V) at n voltages.
size_stack(power_kW: 'float', chemistry: 'str', cell_voltage_V: 'float', j_A_cm2: 'float', cell_area_cm2: 'float' = 280.0, specific_power_kW_kg: 'float | list | None' = None) -> 'dict'Screening sizing of a fuel-cell stack for a net electrical power.
compare_aviation(power_kW: 'float' = 1000.0, pem_j_A_cm2: 'float' = 1.0, sofc_voltage_V: 'float' = 0.8, sofc_T_C: 'float' = 800.0, year: 'str' = '2030', pem_calibration: 'str' = 'lab', sofc_class: 'str' = 'rig') -> 'dict'PEM vs SOFC side by side for one aviation power requirement.
system_estimate(net_kW: 'float', chemistry: 'str' = 'pem', year: 'str' = '2030', sofc_basis: 'str' = 'review', cell_area_cm2: 'float' = 280.0, sofc_j_A_cm2: 'float | None' = None, pem_calibration: 'str' = 'lab', sofc_class: 'str' = 'rig') -> 'dict'Stacks to scale plus balance of plant: stack count and size, gross power, parasitic kW/kW, stack and system mass.
evidence() -> 'dict'The evidence board: headline results read from frozen outputs, each with source paths and SHA-256.
test_plan() -> 'dict'The proposed next PEM test batch (Bayesian expected information gain per rig minute).
sofc_impedance_record() -> 'dict'The frozen SOFC record-05 impedance spectrum (for Nyquist Bench), with its provenance file.