JAX-native fusion power plant costing framework
Project description
1costingfe
JAX-native fusion power plant costing framework. Replaces the PyFECONS adapter in the fusion-tea SysML pipeline with a differentiable, 5-layer customer-first model.
Install
pip install -e .
# or with dev dependencies:
pip install -e ".[dev]"
Requires Python 3.10+.
Quick Start
from costingfe import CostModel, ConfinementConcept, Fuel
# Create a model for a DT tokamak
model = CostModel(concept=ConfinementConcept.TOKAMAK, fuel=Fuel.DT)
# Forward costing: customer requirements -> LCOE
result = model.forward(
net_electric_mw=1000.0,
availability=0.85,
lifetime_yr=30,
)
print(f"LCOE: {result.costs.lcoe:.1f} $/MWh")
print(f"Overnight cost: {result.costs.overnight_cost:.0f} $/kW")
print(f"Fusion power: {result.power_table.p_fus:.0f} MW")
Sensitivity Analysis (JAX autodiff)
sens = model.sensitivity(result.params)
# Engineering levers (sorted by |elasticity|)
for k, v in sorted(sens["engineering"].items(), key=lambda x: abs(x[1]), reverse=True):
print(f" {k:25s} {v:+.4f}")
# Financial parameters
for k, v in sens["financial"].items():
print(f" {k:25s} {v:+.4f}")
Elasticity = (dLCOE/dp) * (p/LCOE) -- dimensionless, comparable across parameters.
Batch Parameter Sweeps (JAX vmap)
# Sweep blanket thickness from 0.5m to 1.0m
lcoes = model.batch_lcoe(
{"blanket_t": [0.5, 0.6, 0.7, 0.8, 0.9, 1.0]},
result.params,
)
Cross-Concept Comparison
from costingfe import compare_all
results = compare_all(net_electric_mw=1000.0, availability=0.85, lifetime_yr=30)
for r in results[:5]:
print(f" {r.concept.value:15s} {r.fuel.value:5s} {r.lcoe:6.1f} $/MWh")
Backcasting
from costingfe.analysis.backcast import backcast_single
# What availability achieves 60 $/MWh?
avail = backcast_single(
model, target_lcoe=60.0, param_name="availability",
param_range=(0.70, 0.98), base_params=result.params,
)
Cost Overrides
Override any CAS account or CAS22 sub-account with a known value (M$). Downstream totals (CAS20, total capital, LCOE) recompute automatically.
# Override an entire CAS account
result = model.forward(
net_electric_mw=1000.0,
availability=0.85,
lifetime_yr=30,
cost_overrides={"CAS21": 50.0}, # "I know my building cost"
)
assert result.costs.cas21 == 50.0
print(result.overridden) # ["CAS21"]
# Override a CAS22 sub-account (coils)
result = model.forward(
net_electric_mw=1000.0,
availability=0.85,
lifetime_yr=30,
cost_overrides={"C220103": 300.0}, # "Use this coil cost"
)
# CAS22 total is recomputed from patched sub-accounts
print(result.cas22_detail["C220103"]) # 300.0
print(result.cas22_detail["C220000"]) # Recomputed total
Available CAS-level keys: CAS10, CAS21-CAS28.
Available CAS22 sub-account keys: C220101 (blanket), C220102 (shield), C220103 (coils), C220104 (heating), C220105 (structure), C220106 (vacuum), C220107 (power supplies), C220108 (divertor), C220109 (DEC), C220111 (installation), C220112 (isotope sep), C220200 (coolant), C220300 (aux cooling), C220400 (rad waste), C220500 (fuel handling), C220600 (other equipment), C220700 (I&C).
Sub-line convention: an account that bundles components with distinct cost bases also emits informational <CODE>_<component> keys alongside the canonical total — currently C220106_vessel and C220106_pump (vessel shell vs gas-load pumping). These sub-lines are excluded from all aggregation and are for visibility/sensitivity only; the canonical C220106 carries the sum.
CAS70 sub-accounts: CAS71 (annual O&M), CAS72 (annualized scheduled replacement — blanket/FW + divertor, PV-discounted at interest rate).
Sensitivity analysis works with overrides -- overridden accounts become constants with zero gradient:
sens = model.sensitivity(result.params, cost_overrides={"CAS21": 50.0})
Fusion-Tea Adapter
from costingfe.adapter import FusionTeaInput, run_costing
inp = FusionTeaInput(
concept="tokamak",
fuel="dt",
net_electric_mw=1000.0,
availability=0.85,
lifetime_yr=30,
)
out = run_costing(inp)
# out.lcoe, out.costs (CAS-keyed dict), out.power_table, out.sensitivity
The adapter supports two additional override mechanisms for the fusion-tea pipeline:
inp = FusionTeaInput(
concept="tokamak",
fuel="dt",
net_electric_mw=1000.0,
availability=0.85,
lifetime_yr=30,
# Inject known CAS account values (M$)
cost_overrides={"CAS21": 50.0, "C220103": 300.0},
# Override costing constants (unit costs, fractions, etc.)
costing_overrides={"blanket_unit_cost_dt": 1.0},
)
out = run_costing(inp)
print(out.overridden) # ["CAS21", "C220103"]
print(out.costs["C220103"]) # 300.0 (CAS22 sub-accounts included in costs dict)
cost_overrides-- replace computed CAS account values with known costs. Passed through toCostModel.forward().costing_overrides-- override fields onCostingConstants(unit costs, scaling coefficients). Applied viacc.replace()before model construction.out.overridden-- list of keys that were injected rather than computed.
Supported Concepts
| Family | Concept | Key features |
|---|---|---|
| MFE | tokamak |
Toroidal confinement, TF/CS/PF coils |
| MFE | stellarator |
Steady-state, complex 3D coils |
| MFE | mirror |
Cylindrical, end-loss DEC opportunity |
| IFE | laser_ife |
Split laser drivers, target factory |
| IFE | zpinch |
Pulsed power driver |
| IFE | heavy_ion |
Heavy ion accelerator |
| MIF | mag_target |
Magnetized target, liner factory |
| MIF | plasma_jet |
Plasma jet driver |
Fuels
dt-- Deuterium-Tritium (breeding blanket, heavy shielding)dd-- Deuterium-Deuterium (no breeding, moderate shielding)dhe3-- Deuterium-Helium-3 (mostly aneutronic)pb11-- Proton-Boron-11 (fully aneutronic, minimal shielding)
Engineering Overrides
Pass any engineering parameter as a keyword argument:
result = model.forward(
net_electric_mw=1000.0,
availability=0.85,
lifetime_yr=30,
eta_th=0.50, # Override thermal efficiency
blanket_t=0.90, # Thicker blanket
axis_t=7.0, # Larger major radius
)
See src/costingfe/data/defaults/ YAML files for all available parameters.
Power Cycle Selection
Select the thermal cycle used for power conversion. This sets eta_th and BOP cost
coefficients (CAS23, CAS26) appropriate for the chosen cycle.
from costingfe import CostModel, ConfinementConcept, Fuel, PowerCycle
# sCO2 Brayton cycle
model = CostModel(
concept=ConfinementConcept.TOKAMAK,
fuel=Fuel.DT,
power_cycle=PowerCycle.BRAYTON_SCO2,
)
result = model.forward(net_electric_mw=1000.0, availability=0.85, lifetime_yr=30)
Available cycles:
| Cycle | eta_th |
Description |
|---|---|---|
RANKINE (default) |
0.40 | Steam Rankine (sub/supercritical) |
BRAYTON_SCO2 |
0.47 | Supercritical CO2 recompression Brayton |
COMBINED |
0.53 | Gas topping + steam bottoming |
You can override eta_th or BOP coefficients independently:
# sCO2 Brayton but with custom efficiency
result = model.forward(
net_electric_mw=1000.0, availability=0.85, lifetime_yr=30,
eta_th=0.50, # Override preset's 0.47
)
Tests
pytest tests/ -v
Architecture
Customer Requirements (net_electric_mw, availability, lifetime_yr)
|
v
Layer 2: Physics (power balance, inverse for target p_net)
|
v
Layer 3: Engineering (radial build -> geometry -> volumes)
|
v
Layer 4: Costs (CAS 10-60 accounts, volume-based + power-scaled)
|
v
Layer 5: Economics (CAS 70-90, LCOE)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file 1costingfe-0.1.0a2.tar.gz.
File metadata
- Download URL: 1costingfe-0.1.0a2.tar.gz
- Upload date:
- Size: 1.4 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
acf2de57637753615c72254f34648e8096e8a35fde8c23bb06c0a72b65f69bd3
|
|
| MD5 |
23e44ba0167af02f41eddf3b71e89259
|
|
| BLAKE2b-256 |
e1a6a794438ae90181efa00b6499f7263f27827bcf434e14a6d50dde3c910576
|
File details
Details for the file 1costingfe-0.1.0a2-py3-none-any.whl.
File metadata
- Download URL: 1costingfe-0.1.0a2-py3-none-any.whl
- Upload date:
- Size: 122.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
38cc31d8abab61ad00485503c7483138e50b447fda65f40ff9e6fc3236dbae59
|
|
| MD5 |
de1a6c13d76e5196778feb12d25ce51c
|
|
| BLAKE2b-256 |
3adee3e11330298dde32163cd0c2562f66971c83b2d4a275c9b3545776acb3df
|