RadCluster
Graph-based cluster dynamics for irradiated materials
Loading...
Searching...
No Matches
create_excel.py
Go to the documentation of this file.
1#!/usr/bin/env python3
2"""
3create_excel.py — Generate input_parameters.xlsx for RadCluster_2_1.
4
5Creates a 5-sheet workbook with exact bcc Fe / EUROFER97 parameters from:
6 Ghoniem, N.M. (2026), "A Cluster Dynamics Model for Radiation Damage
7 Evolution in Ferritic-Martensitic Steels" (Rate_Equations.pdf).
8
9Sheet layout
10------------
11Production — cascade production parameters (Tables 2, 5): fission vs. fusion
12Energetics — lattice, migration/formation energies, He EOS (Tables 5, 8)
13Diffusion — diffusion pre-factors, solute trapping (Tables 5, 16)
14Dissociation — binding energy parameters, trap mutation (Tables 18-19, 27)
15Reactions — rate constant prefactors, sink parameters, solver settings (Tables 25-26, 29)
16
17Run from radcluster_code/:
18 python create_excel.py
19
20Overwrites input/input_parameters.xlsx.
21"""
22
23from pathlib import Path
24import pandas as pd
25
26OUTPUT_FILE = Path(__file__).parent / 'input' / 'input_parameters.xlsx'
27
28
29# ── Sheet 1: Production ───────────────────────────────────────────────────────
30# Tables 2 and 5 of Rate_Equations.pdf
31
32PRODUCTION = [
33 # (Parameter, Symbol, Fission, Fusion, Units)
34 ('Survival and Dose Rate', None, None, None, None),
35 ('Survival efficiency (spectrum-avg.)', 'eta', 0.30, 0.28, '−'),
36 ('Displacement rate', 'phi_dot', 'user', 'user', 'dpa/s'),
37 ('He production rate', 'G_He/G', '0.5−1','~10', 'appm He/dpa'),
38
39 ('Interstitial Cluster Production', None, None, None, None),
40 ('SIA clustering fraction', 'f_cl_i', 0.58, 0.65, '−'), # Table 2
41 ('SIA power-law exponent', 's_i', 1.6, 1.5, '−'), # Table 2, Eq. 7
42 ('Max SIA cascade size', 'i_cascade', 20, 50, 'SIAs'), # Table 2
43 ('SIA normalization constant', 'C_i', 0.1093, 0.0553, '−'), # Eq. 9
44
45 ('Vacancy Cluster Production', None, None, None, None),
46 ('Vacancy clustering fraction', 'f_cl_v', 0.15, 0.20, '−'), # Table 2
47 ('Vacancy power-law exponent', 's_v', 2.5, 2.3, '−'), # Table 2, Eq. 8
48 ('Max vacancy cascade size', 'v_cascade', 10, 20, 'vacancies'), # Table 2
49 ('Vacancy normalization constant', 'C_v', 0.1506, 0.1296, '−'), # Eq. 10
50]
51
52# ── Sheet 2: Energetics ───────────────────────────────────────────────────────
53# Tables 5 and 8 of Rate_Equations.pdf
54
55ENERGETICS = [
56 # (Parameter, Symbol, Value, Units, Notes)
57 ('Lattice and Elastic Constants', None, None, None, None),
58 ('Lattice constant', 'a', 0.2867, 'nm', 'bcc Fe'), # Table 5
59 ('Atomic volume', 'Omega', 1.18e-29, 'm^3', 'a^3/2'), # Table 5
60 ('Burgers vector (1/2<111>)', 'b_111', 0.2482, 'nm', None), # Table 5
61 ('Burgers vector (<100>)', 'b_100', 0.2867, 'nm', None), # Table 5
62 ('Shear modulus (RT)', 'mu', 82, 'GPa', None), # Table 5
63 ('Poisson ratio', 'nu', 0.29, '−', None), # Table 5
64 ('Surface energy', 'gamma_s',2.0, 'J/m^2', 'DFT average'), # Table 5
65
66 ('Vacancy Energetics', None, None, None, None),
67 ('Formation energy', 'E_f_v', 2.0, 'eV', 'DFT consensus'), # Table 5
68 ('Migration energy', 'E_m_v', 0.67, 'eV', 'DFT, Stage III'), # Table 5
69 ('Divacancy binding (2NN)', 'E_B_2v', 0.22, 'eV', 'DFT'), # Table 5
70 ('Divacancy migration', 'E_m_2v', 0.70, 'eV', 'DFT'), # Table 5
71
72 ('SIA Energetics', None, None, None, None),
73 ('Formation energy (<110> dumbbell)', 'E_f_i', 3.64, 'eV', 'DFT'), # Table 5
74 ('Migration energy (<110> T-R)', 'E_m_i', 0.34, 'eV', 'DFT, Stage I_E'),# Table 5
75 ('Di-SIA binding energy', 'E_B_2i', 0.80, 'eV', 'DFT'), # Table 5
76 ('Di-SIA migration energy', 'E_m_2i', 0.42, 'eV', 'DFT'), # Table 5
77
78 ('Helium Energetics', None, None, None, None),
79 ('He migration energy (tetrahedral)', 'E_m_h', 0.06, 'eV', 'DFT'), # Table 5
80 ('He-vacancy binding (1st He)', 'E_b_hV_1', 2.30, 'eV', 'Fu & Willaime 2005'), # Table 5
81 ('He-vacancy binding (2nd He)', 'E_b_hV_2', 2.00, 'eV', 'Fu & Willaime 2005'), # Table 5
82 ('He solution energy (interstitial)', 'E_s_He', 2.35, 'eV', 'Fu & Willaime 2005'), # Table 5
83
84 ('Attempt Frequencies', None, None, None, None),
85 ('Vacancy', 'nu_v', 1.0e13, 's^-1', None), # Table 5
86 ('SIA (<110>)', 'nu_i', 1.0e13, 's^-1', None), # Table 5
87 ('He interstitial','nu_h', 3.0e12, 's^-1', None), # Table 5
88
89 ('He Equation of State (Virial, 600-1000 K)', None, None, None, None),
90 ('Second virial coefficient', 'B2', 1.67e-29, 'm^3/atom', 'Eq. 64, Table 8'), # Table 8
91 ('Third virial coefficient', 'B3', 1.84e-58, 'm^6/atom^2','Eq. 65, Table 8'), # Table 8
92]
93
94# ── Sheet 3: Diffusion ────────────────────────────────────────────────────────
95# Tables 5 and 16 of Rate_Equations.pdf
96
97DIFFUSION = [
98 # (Parameter, Symbol, Value, Units, Notes)
99 ('Pure Fe Baseline Diffusion', None, None, None, None),
100 ('Vacancy D0', 'D0_v', 8.2e-8, 'm^2/s', 'Eq. 17'), # Table 5
101 ('Vacancy E_m', 'E_m_v', 0.67, 'eV', None),
102 ('SIA D0', 'D0_i', 8.2e-8, 'm^2/s', 'Eq. 17'), # Table 5
103 ('SIA E_m', 'E_m_i', 0.34, 'eV', None),
104 ('He D0', 'D0_h', 2.5e-8, 'm^2/s', 'Eq. 17'), # Table 5
105 ('He E_m', 'E_m_h', 0.06, 'eV', None),
106
107 ('SIA Cluster 1D Glide (n >= 4)', None, None, None, None),
108 ('Attempt frequency', 'nu0_1D', 6.0e12, 's^-1', 'Eq. 33'), # Table 5
109 ('1D migration energy','E_m_1D', 0.03, 'eV', 'mid-range estimate'),# Table 5
110 ('Size exponent', 's_1D', 0.7, '−', 'MD range 0.5-1.0'), # Table 5
111 ('Max mobile SIA size', 'i_mobile', 100, 'SIAs', None), # Table 5
112
113 ('Vacancy Cluster Diffusion', None, None, None, None),
114 ('Size exponent', 's_vc', 1.0, '−', None), # Table 5
115 ('Max mobile vacancy size', 'v_mobile', 5, 'vacancies', None), # Table 5
116
117 ('EUROFER Dissolved Solute Concentrations', None, None, None, None),
118 ('Cr', 'c_Cr', 0.094, 'at/at', '9 wt% Cr'), # Table 16
119 ('W', 'c_W', 0.0033, 'at/at', '1.1 wt% W'), # Table 16
120 ('Mn', 'c_Mn', 0.0047, 'at/at', '0.47 wt% Mn'), # Table 16
121 ('C (dissolved)', 'c_C', 5.0e-4, 'at/at', 'after tempering'), # Table 16
122 ('N (dissolved)', 'c_N', 2.0e-4, 'at/at', 'after tempering'), # Table 16
123
124 ('SIA Solute Trapping: z_s * exp(E_b / kT) (Eq. 42)', None, None, None, None),
125 ('C-SIA binding', 'E_b_C_SIA', 0.45, 'eV', 'z=4'), # Table 16
126 ('N-SIA binding', 'E_b_N_SIA', 0.40, 'eV', 'z=4'), # Table 16
127 ('Cr-SIA binding', 'E_b_Cr_SIA', 0.10, 'eV', 'z=8'), # Table 16
128 ('Mn-SIA binding', 'E_b_Mn_SIA', 0.20, 'eV', 'z=6'), # Table 16
129
130 ('Vacancy Solute Trapping: z_s * exp(E_b / kT) (Eq. 48)', None, None, None, None),
131 ('C-V binding', 'E_b_C_V', 0.45, 'eV', 'z=3'), # Table 16
132 ('N-V binding', 'E_b_N_V', 0.40, 'eV', 'z=3'), # Table 16
133 ('W-V binding', 'E_b_W_V', 0.27, 'eV', 'z=8'), # Table 16
134 ('Mn-V binding', 'E_b_Mn_V', 0.10, 'eV', 'z=8'), # Table 16
135 ('Cr-V binding', 'E_b_Cr_V', 0.05, 'eV', 'z=8'), # Table 16
136
137 ('SIA Cluster Loop Trapping (1D, Eq. 52)', None, None, None, None),
138 ('C-loop binding', 'E_b_C_loop', 0.50, 'eV', 'z=2'), # Table 16
139 ('N-loop binding', 'E_b_N_loop', 0.40, 'eV', 'z=2'), # Table 16
140 ('Cr-loop binding', 'E_b_Cr_loop', 0.10, 'eV', 'z=4'), # Table 16
141
142 ('Mixed 1D/3D Parameters', None, None, None, None),
143 ('Mean free path (EUROFER)', 'L_hat', 50.0, '−', 'L/a, alloy-dependent'), # Table 5
144 ('1D/3D interpolation const.','B_rot', 2.627, '−', 'Eq. 128'), # Eq. 128
145]
146
147# ── Sheet 4: Dissociation ─────────────────────────────────────────────────────
148# Tables 18-19, 27 of Rate_Equations.pdf
149
150DISSOCIATION = [
151 # (Parameter, Symbol, Value, Units, Notes)
152 ('Void Binding Energy Model (Eqs. 66-67)', None, None, None, None),
153 ('Vacancy formation energy', 'E_f_v', 2.0, 'eV', None),
154 ('Surface energy', 'gamma_s', 2.0, 'J/m^2', None),
155 ('Divacancy binding (DFT)', 'E_b_v2', 0.22, 'eV', 'anchor point'),
156 ('Decay constant', 'lambda', 0.5756, 'vac^-1','ln(100)/8'),
157
158 ('Atomistic Fitting Amplitudes A(m) — Table 18', None, None, None, None),
159 ('A(m=0)', 'A_void_0', 1.2353, 'eV', 'pure void correction'), # Table 18
160 ('A(m=1)', 'A_void_1', 2.9064, 'eV', None), # Table 18
161 ('A(m=2)', 'A_void_2', 3.4147, 'eV', None), # Table 18
162 ('A(m=3)', 'A_void_3', 2.1504, 'eV', None), # Table 18
163 ('A(m=4)', 'A_void_4',-0.1590, 'eV', None), # Table 18
164
165 ('Vacancy Loop Binding (Eqs. 104-105)', None, None, None, None),
166 ('Stacking fault energy', 'gamma_sf', 0.6, 'J/m^2', None),
167 ('Core radius', 'r_c', 0.333, 'b_111', None),
168 ('Divacancy binding', 'E_b_v2', 0.22, 'eV', None),
169 ('Decay constant', 'lambda_v', 0.575, 'vac^-1',None),
170
171 ('Interstitial Loop Binding (power-law + blend, Eqs. 106-108)', None, None, None, None),
172 ('1/2<111> amplitude', 'A_111', 0.7501, 'eV', None), # Table 18 / Eq. 106
173 ('1/2<111> exponent', 'B_111', 0.3873, '−', None), # Table 18 / Eq. 106
174 # Di-interstitial binding energy: E_b^fit(2) = A_111*2^{+B_111}. When set
175 # (>0) it OVERRIDES A_111 via A_111 = E_b_i2*2^{-B_111}, and rescales A_100
176 # by the same factor so the <100>/<111> ratio is preserved. Blank/0 => the
177 # A_111/A_100 values above are used verbatim.
178 ('Di-interstitial binding', 'E_b_i2', 0.80, 'eV',
179 'DFT anchor (bcc Fe); overrides A_111 = E_b_i2*2^-B_111'),
180 ('<100> amplitude', 'A_100', 0.7160, 'eV', None), # Table 18 / Eq. 107
181 ('<100> exponent', 'B_100', 0.3581, '−', None), # Table 18 / Eq. 107
182 ('Blend center', 'n_tr', 25, 'SIAs', None), # Eq. 108
183 ('Blend width', 'sigma_tr',5, 'SIAs', None), # Eq. 108
184
185 ('He Maximum Loading', None, None, None, None),
186 ('He/V ratio parameter', 'alpha_He', 1.7, '−', 'l_max = alpha * m^(2/3)'), # Table 29
187
188 ('He Binding Energy to Bubbles (Eqs. 76-77)', None, None, None, None),
189 ('He atomic mass', 'm_He', 4.0026, 'amu', '4-He'),
190 ('He virial B2', 'B2', 1.67e-29,'m^3/atom', 'Table 8'),
191 ('He virial B3', 'B3', 1.84e-58,'m^6/atom^2','Table 8'),
192
193 ('He Binding: Atomistic-Continuum Blending (Table 19)', None, None, None, None),
194 ('Decay constant', 'mu_He', 0.658, 'He^-1', 'ln(100)/7'), # Table 19
195 ('Fitting amplitude A^He(2)', 'A_He_2', 0.55, 'eV', 'Caturla/Fu'), # Table 19
196 ('Fitting amplitude A^He(3)', 'A_He_3', 0.40, 'eV', 'Caturla/Fu'), # Table 19
197 ('Fitting amplitude A^He(4)', 'A_He_4', 0.75, 'eV', 'Caturla/Fu'), # Table 19
198
199 ('Trap Mutation (Eq. 83, Eq. 142, Table 27)', None, None, None, None),
200 ('Attempt frequency', 'nu0_TM', 1.0e12, 's^-1', None), # Table 27
201 ('E_TM: He5V1', 'E_TM_1_5', 1.00, 'eV', 'Morishita 2003'),# Table 27
202 ('E_TM: He6V1', 'E_TM_1_6', 0.50, 'eV', 'Morishita 2003'),# Table 27
203 ('E_TM: He7V1', 'E_TM_1_7', 0.00, 'eV', 'spontaneous'), # Table 27
204 ('E_TM: He4 (alpha=0)', 'E_TM_0_4', 0.30, 'eV', 'Gao 2011'), # Table 27
205 ('E_TM: He5 (alpha=0)', 'E_TM_0_5', 0.10, 'eV', 'Gao 2011'), # Table 27
206 ('E_TM: He6 (alpha=0)', 'E_TM_0_6', 0.00, 'eV', 'spontaneous'), # Table 27
207]
208
209# ── Sheet 5: Reactions ────────────────────────────────────────────────────────
210# Tables 25-26, 29 of Rate_Equations.pdf
211
212REACTIONS = [
213 # (Parameter, Symbol, Value, Units, Notes)
214 ('Geometric Rate Constant Prefactors (Eq. 128, Table 25)', None, None, None, None),
215 ('Spherical cluster', 'A_sph', 7.818, '−', '(48*pi^2)^(1/3); Eq. 128'), # Table 25
216 ('Dislocation loop', 'A_loop', 10.78, '−', '8*sqrt(pi/sqrt(3)); Eq. 128'),# Table 25
217 ('Pure 1D sink', 'A_1D', 2.632, '−', '9/(8*pi^(2/3)); Eq. 128'), # Table 25
218 ('1D/3D interpolation', 'B_rot', 2.627, '−', '(4/pi)*(8*pi/3)^(1/3)'), # Table 25
219 ('V-SIA recombination', 'K_iv_pf',21.77, '−', '4*sqrt(3)*pi'), # Eq. 130
220
221 ('Dislocation Network Sink (Table 26)', None, None, None, None),
222 ('Network dislocation density', 'rho_d', 1.0e14, 'm^-2', 'EUROFER tempered'), # Table 26
223 ('Interstitial bias factor', 'Z_i', 1.10, '−', 'Table 26; NETWORK dislocation bias'), # Table 26
224 ('Loop interstitial bias', 'Z_i_loop',1.10, '−', 'Eq. P3_i; LOOP bias, independent of Z_i. blank = use Z_i'),
225 ('Vacancy bias factor', 'Z_v', 1.00, '−', 'Table 26'), # Table 26
226 ('He bias factor', 'Z_He', 1.00, '−', 'Table 26'), # Table 26
227
228 ('Grain Boundary Sink (Eq. 134-137)', None, None, None, None),
229 ('Grain diameter', 'd_g', 5.0e-6, 'm', 'EUROFER typical'), # Table 26
230
231 ('Precipitate Sink (Eq. 134-137)', None, None, None, None),
232 ('Precipitate density', 'rho_p', 1.0e21, 'm^-3', 'M23C6 precipitates'), # Table 26
233 ('Precipitate radius', 'r_p', 5.0e-9, 'm', 'EUROFER typical'), # Table 26
234 ('Precipitate bias SIA', 'Z_p_i', 1.0, '−', None), # Table 26
235 ('Precipitate bias vac', 'Z_p_v', 1.0, '−', None), # Table 26
236
237 ('Radiation Re-solution (Eq. 143)', None, None, None, None),
238 ('Re-solution parameter (fission)', 'b0_fission', 0.01, 'dpa^-1/He', None), # Table 29
239 ('Re-solution parameter (fusion)', 'b0_fusion', 0.10, 'dpa^-1/He', None), # Table 29
240
241 ('He State-Space Parameters (Table 29)', None, None, None, None),
242 ('He max loading parameter', 'alpha_He', 1.7, '−', None), # Table 29
243 ('Max SIA cluster tracked', 'I', 500, '−', 'user: 500-5000'),# Table 29
244 ('Max vacancy cluster tracked','V', 500, '−', 'user: 500-5000'),# Table 29
245 ('Max He per cluster', 'L_He_max', 'mf', '−', 'mf=mean-field'), # Table 29
246
247 ('Size-Bin Moment Parameters (Chapter 9)', None, None, None, None),
248 ('Moments per bin', 'n_moments', 2, '−', 'zeroth + first'),
249 ('Max discrete SIA size', 'i_discrete', 1, '−', 'sizes 1..i_discrete resolved individually'),
250 ('Max discrete vacancy size','v_discrete', 5, '−', 'sizes 1..v_discrete resolved individually; default = v_mobile'),
251 ('Number of SIA bin-moment eqs', 'I_bin', 14, '−', 'grouped bins for SIA clusters'),
252 ('Number of VAC bin-moment eqs', 'V_bin', 14, '−', 'grouped bins for vacancy clusters'),
253 ('Grouping transition', 'n_group', 50, '−', 'Eq. 190'),
254
255 ('Loop 1/2<111> -> <100> Conversion (Marian 2002 + Dudarev 2008)', None, None, None, None),
256 ('Unary direct-rotation barrier','E_a0_conv', 1.8, 'eV', 'single-loop 1/2<111>-><100> direct rotation (Marian >2 eV); sets f111(T) crossover ~350 C; calibrate to dose'),
257 ('Two-step fwd barrier dH2', 'dH2_conv', 1.0, 'eV', 'Marian Fig.3: 1/2<110>-><100> (junction/absorption success prob)'),
258 ('Two-step rev barrier dHrev','dH_rev_conv', 0.30, 'eV', 'Marian Fig.3: 1/2<110>->1/2<111> reversion; P_success=ef/(ef+eb)'),
259 ('Unary barrier size slope', 'gamma_a_conv', 0.03, 'eV', 'per perimeter-segment; calibrate to Arakawa onset + size window'),
260 ('Unary attempt frequency', 'nu0_conv', 1.0e13, '1/s', 'Debye'),
261 ('Conversion crossover temp', 'T_star_conv_C',450.0, 'C', 'dF(n_ref,T*)=0; in [350,550] (Dudarev Fig. 4)'),
262 ('Conversion reference size', 'n_ref_conv', 30, '-', 'calibration anchor size for LoopEnergetics'),
263 ('Junction peak yield', 'phi_max_junc', 0.5, '-', 'Marian; yield at n=n_prime (0-1)'),
264 ('Junction log-size tol.', 'sigma_s_junc', 0.35, '-', 'Marian comparable-size width in ln(n/n_prime)'),
265 ('Junction min size', 'n_j_min_junc', 30, '-', 'Marian; junctions from n ~ 34-37'),
266 ('Junction min-size fraction', 'n_j_min_frac', 0.6, '-', 'n_j_min_eff = min(n_j_min_junc, ceil(frac*i_mobile)); 0.6 keeps 30 at i_mobile=50'),
267 ('<100> loop-onset size', 'n_loop_min', 4, '-', 'bulk-100 n_min; below this no <100> loop exists'),
268
269 # ── Loop → network-dislocation loss (loop_network_loss.tex) ──────────────
270 # Keys with a STATIC code default carry that number here; the two with a
271 # DYNAMIC default (loop_net_n_inc -> i_mobile, loop_net_w_c -> the
272 # per-character Burgers vector) are shipped BLANK and the code falls back.
273 ('Loop -> Network Dislocation Loss (loop_network_loss.tex)', None, None, None, None),
274 ('Channel enable flag', 'LOOP_NETWORK_LOSS', 0, '-', '0=off (legacy 2_0 behaviour), 1=on; needs run_adaptive()'),
275 ('Elastic capture range', 'loop_net_chi', 1.0, '-', 'R_int = chi*d_loop; CHANNEL IS ~0 BELOW chi~30 (few-nm loops vs ~100 nm network spacing)'),
276 ('Capture width', 'loop_net_w_c', None, 'm', 'blank = per-character Burgers vector (physical); 150*b_111 reaches the EUROFER plateau'),
277 ('Recovery prefactor', 'loop_net_K_rec', 0.0, 'm/s', 'drho = -K_rec*rho_net^{3/2}; 0 = no recovery (monotonic growth)'),
278 ('Network density ceiling', 'loop_net_rho_max', 1.0e16,'m^-2', 'runaway guard; EUROFER experimental plateau is ~5e14'),
279 ('Small-n stress floor', 'loop_net_xi', 0.0, '-', 'elastic-zone floor for small n; 0 = off'),
280 ('Incorporation onset size', 'loop_net_n_inc', None, '-', 'blank = i_mobile; loops below this size are excluded'),
281
282 ('Solver Settings (Table 29)', None, None, None, None),
283 ('Solver mode', 'solver_mode', 'full_system', '−', 'full_system | active_window'),
284 ('Physics option', 'physics_option','full_CD_fission', '−', 'full_CD_fission | full_CD_fusion | bin_moment_CD_fission | bin_moment_CD_fusion'),
285 ('Free He kinetics', 'he_kinetics', 'dynamic', '−', 'dynamic | quasi_steady_state'),
286 ('Start time', 't_begin', 1.0e-8, 's', None),
287 ('End time', 't_end', 1.0e7, 's', None),
288 ('Output points', 'n_points', 200, '−', None),
289 ('Log time spacing', 'log_time', 1, '−', '1=yes, 0=no'),
290 ('Rel. tolerance', 'rtol', 1.0e-8, '−', None),
291 ('Abs. tolerance', 'atol', 1.0e-50, '−', None),
292 ('Linear solver', 'linsol', 'dense', '−', 'dense | band | gmres | klu (sparse, full_CD only)'),
293 ('Band upper bw', 'mu_band', 0, '−', '0 = auto'),
294 ('Band lower bw', 'ml_band', 0, '−', '0 = auto'),
295 ('Window width', 'window_width', 100, '−', 'sliding window initial width (shared SIA/VAC)'),
296 ('Window expand thr','window_C_exp', 1.0e-18, '−', 'expand when C > this'),
297 ('Concentration floor','C_floor', 1.0e-100, '−', None),
298
299 ('Irradiation Conditions', None, None, None, None),
300 ('Temperature', 'T', 600.0, 'K', 'irradiation temperature'),
301 ('Displacement rate', 'G', 1.0e-6, 'dpa/s', None),
302 ('He production rate', 'G_He_r', 1.0, 'appm/dpa','for fusion use ~10'),
303 ('Neutron spectrum', 'spectrum','fission','−', 'fission | fusion'),
304]
305
306
307# ── Writer ───────────────────────────────────────────────────────────────────
308
309def build_df(rows, columns=('Parameter', 'Symbol', 'Value', 'Units', 'Notes')):
310 return pd.DataFrame(rows, columns=list(columns))
311
312
314 OUTPUT_FILE.parent.mkdir(parents=True, exist_ok=True)
315
316 prod_df = build_df(PRODUCTION,
317 ('Parameter', 'Symbol', 'Fission', 'Fusion', 'Units'))
318 ener_df = build_df(ENERGETICS)
319 diff_df = build_df(DIFFUSION)
320 diss_df = build_df(DISSOCIATION)
321 reac_df = build_df(REACTIONS)
322
323 with pd.ExcelWriter(OUTPUT_FILE, engine='openpyxl') as writer:
324 prod_df.to_excel(writer, sheet_name='Production', index=False)
325 ener_df.to_excel(writer, sheet_name='Energetics', index=False)
326 diff_df.to_excel(writer, sheet_name='Diffusion', index=False)
327 diss_df.to_excel(writer, sheet_name='Dissociation', index=False)
328 reac_df.to_excel(writer, sheet_name='Reactions', index=False)
329
330 print(f"Written: {OUTPUT_FILE.resolve()}")
331 print(f" Sheets: Production, Energetics, Diffusion, Dissociation, Reactions")
332
333
334if __name__ == '__main__':
build_df(rows, columns=('Parameter', 'Symbol', 'Value', 'Units', 'Notes'))