Reconcile overview¶
Loads every reactor.yaml under reactors/, reconciles each one, and renders a single variable-by-reactor table plus the plasma cross-sections.
Reactor header is red when reconciliation failed, normal otherwise.
Variable cells (a variable is used when it enters the reactor's active relation graph):
- green — input, used, value unchanged after reconcile (
value). - yellow — input, used, moved within tolerance (
input (value)). - red — input, used, moved beyond tolerance (
input → value, the culprit input is bold). - transparent + grey value — variable not used.
- transparent + normal value — value computed by reconcile.
Diagnostics (warnings, errors, failed relations) are printed inline while each reactor is solved.
In [1]:
Copied!
from pathlib import Path
import sys
import time
import warnings
import numpy as np
import matplotlib.pyplot as plt
from IPython.display import display, HTML
# Locate the project root and import the package.
root = Path.cwd().resolve()
while root != root.parent and not (root / "src" / "fusdb").is_dir():
root = root.parent
if str(root / "src") not in sys.path:
sys.path.insert(0, str(root / "src"))
from fusdb import Reactor
from fusdb.relations.geometry.plasma_geometry import sauter_cross_section_points
def fmt(x):
"""Compact number / profile formatting for table and legend cells."""
if x is None:
return ""
a = np.asarray(x, dtype=float)
if a.ndim == 0 or a.size == 1:
v = float(a.ravel()[0])
if v == 0:
return "0"
if abs(v) >= 1e4 or abs(v) < 1e-3:
return f"{v:.3e}"
return f"{v:.4g}"
return f"prof[{a.size}] mean={np.nanmean(a):.3g}"
def pick(system, name):
"""Return a variable's reconciled value, falling back to its input."""
var = system.variables_by_name.get(name)
if var is None:
return None
return var.value if var.value is not None else var.input_value
reactor_files = sorted((root / "reactors").rglob("reactor.yaml"))
print(f"Found {len(reactor_files)} reactor(s) under {root / 'reactors'}")
from pathlib import Path
import sys
import time
import warnings
import numpy as np
import matplotlib.pyplot as plt
from IPython.display import display, HTML
# Locate the project root and import the package.
root = Path.cwd().resolve()
while root != root.parent and not (root / "src" / "fusdb").is_dir():
root = root.parent
if str(root / "src") not in sys.path:
sys.path.insert(0, str(root / "src"))
from fusdb import Reactor
from fusdb.relations.geometry.plasma_geometry import sauter_cross_section_points
def fmt(x):
"""Compact number / profile formatting for table and legend cells."""
if x is None:
return ""
a = np.asarray(x, dtype=float)
if a.ndim == 0 or a.size == 1:
v = float(a.ravel()[0])
if v == 0:
return "0"
if abs(v) >= 1e4 or abs(v) < 1e-3:
return f"{v:.3e}"
return f"{v:.4g}"
return f"prof[{a.size}] mean={np.nanmean(a):.3g}"
def pick(system, name):
"""Return a variable's reconciled value, falling back to its input."""
var = system.variables_by_name.get(name)
if var is None:
return None
return var.value if var.value is not None else var.input_value
reactor_files = sorted((root / "reactors").rglob("reactor.yaml"))
print(f"Found {len(reactor_files)} reactor(s) under {root / 'reactors'}")
Found 7 reactor(s) under /home/alessmor/Scrivania/fusdb/reactors
In [2]:
Copied!
# Reconcile every reactor, printing warnings and errors as each one is solved.
records = []
for path in reactor_files:
reactor = Reactor.from_yaml(path)
system = reactor.relation_system()
started = time.perf_counter()
with warnings.catch_warnings(record=True) as caught:
warnings.simplefilter("always")
try:
result = system.run("reconcile")
except Exception as exc:
result = {"success": False, "termination": f"crashed: {exc!r}", "errors": [repr(exc)], "warnings": []}
elapsed = time.perf_counter() - started
success = bool(result.get("success", False))
relation_status = result.get("relation_status", {})
failed = [n for n, s in relation_status.items() if isinstance(s, dict) and s.get("enforced", True) and not s.get("verified", False)]
records.append({
"name": reactor.name,
"system": system,
"active": set(system.active_variable_names),
"success": success,
})
print(f"{'OK ' if success else 'FAIL'} {reactor.name} in {elapsed:.1f}s | termination={result.get('termination', '?')}")
for err in result.get("errors", []):
print(f" error: {err}")
for msg in result.get("warnings", []):
print(f" warning: {msg}")
for w in caught:
print(f" {w.category.__name__}: {w.message}")
if failed:
print(f" failed relations: {', '.join(failed)}")
# Reconcile every reactor, printing warnings and errors as each one is solved.
records = []
for path in reactor_files:
reactor = Reactor.from_yaml(path)
system = reactor.relation_system()
started = time.perf_counter()
with warnings.catch_warnings(record=True) as caught:
warnings.simplefilter("always")
try:
result = system.run("reconcile")
except Exception as exc:
result = {"success": False, "termination": f"crashed: {exc!r}", "errors": [repr(exc)], "warnings": []}
elapsed = time.perf_counter() - started
success = bool(result.get("success", False))
relation_status = result.get("relation_status", {})
failed = [n for n, s in relation_status.items() if isinstance(s, dict) and s.get("enforced", True) and not s.get("verified", False)]
records.append({
"name": reactor.name,
"system": system,
"active": set(system.active_variable_names),
"success": success,
})
print(f"{'OK ' if success else 'FAIL'} {reactor.name} in {elapsed:.1f}s | termination={result.get('termination', '?')}")
for err in result.get("errors", []):
print(f" error: {err}")
for msg in result.get("warnings", []):
print(f" warning: {msg}")
for w in caught:
print(f" {w.category.__name__}: {w.message}")
if failed:
print(f" failed relations: {', '.join(failed)}")
FAIL ARC 2015 in 9.2s | termination=The maximum number of function evaluations is exceeded.
failed relations: Total fusion power, Toroidal beta, Normalized beta, Default electron density profile from average density, Default electron temperature profile from average temperature, Default ion temperature profile from average temperature
OK ARC V3A in 8.3s | termination=Both `ftol` and `xtol` termination conditions are satisfied.
FAIL EU-DEMO 2022 in 14.5s | termination=The maximum number of function evaluations is exceeded.
failed relations: Elongation 95%, L-H transition threshold power, Total fusion power, Greenwald density fraction, Normalized beta, P_sep metric
OK Hammir 2024 in 0.1s | termination=already verified; no reconcile solve
OK INFINITY TWO 2025 in 3.0s | termination=`gtol` termination condition is satisfied.
FAIL Stellaris 2025 - Point A in 2.6s | termination=`ftol` termination condition is satisfied.
failed relations: Total fusion power
FAIL STEP 2024 EB-CC in 13.2s | termination=The maximum number of function evaluations is exceeded.
failed relations: Major radius, Aspect ratio, Elongation 95%, ST elongation vs aspect ratio, Energy confinement balance, Total fusion power, Toroidal beta, Normalized beta
In [3]:
Copied!
# Variable-by-reactor table: variables as rows, reactors as columns.
# Rows are every variable that is an input or is used in at least one reactor.
var_names = set()
for rec in records:
var_names |= rec["active"]
for name, var in rec["system"].variables_by_name.items():
if var.input_value is not None:
var_names.add(name)
var_names = sorted(var_names)
html = ["<table style='border-collapse:collapse;font-size:0.8em'>"]
html.append("<tr><th style='text-align:left;padding:2px 8px'>variable</th>")
for rec in records:
color = "#c00000" if not rec["success"] else "#1EFF00"
html.append(f"<th style='padding:2px 8px;color:{color}'>{rec['name']}</th>")
html.append("</tr>")
for name in var_names:
html.append(f"<tr><td style='text-align:left;padding:2px 8px;font-weight:bold'>{name}</td>")
for rec in records:
var = rec["system"].variables_by_name.get(name)
background = ""
color = "#000000"
text = ""
if var is not None:
has_input = var.input_value is not None
used = name in rec["active"]
inp = var.input_value
val = var.value
if has_input and used and val is not None:
ai = np.asarray(inp, dtype=float)
av = np.asarray(val, dtype=float)
try:
exact = bool(np.array_equal(ai, av))
scale = max(float(np.max(np.abs(ai))), float(np.max(np.abs(av))), 1e-300)
tol = max(float(var.abs_tol or 0.0), float(var.rel_tol or 0.0) * scale)
within = bool(np.all(np.abs(av - ai) <= tol))
except Exception:
exact, within = False, False
if exact:
background, color, text = "#c6efce", "#006100", fmt(val)
elif within:
background, color, text = "#ffeb9c", "#9c6500", f"{fmt(inp)} ({fmt(val)})"
else:
background, color, text = "#ffc7ce", "#9c0006", f"<b>{fmt(inp)}</b> → {fmt(val)}"
elif has_input and not used:
color, text = "#6E6E6E", fmt(inp)
elif (not has_input) and used and val is not None:
color, text = "#FFFFFF", fmt(val)
elif has_input and used and val is None:
color, text = "#606060", fmt(inp)
style = f"padding:2px 8px;color:{color}"
if background:
style += f";background-color:{background}"
html.append(f"<td style='{style}'>{text}</td>")
html.append("</tr>")
html.append("</table>")
display(HTML("".join(html)))
# Variable-by-reactor table: variables as rows, reactors as columns.
# Rows are every variable that is an input or is used in at least one reactor.
var_names = set()
for rec in records:
var_names |= rec["active"]
for name, var in rec["system"].variables_by_name.items():
if var.input_value is not None:
var_names.add(name)
var_names = sorted(var_names)
html = [""]
html.append("
")
display(HTML("".join(html)))
| variable | ") for rec in records: color = "#c00000" if not rec["success"] else "#1EFF00" html.append(f"{rec['name']} | ") html.append("
|---|---|
| {name} | ") for rec in records: var = rec["system"].variables_by_name.get(name) background = "" color = "#000000" text = "" if var is not None: has_input = var.input_value is not None used = name in rec["active"] inp = var.input_value val = var.value if has_input and used and val is not None: ai = np.asarray(inp, dtype=float) av = np.asarray(val, dtype=float) try: exact = bool(np.array_equal(ai, av)) scale = max(float(np.max(np.abs(ai))), float(np.max(np.abs(av))), 1e-300) tol = max(float(var.abs_tol or 0.0), float(var.rel_tol or 0.0) * scale) within = bool(np.all(np.abs(av - ai) <= tol)) except Exception: exact, within = False, False if exact: background, color, text = "#c6efce", "#006100", fmt(val) elif within: background, color, text = "#ffeb9c", "#9c6500", f"{fmt(inp)} ({fmt(val)})" else: background, color, text = "#ffc7ce", "#9c0006", f"{fmt(inp)} → {fmt(val)}" elif has_input and not used: color, text = "#6E6E6E", fmt(inp) elif (not has_input) and used and val is not None: color, text = "#FFFFFF", fmt(val) elif has_input and used and val is None: color, text = "#606060", fmt(inp) style = f"padding:2px 8px;color:{color}" if background: style += f";background-color:{background}" html.append(f"{text} | ") html.append("
| variable | ARC 2015 | ARC V3A | EU-DEMO 2022 | Hammir 2024 | INFINITY TWO 2025 | Stellaris 2025 - Point A | STEP 2024 EB-CC |
|---|---|---|---|---|---|---|---|
| A | 2.92 | 3.915 | 3.1 | 10 | 9.8 | 1.8 | |
| A_p | 232.4 | 257 → 292.8 | 1591 | 327 | 369.8 | ||
| B0 | 9.2 → 9.695 | 11.4 | 5.86 → 4.118 | 9 (9) | 3.2 → 2.073 | ||
| B_max | 23 | 12 | |||||
| G89 | 0.14 | ||||||
| H89 | 2.8 | ||||||
| H98_y2 | 1.8 | 0.98 | 1.03 | ||||
| I_p | 7.800e+06 (7.799e+06) | 1.200e+07 | 1.775e+07 → 1.972e+07 | 1.603e+09 | 2.270e+07 → 2.934e+06 | ||
| L_p | 11.21 | 10.66 | 29.64 | 17.6 | |||
| P_LH | 1.208e+08 (1.210e+08) | 1.673e+07 | |||||
| P_aux | 2.194e+07 | 2.000e+08 | 2.000e+07 | 5.000e+07 | 1.300e+08 | ||
| P_brem | 7.254e+07 | 1.032e+08 | 3.977e+06 | ||||
| P_charged | 1.480e+08 | 2.228e+08 | 2.567e+08 | 1.593e+08 | 1.050e+09 | 4.914e+06 | |
| P_elec_tot | 4.000e+08 | ||||||
| P_fus | 5.250e+08 (5.252e+08) | 1.130e+09 (1.119e+09) | 2.000e+09 (1.984e+09) | 8.000e+08 | 2.700e+09 (2.700e+09) | 1.560e+09 (1.560e+09) | |
| P_fus_DD | 9.338e+05 | 1.197e+06 | 1.410e+06 | 9.602e+05 | 5.602e+06 | 3.083e+04 | |
| P_fus_DDn | 3.987e+05 | 5.191e+05 | 6.189e+05 | 4.246e+05 | 2.439e+06 | 1.366e+04 | |
| P_fus_DDn_He3 | 9.998e+04 | 1.302e+05 | 1.552e+05 | 1.065e+05 | 6.117e+05 | 3427 | |
| P_fus_DDn_n | 2.987e+05 | 3.889e+05 | 4.637e+05 | 3.181e+05 | 1.828e+06 | 1.024e+04 | |
| P_fus_DDp | 5.351e+05 | 6.777e+05 | 7.913e+05 | 5.356e+05 | 3.163e+06 | 1.717e+04 | |
| P_fus_DDp_T | 1.341e+05 | 1.698e+05 | 1.983e+05 | 1.342e+05 | 7.927e+05 | 4303 | |
| P_fus_DDp_p | 4.010e+05 | 5.079e+05 | 5.930e+05 | 4.014e+05 | 2.370e+06 | 1.287e+04 | |
| P_fus_DHe3 | 0.001497 | 7.988e-04 | 4.223e-04 | 1.452e-04 | 0.002952 | 3.675e-06 | |
| P_fus_DHe3_alpha | 2.944e-04 | 1.571e-04 | 8.308e-05 | 2.857e-05 | 5.807e-04 | 7.230e-07 | |
| P_fus_DHe3_p | 0.001202 | 6.417e-04 | 3.392e-04 | 1.167e-04 | 0.002371 | 2.952e-06 | |
| P_fus_DT | 7.411e+08 | 1.116e+09 | 1.286e+09 | 7.979e+08 | 5.261e+09 | 2.461e+07 | |
| P_fus_DT_alpha | 1.474e+08 | 2.219e+08 | 2.557e+08 | 1.587e+08 | 1.046e+09 | 4.893e+06 | |
| P_fus_DT_n | 5.937e+08 | 8.941e+08 | 1.030e+09 | 6.393e+08 | 4.215e+09 | 1.971e+07 | |
| P_fus_TT | 1.296e+06 | 1.624e+06 | 1.775e+06 | 1.109e+06 | 7.461e+06 | 3.442e+04 | |
| P_loss | 2.438e+08 | 1.974e+08 | 3.030e+08 | 5.322e+08 | 4.581e+08 | ||
| P_neutron | 5.940e+08 | 8.945e+08 | 1.031e+09 | 6.396e+08 | 4.217e+09 | 1.972e+07 | |
| P_rad | 2.970e+08 | ||||||
| P_sep | 1.704e+08 (1.705e+08) | ||||||
| P_sep_B_over_q95AR | 9.200e+06 (9.191e+06) | ||||||
| P_sep_over_R | 1.890e+07 (1.890e+07) | ||||||
| P_wall | 4.050e+06 | ||||||
| Q_sci | 51 (51) | 9.918 | 40 | 54 | 12 (12) | ||
| R | 3.3 | 4.62 | 9 | 12.5 | 12.74 | 3.6 | |
| R_max | 4.43 | 5.8 | 11.9 | 13.75 | 14.04 | 2.682 | |
| R_min | 2.17 | 3.44 | 6.1 | 11.25 | 11.44 | 0.2177 | |
| Rr_DDn | 7.610e+17 | 9.908e+17 | 1.181e+18 | 8.104e+17 | 4.656e+18 | 2.608e+16 | |
| Rr_DDp | 8.287e+17 | 1.050e+18 | 1.226e+18 | 8.295e+17 | 4.899e+18 | 2.659e+16 | |
| Rr_DHe3 | 5.104e+08 | 2.725e+08 | 1.440e+08 | 4.953e+07 | 1.007e+09 | 1.253e+06 | |
| Rr_DT | 2.628e+20 | 3.958e+20 | 4.560e+20 | 2.830e+20 | 1.866e+21 | 8.726e+18 | |
| Rr_He3He3 | 9.801e-06 | 1.400e-06 | 2.299e-07 | 2.774e-08 | 3.689e-06 | 4.831e-10 | |
| Rr_THe3 | 2.463e+07 | 1.412e+07 | 7.402e+06 | 2.443e+06 | 5.233e+07 | 6.060e+04 | |
| Rr_THe3_D | 1.012e+07 | 5.815e+06 | 3.053e+06 | 1.008e+06 | 2.156e+07 | 2.503e+04 | |
| Rr_THe3_np | 1.452e+07 | 8.305e+06 | 4.349e+06 | 1.434e+06 | 3.077e+07 | 3.557e+04 | |
| Rr_TT | 7.161e+17 | 8.970e+17 | 9.804e+17 | 6.123e+17 | 4.121e+18 | 1.901e+16 | |
| S_phi | 7.381 | 6.725 | 48.93 | 14.01 | |||
| T0 | 27 | ||||||
| TBR | 1.1 | 1.3 | |||||
| T_avg | 14 → 14.86 | 13.54 | 12.49 → 9.177 | 150 | 6.8 | 12 (12) | 9.69 → 6.161 |
| T_e | prof[46] mean=15 | prof[46] mean=13.5 | prof[46] mean=9.18 | prof[46] mean=6.8 | prof[46] mean=12 | prof[46] mean=6.16 | |
| T_i | prof[46] mean=15 | prof[46] mean=13.5 | prof[46] mean=9.18 | prof[46] mean=6.8 | prof[46] mean=12 | prof[46] mean=6.16 | |
| T_i_avg | 15.01 | 100 | 9.177 | 6.8 | 12 | 6.161 | |
| V_p | 153 (152.8) | 189 → 187 | 2656 | 46 | 838.4 | 425 (425) | 299.4 |
| W_th | 1.653e+08 | 2.310e+08 → 2.354e+08 | 1.018e+09 | 5.152e+08 | 7.771e+08 | 5.735e+07 | |
| Z_eff | 2.12 | 1.2 | 2.31 | ||||
| a | 1.13 | 1.18 | 2.9 | 1.25 | 1.3 | 1.232 | |
| afuel | 2.5 | 2.5 | 2.5 (2.491) | 2.5 | 2.5 | 2.5 | |
| beta_N | 2.59 (2.59) | 1.819 | 2.5 (2.5) | 0.0276 | 0.0393 (0.03928) | ||
| beta_T | 0.019 (0.01897) | 0.01622 | 0.03786 | 0.03782 | 0.139 (0.139) | ||
| beta_limit | 0.01993 | 0.02498 | 0.04623 | 0.03216 | |||
| delta | 0.003397 | 0.65 (0.6547) | 0.495 | 0.4001 | |||
| delta_95 | 0.002265 | 0.4365 | 0.33 | 0.2667 | |||
| eps | 0.3425 | 0.26 → 0.2554 | 0.3226 | 0.1 | 0.102 | 0.5556 | |
| f_BS | 0.63 | ||||||
| f_CD | 0.05 | ||||||
| f_D | 0.5 (0.5007) | 0.5 (0.5025) | 0.5 | 0.5 | 0.5 | 0.5 | |
| f_GW | 0.67 | 0.7067 | 1.2 → 1.183 | 1.052 | |||
| f_He3 | 1.000e-10 | 1.000e-10 | 1.000e-10 | 1.000e-10 | 1.000e-10 | 1.000e-10 | |
| f_He4 | 1.000e-10 | 1.000e-10 | 1.000e-10 | 1.000e-10 | 1.000e-10 | 1.000e-10 | |
| f_Imp | 1.000e-10 | 1.000e-10 | 1.000e-10 | 1.000e-10 | 1.000e-10 | 1.000e-10 | |
| f_NI | 0.39 | ||||||
| f_T | 0.5 (0.5004) | 0.5 (0.5025) | 0.5 | 0.5 | 0.5 | 0.5 | |
| greenwald_margin | -6.517e+19 | -8.047e+19 | 1.224e+19 | 3.177e+18 | |||
| kappa | 1.84 | 1.8 → 1.587 | 1.91 | 3 | |||
| kappa_95 | 1.643 | 1.417 | 1.65 | 2.8 | |||
| kappa_ipb | 1.837 | 1.473 | 1.778 | 2.175 | 1 | 2.776 | |
| li | 0.67 | ||||||
| n0 | 1.800e+20 | 5.060e+20 | |||||
| n_D | prof[46] mean=6.99e+19 | prof[46] mean=9.69e+19 | prof[46] mean=4.34e+19 | prof[46] mean=9.4e+19 | prof[46] mean=1.58e+20 | prof[46] mean=3.23e+19 | |
| n_GW | 1.944e+20 | 2.743e+20 | 7.463e+19 | 6.152e+19 | |||
| n_He3 | prof[46] mean=1.4e+10 | prof[46] mean=1.93e+10 | prof[46] mean=8.69e+09 | prof[46] mean=1.88e+10 | prof[46] mean=3.17e+10 | prof[46] mean=6.47e+09 | |
| n_He4 | prof[46] mean=1.4e+10 | prof[46] mean=1.93e+10 | prof[46] mean=8.69e+09 | prof[46] mean=1.88e+10 | prof[46] mean=3.17e+10 | prof[46] mean=6.47e+09 | |
| n_SUDO | 5.562e+21 | ||||||
| n_T | prof[46] mean=6.99e+19 | prof[46] mean=9.69e+19 | prof[46] mean=4.34e+19 | prof[46] mean=9.4e+19 | prof[46] mean=1.58e+20 | prof[46] mean=3.23e+19 | |
| n_avg | 1.300e+20 (1.292e+20) | 1.939e+20 | 8.687e+19 | 7.500e+19 | 1.880e+20 (1.880e+20) | 3.170e+20 (3.170e+20) | 1.640e+20 → 6.470e+19 |
| n_e | prof[46] mean=1.4e+20 | prof[46] mean=1.94e+20 | prof[46] mean=8.69e+19 | prof[46] mean=1.88e+20 | prof[46] mean=3.17e+20 | prof[46] mean=6.47e+19 | |
| n_i | prof[46] mean=1.4e+20 | prof[46] mean=1.93e+20 | prof[46] mean=8.69e+19 | prof[46] mean=1.88e+20 | prof[46] mean=3.17e+20 | prof[46] mean=6.47e+19 | |
| n_i_avg | 1.396e+20 | 8.687e+19 | 1.880e+20 | 3.170e+20 | 6.470e+19 | ||
| n_imp | prof[46] mean=1.4e+10 | prof[46] mean=1.93e+10 | prof[46] mean=8.69e+09 | prof[46] mean=1.88e+10 | prof[46] mean=3.17e+10 | prof[46] mean=6.47e+09 | |
| n_la | 1.292e+20 | 1.939e+20 | 8.687e+19 | 1.880e+20 | 3.170e+20 | 6.470e+19 | |
| p_th | 7.212e+05 | 8.390e+05 | 2.555e+05 | 4.096e+05 | 1.219e+06 | 1.277e+05 | |
| q95 | 7.2 | 3.89 (3.885) | 8.03 | ||||
| q_a | 4.7 | ||||||
| q_min | 3.5 | ||||||
| rho | prof[46] mean=0.5 | prof[46] mean=0.5 | prof[46] mean=0.5 | prof[46] mean=0.5 | prof[46] mean=0.5 | prof[46] mean=0.5 | prof[46] mean=0.5 |
| sigmav_DD | prof[46] mean=3.4e-24 | prof[46] mean=2.32e-24 | prof[46] mean=9.61e-25 | prof[46] mean=4.43e-25 | prof[46] mean=1.79e-24 | prof[46] mean=3.36e-25 | |
| sigmav_DDn | prof[46] mean=1.63e-24 | prof[46] mean=1.13e-24 | prof[46] mean=4.71e-25 | prof[46] mean=2.19e-25 | prof[46] mean=8.72e-25 | prof[46] mean=1.67e-25 | |
| sigmav_DDp | prof[46] mean=1.77e-24 | prof[46] mean=1.19e-24 | prof[46] mean=4.89e-25 | prof[46] mean=2.24e-25 | prof[46] mean=9.18e-25 | prof[46] mean=1.7e-25 | |
| sigmav_DHe3 | prof[46] mean=2.59e-24 | prof[46] mean=7.79e-25 | prof[46] mean=1.44e-25 | prof[46] mean=3.34e-26 | prof[46] mean=4.71e-25 | prof[46] mean=2e-26 | |
| sigmav_DT | prof[46] mean=2.84e-22 | prof[46] mean=2.25e-22 | prof[46] mean=9.1e-23 | prof[46] mean=3.82e-23 | prof[46] mean=1.75e-22 | prof[46] mean=2.79e-23 | |
| sigmav_He3He3 | prof[46] mean=4.86e-28 | prof[46] mean=4.02e-29 | prof[46] mean=2.29e-30 | prof[46] mean=1.87e-31 | prof[46] mean=1.73e-29 | prof[46] mean=7.71e-32 | |
| sigmav_THe3 | prof[46] mean=1.26e-25 | prof[46] mean=4.04e-26 | prof[46] mean=7.38e-27 | prof[46] mean=1.65e-27 | prof[46] mean=2.45e-26 | prof[46] mean=9.67e-28 | |
| sigmav_THe3_D | prof[46] mean=5.16e-26 | prof[46] mean=1.66e-26 | prof[46] mean=3.05e-27 | prof[46] mean=6.81e-28 | prof[46] mean=1.01e-26 | prof[46] mean=3.99e-28 | |
| sigmav_THe3_np | prof[46] mean=7.4e-26 | prof[46] mean=2.37e-26 | prof[46] mean=4.34e-27 | prof[46] mean=9.68e-28 | prof[46] mean=1.44e-26 | prof[46] mean=5.68e-28 | |
| sigmav_TT | prof[46] mean=1.53e-24 | prof[46] mean=1.02e-24 | prof[46] mean=3.91e-25 | prof[46] mean=1.65e-25 | prof[46] mean=7.72e-25 | prof[46] mean=1.21e-25 | |
| squareness | 0 | 0.02616 | 0 (6.745e-04) | 0 | 0 | 0 | |
| sudo_margin | -5.245e+21 | ||||||
| tau_E | 0.64 → 0.678 | 5.158 | 1.7 | 1.46 (1.46) | 0.1252 | ||
| tau_p | 1 | 11 | |||||
| tau_pulse | 7200 | ||||||
| troyon_margin | -9.664e-04 | -0.008753 | -0.008367 | 0.1068 |
In [4]:
Copied!
# Plasma cross-sections, with reactor geometry summarised in the legend below.
fig, ax = plt.subplots(figsize=(7, 8))
for rec in records:
system = rec["system"]
R = pick(system, "R")
a = pick(system, "a")
kappa = pick(system, "kappa")
delta = pick(system, "delta")
xi = pick(system, "squareness") or 0.0
V_p = pick(system, "V_p")
if None in (R, a, kappa, delta):
continue
r_pts, z_pts = sauter_cross_section_points(float(R), float(a), kappa=float(kappa), delta=float(delta), squareness=float(xi), n=256)
vp_text = fmt(V_p) if V_p is not None else "—"
label = f"{rec['name']} R: {fmt(R)} a: {fmt(a)} k: {fmt(kappa)} δ: {fmt(delta)} ξ: {fmt(xi)} V_p: {vp_text}"
ax.plot(r_pts, z_pts, label=label)
ax.set_aspect("equal")
ax.set_xlabel("R [m]")
ax.set_ylabel("Z [m]")
ax.set_title("Plasma cross-sections")
ax.grid(True, alpha=0.3)
ax.legend(loc="upper center", bbox_to_anchor=(0.5, -0.10), fontsize=8, frameon=False)
fig.tight_layout()
plt.show()
# Plasma cross-sections, with reactor geometry summarised in the legend below.
fig, ax = plt.subplots(figsize=(7, 8))
for rec in records:
system = rec["system"]
R = pick(system, "R")
a = pick(system, "a")
kappa = pick(system, "kappa")
delta = pick(system, "delta")
xi = pick(system, "squareness") or 0.0
V_p = pick(system, "V_p")
if None in (R, a, kappa, delta):
continue
r_pts, z_pts = sauter_cross_section_points(float(R), float(a), kappa=float(kappa), delta=float(delta), squareness=float(xi), n=256)
vp_text = fmt(V_p) if V_p is not None else "—"
label = f"{rec['name']} R: {fmt(R)} a: {fmt(a)} k: {fmt(kappa)} δ: {fmt(delta)} ξ: {fmt(xi)} V_p: {vp_text}"
ax.plot(r_pts, z_pts, label=label)
ax.set_aspect("equal")
ax.set_xlabel("R [m]")
ax.set_ylabel("Z [m]")
ax.set_title("Plasma cross-sections")
ax.grid(True, alpha=0.3)
ax.legend(loc="upper center", bbox_to_anchor=(0.5, -0.10), fontsize=8, frameon=False)
fig.tight_layout()
plt.show()