d0fus 2.2.2__tar.gz → 2.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {d0fus-2.2.2 → d0fus-2.3.0}/D0FUS.py +30 -3
- {d0fus-2.2.2 → d0fus-2.3.0}/D0FUS_BIB/D0FUS_figures.py +104 -19
- {d0fus-2.2.2 → d0fus-2.3.0}/D0FUS_BIB/D0FUS_import.py +5 -1
- {d0fus-2.2.2 → d0fus-2.3.0}/D0FUS_BIB/D0FUS_parameterization.py +50 -6
- {d0fus-2.2.2 → d0fus-2.3.0}/D0FUS_BIB/D0FUS_physical_functions.py +239 -29
- {d0fus-2.2.2 → d0fus-2.3.0}/D0FUS_BIB/D0FUS_radial_build_functions.py +258 -66
- d0fus-2.3.0/D0FUS_EXE/D0FUS_genetic.py +2959 -0
- {d0fus-2.2.2 → d0fus-2.3.0}/D0FUS_EXE/D0FUS_run.py +168 -28
- {d0fus-2.2.2 → d0fus-2.3.0}/D0FUS_EXE/D0FUS_scan.py +15 -5
- {d0fus-2.2.2 → d0fus-2.3.0}/PKG-INFO +1 -1
- {d0fus-2.2.2 → d0fus-2.3.0}/d0fus.egg-info/PKG-INFO +1 -1
- {d0fus-2.2.2 → d0fus-2.3.0}/pyproject.toml +1 -1
- d0fus-2.2.2/D0FUS_EXE/D0FUS_genetic.py +0 -1335
- {d0fus-2.2.2 → d0fus-2.3.0}/D0FUS_BIB/D0FUS_cost_data.py +0 -0
- {d0fus-2.2.2 → d0fus-2.3.0}/D0FUS_BIB/D0FUS_cost_functions.py +0 -0
- {d0fus-2.2.2 → d0fus-2.3.0}/LICENSE +0 -0
- {d0fus-2.2.2 → d0fus-2.3.0}/README.md +0 -0
- {d0fus-2.2.2 → d0fus-2.3.0}/d0fus.egg-info/SOURCES.txt +0 -0
- {d0fus-2.2.2 → d0fus-2.3.0}/d0fus.egg-info/dependency_links.txt +0 -0
- {d0fus-2.2.2 → d0fus-2.3.0}/d0fus.egg-info/entry_points.txt +0 -0
- {d0fus-2.2.2 → d0fus-2.3.0}/d0fus.egg-info/requires.txt +0 -0
- {d0fus-2.2.2 → d0fus-2.3.0}/d0fus.egg-info/top_level.txt +0 -0
- {d0fus-2.2.2 → d0fus-2.3.0}/setup.cfg +0 -0
|
@@ -170,12 +170,39 @@ def detect_mode_from_input(input_file):
|
|
|
170
170
|
#%% Main functions
|
|
171
171
|
|
|
172
172
|
def print_banner():
|
|
173
|
-
"""Display D0FUS banner
|
|
174
|
-
|
|
173
|
+
"""Display the D0FUS startup banner.
|
|
174
|
+
|
|
175
|
+
Simple double-line framed banner with title, tagline, version, author,
|
|
176
|
+
license and repository URL. Can be silenced with the environment variable
|
|
177
|
+
``D0FUS_NO_BANNER`` (useful for batch scans, HPC jobs, CI).
|
|
178
|
+
"""
|
|
179
|
+
if os.environ.get("D0FUS_NO_BANNER", "").strip() not in ("", "0", "false", "False"):
|
|
180
|
+
return
|
|
181
|
+
|
|
182
|
+
# Resolve installed package version, fall back to a static string
|
|
183
|
+
try:
|
|
184
|
+
from importlib.metadata import version, PackageNotFoundError
|
|
185
|
+
try:
|
|
186
|
+
v = version("d0fus")
|
|
187
|
+
except PackageNotFoundError:
|
|
188
|
+
v = "dev"
|
|
189
|
+
except ImportError:
|
|
190
|
+
v = "dev"
|
|
191
|
+
|
|
192
|
+
# The version is the only dynamic line; the others are hardcoded for clarity.
|
|
193
|
+
# Inside width is 51 characters; the version is centered programmatically.
|
|
194
|
+
version_line = f"Version {v}".center(51)
|
|
195
|
+
|
|
196
|
+
banner = f"""
|
|
175
197
|
╔═══════════════════════════════════════════════════╗
|
|
176
198
|
║ ║
|
|
177
199
|
║ D0FUS ║
|
|
178
|
-
║
|
|
200
|
+
║ Design 0-dimensional for Fusion Systems ║
|
|
201
|
+
║ ║
|
|
202
|
+
╠═══════════════════════════════════════════════════╣
|
|
203
|
+
║{version_line}║
|
|
204
|
+
║ T. Auclair, CEA-IRFM | CeCILL-C ║
|
|
205
|
+
║ https://github.com/IRFM/D0FUS ║
|
|
179
206
|
║ ║
|
|
180
207
|
╚═══════════════════════════════════════════════════╝
|
|
181
208
|
"""
|
|
@@ -49,6 +49,7 @@ if __name__ != "__main__":
|
|
|
49
49
|
f_He_fraction,
|
|
50
50
|
f_q_profile,
|
|
51
51
|
f_sigmav,
|
|
52
|
+
_two_point_core, M_F_DT,
|
|
52
53
|
)
|
|
53
54
|
from .D0FUS_radial_build_functions import (
|
|
54
55
|
J_non_Cu_NbTi, J_non_Cu_Nb3Sn, J_non_Cu_REBCO,
|
|
@@ -78,6 +79,7 @@ else:
|
|
|
78
79
|
f_He_fraction,
|
|
79
80
|
f_q_profile,
|
|
80
81
|
f_sigmav,
|
|
82
|
+
_two_point_core, M_F_DT,
|
|
81
83
|
)
|
|
82
84
|
from D0FUS_BIB.D0FUS_radial_build_functions import (
|
|
83
85
|
J_non_Cu_NbTi, J_non_Cu_Nb3Sn, J_non_Cu_REBCO,
|
|
@@ -2214,6 +2216,85 @@ def plot_radiation_profile(
|
|
|
2214
2216
|
_save_or_show(fig, save_dir, "run_radiation_profile")
|
|
2215
2217
|
|
|
2216
2218
|
|
|
2219
|
+
def plot_divertor_two_point(
|
|
2220
|
+
run: dict,
|
|
2221
|
+
n_pts: int = 300,
|
|
2222
|
+
save_dir: str | None = None,
|
|
2223
|
+
) -> None:
|
|
2224
|
+
"""
|
|
2225
|
+
Simple two-point-model view: target temperature versus SOL dissipation.
|
|
2226
|
+
|
|
2227
|
+
A single panel shows the target electron temperature T_et as a function of
|
|
2228
|
+
the SOL power-loss fraction f_cooling, at the converged upstream conditions
|
|
2229
|
+
(q_par_u, p_u read from the run). The dashed line is the detachment
|
|
2230
|
+
threshold T_et = 10 eV (Stangeby 2018). The flat plateau at high T_et is the
|
|
2231
|
+
attached sheath-limited branch where the two-point model no longer applies.
|
|
2232
|
+
The minimum dissipation required for target survival (Eq. 14) is given in
|
|
2233
|
+
the title and marked by the dotted vertical line.
|
|
2234
|
+
|
|
2235
|
+
Parameters
|
|
2236
|
+
----------
|
|
2237
|
+
run : dict D0FUS run output; reads the 'divertor' sub-dict produced
|
|
2238
|
+
by f_heat_two_point.
|
|
2239
|
+
n_pts : int Number of f_cooling samples.
|
|
2240
|
+
save_dir : str or None
|
|
2241
|
+
|
|
2242
|
+
References
|
|
2243
|
+
----------
|
|
2244
|
+
P.C. Stangeby, Plasma Phys. Control. Fusion 60 (2018) 044022.
|
|
2245
|
+
"""
|
|
2246
|
+
div = run.get("divertor", {}) or {}
|
|
2247
|
+
if not {"q_par_u", "T_eu", "n_sep"}.issubset(div):
|
|
2248
|
+
print(" [skip] no two-point-model divertor solution in run dict")
|
|
2249
|
+
return
|
|
2250
|
+
|
|
2251
|
+
q_par_u = div["q_par_u"] # [MW/m^2]
|
|
2252
|
+
T_eu = div["T_eu"] # [eV]
|
|
2253
|
+
n_sep = div["n_sep"] # [m^-3]
|
|
2254
|
+
f_c_op = div.get("f_cooling", 0.0)
|
|
2255
|
+
f_m_op = div.get("f_mom", 0.0)
|
|
2256
|
+
T_et_op = div.get("T_et", np.nan)
|
|
2257
|
+
f_pwr_req = div.get("f_pwr_loss_req", np.nan)
|
|
2258
|
+
R0 = run.get("R0", "?")
|
|
2259
|
+
|
|
2260
|
+
q_par_u_SI = q_par_u * 1e6
|
|
2261
|
+
p_u = 2.0 * n_sep * E_ELEM * T_eu
|
|
2262
|
+
|
|
2263
|
+
f_c = np.linspace(0.0, 0.995, n_pts)
|
|
2264
|
+
T_et = np.array([min(_two_point_core(q_par_u_SI, p_u, fc, f_m_op, 7.0, M_F_DT)[0],
|
|
2265
|
+
T_eu) for fc in f_c])
|
|
2266
|
+
|
|
2267
|
+
fig, ax = plt.subplots(figsize=(7, 4.5))
|
|
2268
|
+
ax.plot(f_c, T_et, color="#4477AA", lw=2.4)
|
|
2269
|
+
ax.axhline(10.0, color="#EE6677", lw=1.3, ls="--")
|
|
2270
|
+
ax.text(0.015, 11.0, "detachment (10 eV)", color="#EE6677",
|
|
2271
|
+
fontsize=9, va="bottom")
|
|
2272
|
+
if np.isfinite(f_pwr_req):
|
|
2273
|
+
ax.axvline(f_pwr_req, color="0.55", lw=1.0, ls=":")
|
|
2274
|
+
if np.isfinite(T_et_op):
|
|
2275
|
+
ax.plot([f_c_op], [T_et_op], "o", ms=9, color="k", zorder=5)
|
|
2276
|
+
near_left = f_c_op < 0.5
|
|
2277
|
+
near_top = T_et_op > 0.3 * T_eu
|
|
2278
|
+
ax.annotate(f"operating point\n$T_{{e,t}}$ = {T_et_op:.1f} eV",
|
|
2279
|
+
(f_c_op, T_et_op), textcoords="offset points",
|
|
2280
|
+
xytext=(14 if near_left else -12, -16 if near_top else 14),
|
|
2281
|
+
ha="left" if near_left else "right",
|
|
2282
|
+
va="top" if near_top else "bottom", fontsize=9)
|
|
2283
|
+
|
|
2284
|
+
ax.set_yscale("log")
|
|
2285
|
+
ax.set_xlim(0, 1)
|
|
2286
|
+
ax.set_xlabel(r"SOL power-loss fraction $f_{\rm cooling}$", fontsize=12)
|
|
2287
|
+
ax.set_ylabel(r"Target electron temperature $T_{e,t}$ [eV]", fontsize=12)
|
|
2288
|
+
ttl = (rf"Divertor two-point model: $R_0$={R0} m, "
|
|
2289
|
+
rf"$q_{{\parallel u}}$={q_par_u/1e3:.2f} GW/m$^2$")
|
|
2290
|
+
if np.isfinite(f_pwr_req):
|
|
2291
|
+
ttl += f", required dissipation = {f_pwr_req:.2f}"
|
|
2292
|
+
ax.set_title(ttl, fontsize=11)
|
|
2293
|
+
ax.grid(True, which="both", alpha=0.3)
|
|
2294
|
+
plt.tight_layout()
|
|
2295
|
+
_save_or_show(fig, save_dir, "run_divertor_two_point")
|
|
2296
|
+
|
|
2297
|
+
|
|
2217
2298
|
# ---------------------------------------------------------------------------
|
|
2218
2299
|
# A — Convenience wrapper
|
|
2219
2300
|
# ---------------------------------------------------------------------------
|
|
@@ -2998,23 +3079,24 @@ def plot_run(
|
|
|
2998
3079
|
save_dir: str | None = None,
|
|
2999
3080
|
) -> None:
|
|
3000
3081
|
"""
|
|
3001
|
-
Render the run-specific figure set (
|
|
3082
|
+
Render the run-specific figure set (11 figures).
|
|
3002
3083
|
|
|
3003
3084
|
This is the subset called after each D0FUS run. It contains only the
|
|
3004
3085
|
figures that depend on the current run configuration and results —
|
|
3005
3086
|
no validation curves, no benchmarks, no scaling-law surveys.
|
|
3006
3087
|
|
|
3007
3088
|
Figures produced:
|
|
3008
|
-
[ 1/
|
|
3009
|
-
[ 2/
|
|
3010
|
-
[ 3/
|
|
3011
|
-
[ 4/
|
|
3012
|
-
[ 5/
|
|
3013
|
-
[ 6/
|
|
3014
|
-
[ 7/
|
|
3015
|
-
[ 8/
|
|
3016
|
-
[ 9/
|
|
3017
|
-
[10/
|
|
3089
|
+
[ 1/11] Tokamak LCFS comparison (with D0FUS overlay)
|
|
3090
|
+
[ 2/11] Miller flux surfaces (run geometry)
|
|
3091
|
+
[ 3/11] Shaping profiles κ(ρ), δ(ρ)
|
|
3092
|
+
[ 4/11] Kinetic profiles n(ρ), T(ρ), p(ρ)
|
|
3093
|
+
[ 5/11] Safety factor q(ρ) and current decomposition
|
|
3094
|
+
[ 6/11] Radiation profiles
|
|
3095
|
+
[ 7/11] Divertor two-point model (detachment vs SOL dissipation)
|
|
3096
|
+
[ 8/11] TF coil side view
|
|
3097
|
+
[ 9/11] CICC TF conductor
|
|
3098
|
+
[10/11] CS cross-section
|
|
3099
|
+
[11/11] CICC CS conductor
|
|
3018
3100
|
|
|
3019
3101
|
Parameters
|
|
3020
3102
|
----------
|
|
@@ -3023,7 +3105,7 @@ def plot_run(
|
|
|
3023
3105
|
If provided, figures are saved as PNG files.
|
|
3024
3106
|
Pass ``None`` to display interactively.
|
|
3025
3107
|
"""
|
|
3026
|
-
N =
|
|
3108
|
+
N = 11
|
|
3027
3109
|
|
|
3028
3110
|
def _p(i, label):
|
|
3029
3111
|
print(f" [{i:2d}/{N}] {label}")
|
|
@@ -3051,17 +3133,20 @@ def plot_run(
|
|
|
3051
3133
|
_p(6, "Radiation profiles")
|
|
3052
3134
|
plot_radiation_profile(run, save_dir=save_dir)
|
|
3053
3135
|
|
|
3136
|
+
_p(7, "Divertor two-point model")
|
|
3137
|
+
plot_divertor_two_point(run, save_dir=save_dir)
|
|
3138
|
+
|
|
3054
3139
|
# ── Coils & conductors ────────────────────────────────────────────
|
|
3055
|
-
_p(
|
|
3140
|
+
_p(8, "TF coil side view")
|
|
3056
3141
|
plot_TF_side_view(run, save_dir=save_dir)
|
|
3057
3142
|
|
|
3058
|
-
_p(
|
|
3143
|
+
_p(9, "CICC TF conductor")
|
|
3059
3144
|
plot_CICC_cross_section(build_conductor_from_run(run, coil="TF"), save_dir=save_dir)
|
|
3060
3145
|
|
|
3061
|
-
_p(
|
|
3146
|
+
_p(10, "CS cross-section")
|
|
3062
3147
|
plot_CS_cross_section(run, save_dir=save_dir)
|
|
3063
3148
|
|
|
3064
|
-
_p(
|
|
3149
|
+
_p(11, "CICC CS conductor")
|
|
3065
3150
|
plot_CICC_cross_section(build_conductor_from_run(run, coil="CS"), save_dir=save_dir)
|
|
3066
3151
|
|
|
3067
3152
|
print("Done.")
|
|
@@ -3308,11 +3393,11 @@ def plot_TF_benchmark_table(cfg=None, save_dir=None) -> None:
|
|
|
3308
3393
|
"ARC": {"a": 1.10, "b": 0.89, "R0": 3.30, "σ": 1000e6, "T_op": 20.0,
|
|
3309
3394
|
"B_max": 23.0, "n_TF": 1, "sc": "REBCO", "config": "Plug",
|
|
3310
3395
|
"κ": 1.84, "I_cond": 50e3, "V_max": 10e3, "N_sub": 6,
|
|
3311
|
-
"tau_h": 20, "J_wost":
|
|
3396
|
+
"tau_h": 20, "J_wost": 200e6},
|
|
3312
3397
|
"SPARC": {"a": 0.57, "b": 0.18, "R0": 1.85, "σ": 1000e6, "T_op": 20.0,
|
|
3313
3398
|
"B_max": 20.0, "n_TF": 1, "sc": "REBCO", "config": "Bucking",
|
|
3314
|
-
"κ": 1.75, "I_cond": 40.5e3,"V_max": 10e3, "N_sub":
|
|
3315
|
-
"tau_h": 20, "J_wost":
|
|
3399
|
+
"κ": 1.75, "I_cond": 40.5e3,"V_max": 10e3, "N_sub": 6,
|
|
3400
|
+
"tau_h": 20, "J_wost": 200e6},
|
|
3316
3401
|
}
|
|
3317
3402
|
|
|
3318
3403
|
def _clean(val):
|
|
@@ -18,11 +18,13 @@ os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE"
|
|
|
18
18
|
|
|
19
19
|
import json
|
|
20
20
|
import math
|
|
21
|
+
import multiprocessing
|
|
21
22
|
import random
|
|
22
23
|
import re
|
|
23
24
|
import shutil
|
|
24
25
|
import sys
|
|
25
26
|
import time
|
|
27
|
+
import traceback
|
|
26
28
|
import warnings
|
|
27
29
|
import importlib
|
|
28
30
|
from datetime import datetime
|
|
@@ -34,7 +36,7 @@ import numpy as np
|
|
|
34
36
|
import pandas as pd
|
|
35
37
|
import sympy as sp
|
|
36
38
|
from typing import List, Tuple
|
|
37
|
-
from dataclasses import dataclass
|
|
39
|
+
from dataclasses import dataclass, replace, asdict
|
|
38
40
|
|
|
39
41
|
#%% Scipy - Optimization and Numerical Methods
|
|
40
42
|
|
|
@@ -66,11 +68,13 @@ import matplotlib.colors as mcolors
|
|
|
66
68
|
import matplotlib.lines as mlines
|
|
67
69
|
import matplotlib.patches as mpatches
|
|
68
70
|
import matplotlib.cm as cm
|
|
71
|
+
from matplotlib.animation import FuncAnimation, PillowWriter
|
|
69
72
|
from matplotlib.colors import Normalize
|
|
70
73
|
from matplotlib.gridspec import GridSpec
|
|
71
74
|
from matplotlib.patches import Circle, Rectangle, Patch
|
|
72
75
|
from matplotlib.ticker import MultipleLocator
|
|
73
76
|
from mpl_toolkits.axes_grid1 import make_axes_locatable
|
|
77
|
+
from mpl_toolkits.mplot3d import Axes3D # noqa: F401 (registers the '3d' projection)
|
|
74
78
|
from pandas.plotting import table
|
|
75
79
|
from tqdm import tqdm
|
|
76
80
|
from dataclasses import dataclass
|
|
@@ -97,8 +97,10 @@ class GlobalConfig:
|
|
|
97
97
|
Bmax_TF : float = 12.0 # Peak magnetic field on TF conductor [T]
|
|
98
98
|
Bmax_CS_adm : float = 25.0 # Peak magnetic field allowed on the CS [T]
|
|
99
99
|
P_fus : float = 2000.0 # Total fusion power [MW]
|
|
100
|
-
Tbar : float = 14.0 # Volume-averaged
|
|
101
|
-
|
|
100
|
+
Tbar : float = 14.0 # Volume-averaged electron temperature T_e [keV]
|
|
101
|
+
tau_i_e : float = 1.0 # Ion-to-electron temperature ratio T_i/T_e [-]
|
|
102
|
+
# 1.0 -> single-temperature plasma (T_i = T_e).
|
|
103
|
+
# Prescribed: T_i(rho) = tau_i_e * T_e(rho),
|
|
102
104
|
|
|
103
105
|
# ── 2. Physics and operation ─────────────────────────────────────────────
|
|
104
106
|
Operation_mode : str = 'Pulsed' # 'Steady-State' or 'Pulsed'
|
|
@@ -122,7 +124,7 @@ class GlobalConfig:
|
|
|
122
124
|
# 'Sauter' — uses LCFS values (κ_edge, δ_edge). Sauter, FED 112 (2016) Eq. 30.
|
|
123
125
|
# 'ITER_1989' — uses ψ_N = 0.95 values (κ₉₅, δ₉₅). Uckan (1989), also Johner (2011).
|
|
124
126
|
Option_q95 : str = 'Sauter' # q₉₅ formula: 'Sauter' (default) or 'ITER_1989'
|
|
125
|
-
Option_Kappa : str = 'Wenninger'
|
|
127
|
+
Option_Kappa : str = 'Wenninger' # Elongation model: 'Wenninger', 'Stambaugh', 'Freidberg', 'Manual'
|
|
126
128
|
κ_manual : float = 1.9 # Elongation (Manual mode only) [-]
|
|
127
129
|
|
|
128
130
|
# ── 2a. Safety factor and current density profiles ────────────────────────
|
|
@@ -173,7 +175,15 @@ class GlobalConfig:
|
|
|
173
175
|
|
|
174
176
|
# ── 4. Plasma composition ────────────────────────────────────────────────
|
|
175
177
|
Atomic_mass : float = 2.5 # Volume-averaged ionic mass [AMU] (D-T: 2.5)
|
|
176
|
-
Zeff : float =
|
|
178
|
+
Zeff : float = None # Effective plasma charge [-].
|
|
179
|
+
# None -> computed self-consistently from the impurity
|
|
180
|
+
# inventory (impurity_species + f_imp_core) and the
|
|
181
|
+
# helium ash fraction (see _compute_Zeff_effective):
|
|
182
|
+
# Z_eff = 1 + 2 f_He - sum_j <Z_j> c_j
|
|
183
|
+
# + sum_j <Z_j>^2 c_j
|
|
184
|
+
# An empty impurity inventory therefore yields a clean
|
|
185
|
+
# D-T+He plasma with Z_eff ~ 1 + 2 f_He (~1.1).
|
|
186
|
+
# float -> manual override (legacy behaviour, e.g. Zeff = 2.0).
|
|
177
187
|
r_synch : float = 0.5 # Synchrotron radiation wall reflectivity [-]
|
|
178
188
|
C_Alpha : float = 7.0 # Helium ash dilution tuning parameter [-] (default taken from PROCESS)
|
|
179
189
|
# Impurity line radiation (0D bulk-plasma estimate).
|
|
@@ -215,6 +225,26 @@ class GlobalConfig:
|
|
|
215
225
|
Young_modul_Steel : float = 200e9 # Steel Young's modulus [Pa] (only used in CIRCE model)
|
|
216
226
|
Young_modul_GF : float = 90e9 # S-glass fiber Young's modulus [Pa] (only used in CIRCE model)
|
|
217
227
|
fatigue_CS : float = 2.0 # CS fatigue knockdown factor (pulsed & wedging only) [-]
|
|
228
|
+
# ── Steel allowable safety factors ───────────────────────────────────────
|
|
229
|
+
# Dimensionless knockdown applied to the steel mechanical allowable inside
|
|
230
|
+
# the TF and CS thickness solvers: σ_eff = σ_allowable / SF.
|
|
231
|
+
# Captures effects not represented by the idealised CICC area model:
|
|
232
|
+
# – Realistic winding-pack filling factor: round/square cables inside a
|
|
233
|
+
# rectangular envelope leave 15–30% of the WP cross-section occupied
|
|
234
|
+
# by ground insulation, inter-pancake plates, helium manifolds,
|
|
235
|
+
# terminations and assembly clearances. The structural jacket carries
|
|
236
|
+
# the electromagnetic load through a section reduced by this factor.
|
|
237
|
+
# – Stress concentrations at jacket corners and transitions (K_t ≈ 1.2–1.5).
|
|
238
|
+
# – Weld efficiency on jacket seams (η_w ≈ 0.85–0.90).
|
|
239
|
+
# – Manufacturing thickness tolerances (≈ ±5%).
|
|
240
|
+
# Default 1.0 preserves backward compatibility (raw material allowable used
|
|
241
|
+
# directly). Realistic engineering value for both TF and CS large-magnet
|
|
242
|
+
# CICC designs is ≈ 1.5 (composition of the four contributions above).
|
|
243
|
+
# The CS fatigue knockdown (fatigue_CS) multiplies on top of SF_CS, since
|
|
244
|
+
# the two factors address disjoint phenomena: primary static stress (SF)
|
|
245
|
+
# versus cyclic damage accumulation (fatigue_CS).
|
|
246
|
+
SF_TF : float = 1.0 # Safety factor on TF steel allowable [-] (suggested ≈ 1.5 for realistic CICC packing)
|
|
247
|
+
SF_CS : float = 1.0 # Safety factor on CS steel allowable [-] (suggested ≈ 1.5 for realistic CICC packing)
|
|
218
248
|
|
|
219
249
|
# ── 7. TF coil engineering ───────────────────────────────────────────────
|
|
220
250
|
Radial_build_model : str = 'refined' # Stress model: 'academic', 'refined', 'CIRCE'
|
|
@@ -257,7 +287,11 @@ class GlobalConfig:
|
|
|
257
287
|
f_void : float = None # Interstitial void fraction in strand bundle [-]
|
|
258
288
|
# None = auto: 0.33 (LTS) / 0.00 (REBCO).
|
|
259
289
|
# Set explicitly (e.g. 0.30) to override.
|
|
260
|
-
f_In : float = 0.
|
|
290
|
+
f_In : float = 0.05 # Insulation area fraction [-]
|
|
291
|
+
# Winding-pack overhead fraction in wost, treated exactly like the
|
|
292
|
+
# helium fraction: ground and inter-pancake insulation plus assembly
|
|
293
|
+
# clearances that occupy volume but carry neither current nor load.
|
|
294
|
+
f_gap : float = 0.15 # WP insulation + clearance fraction in wost [-]
|
|
261
295
|
|
|
262
296
|
# Temperature margins above T_helium defining T_operating [K]
|
|
263
297
|
# Conservative baseline: Corato et al., "Common operating values for DEMO…" (2016)
|
|
@@ -297,7 +331,7 @@ class GlobalConfig:
|
|
|
297
331
|
# P_CD_total = P_LH + P_ECRH + P_NBI + P_ICRH (P_aux_input ignored).
|
|
298
332
|
P_LH : float = 0.0 # LHCD plasma power [MW]
|
|
299
333
|
P_ECRH : float = 0.0 # ECRH plasma power [MW]
|
|
300
|
-
P_NBI : float = 0.0 # NBI injected power
|
|
334
|
+
P_NBI : float = 0.0 # NBI injected power[MW]
|
|
301
335
|
P_ICRH : float = 0.0 # ICRH plasma power [MW] (heating only, no current drive)
|
|
302
336
|
# --- Steady-State mode: power fractions per source [-] ---
|
|
303
337
|
# Used when Operation_mode = 'Steady-State' and CD_source = 'Multi'
|
|
@@ -325,6 +359,16 @@ class GlobalConfig:
|
|
|
325
359
|
# ── 12. Plasma-facing components ─────────────────────────────────────────
|
|
326
360
|
theta_deg : float = 2.7 # Divertor strike-point grazing angle [deg]
|
|
327
361
|
|
|
362
|
+
# Refined divertor exhaust (two-point model, Stangeby 2018). All used only
|
|
363
|
+
# in the post-convergence f_heat_two_point evaluation; they do not feed the
|
|
364
|
+
# core power balance.
|
|
365
|
+
f_n_sep : float = 0.20 # n_sep / volume-average density n̄ [-].
|
|
366
|
+
# Groth value taken from https://arxiv.org/pdf/2406.15693
|
|
367
|
+
f_cooling_div : float = 0.0 # SOL volumetric power-loss fraction [-] (2PM input)
|
|
368
|
+
f_mom_div : float = 0.0 # SOL volumetric momentum-loss fraction [-] (2PM input)
|
|
369
|
+
q_dep_limit : float = 5.0 # Tolerable deposited target heat flux [MW/m²]
|
|
370
|
+
flux_expansion: float = 1.0 # Target/upstream flux expansion R_t/R_u [-]
|
|
371
|
+
|
|
328
372
|
# ── 13. Maintenance constraints ──────────────────────────────────────────
|
|
329
373
|
ripple_adm : float = 0.01 # Admissible toroidal field ripple [-] (default 1%)
|
|
330
374
|
L_min : float = 3.00 # Minimum toroidal maintenance access width [m]
|