d0fus 2.4.1__tar.gz → 2.4.2__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.
Files changed (24) hide show
  1. {d0fus-2.4.1 → d0fus-2.4.2}/D0FUS_EXE/D0FUS_run.py +67 -50
  2. {d0fus-2.4.1 → d0fus-2.4.2}/D0FUS_EXE/D0FUS_scan.py +16 -6
  3. {d0fus-2.4.1/d0fus.egg-info → d0fus-2.4.2}/PKG-INFO +3 -3
  4. {d0fus-2.4.1 → d0fus-2.4.2}/README.md +3 -3
  5. {d0fus-2.4.1 → d0fus-2.4.2/d0fus.egg-info}/PKG-INFO +3 -3
  6. {d0fus-2.4.1 → d0fus-2.4.2}/pyproject.toml +1 -1
  7. {d0fus-2.4.1 → d0fus-2.4.2}/D0FUS.py +0 -0
  8. {d0fus-2.4.1 → d0fus-2.4.2}/D0FUS_BIB/D0FUS_cost_data.py +0 -0
  9. {d0fus-2.4.1 → d0fus-2.4.2}/D0FUS_BIB/D0FUS_cost_functions.py +0 -0
  10. {d0fus-2.4.1 → d0fus-2.4.2}/D0FUS_BIB/D0FUS_figures.py +0 -0
  11. {d0fus-2.4.1 → d0fus-2.4.2}/D0FUS_BIB/D0FUS_import.py +0 -0
  12. {d0fus-2.4.1 → d0fus-2.4.2}/D0FUS_BIB/D0FUS_parameterization.py +0 -0
  13. {d0fus-2.4.1 → d0fus-2.4.2}/D0FUS_BIB/D0FUS_physical_functions.py +0 -0
  14. {d0fus-2.4.1 → d0fus-2.4.2}/D0FUS_BIB/D0FUS_radial_build_functions.py +0 -0
  15. {d0fus-2.4.1 → d0fus-2.4.2}/D0FUS_EXE/D0FUS_genetic.py +0 -0
  16. {d0fus-2.4.1 → d0fus-2.4.2}/D0FUS_EXE/D0FUS_popcon.py +0 -0
  17. {d0fus-2.4.1 → d0fus-2.4.2}/D0FUS_EXE/D0FUS_uncertainty.py +0 -0
  18. {d0fus-2.4.1 → d0fus-2.4.2}/LICENSE +0 -0
  19. {d0fus-2.4.1 → d0fus-2.4.2}/d0fus.egg-info/SOURCES.txt +0 -0
  20. {d0fus-2.4.1 → d0fus-2.4.2}/d0fus.egg-info/dependency_links.txt +0 -0
  21. {d0fus-2.4.1 → d0fus-2.4.2}/d0fus.egg-info/entry_points.txt +0 -0
  22. {d0fus-2.4.1 → d0fus-2.4.2}/d0fus.egg-info/requires.txt +0 -0
  23. {d0fus-2.4.1 → d0fus-2.4.2}/d0fus.egg-info/top_level.txt +0 -0
  24. {d0fus-2.4.1 → d0fus-2.4.2}/setup.cfg +0 -0
@@ -1999,55 +1999,72 @@ def run(config: GlobalConfig = None, verbose: int = 0) -> tuple:
1999
1999
  "Valid options: 'academic', 'refined', 'CIRCE'."
2000
2000
  )
2001
2001
 
2002
- # ── Return nan tuple if TF radial build failed ────────────────────────────
2002
+ # ── TF radial build failed: keep the converged plasma, blank only the
2003
+ # magnet / engineering quantities ────────────────────────────────────────
2004
+ # When f_TF_* cannot size a feasible inboard leg, c comes back non-finite:
2005
+ # the winding pack reaching the requested peak field Bmax_TF within the steel
2006
+ # stress allowable does not fit in the available inboard space R0 - a - b.
2007
+ # The plasma equilibrium itself is still physical and was already solved
2008
+ # above, so returning an all-NaN tuple here would discard a perfectly valid
2009
+ # operating point (its density, beta, q95, Ip, Q, ...). That discarding is
2010
+ # exactly what makes the plasma operating space appear blank in 2-D scans in
2011
+ # regions where no plasma limit is reached but the TF coil is not buildable.
2012
+ # We therefore return the plasma quantities and set to NaN only the
2013
+ # quantities that genuinely depend on the (failed) coil build: the TF/CS
2014
+ # geometry and stresses, the magnetic-flux scenario, and all coil/component
2015
+ # volumes, masses, lifetimes and costs. The earlier convergence guard on
2016
+ # (f_alpha, Q) still returns an all-NaN tuple, because without a converged
2017
+ # burn there is no plasma to report at all.
2003
2018
  _nan = np.nan
2004
2019
  if not np.isfinite(c):
2005
- return (
2006
- _nan, _nan, _nan, # B0, B_CS, B_pol
2007
- _nan, _nan, # tauE, W_th
2008
- _nan, _nan, _nan, # Q, Volume, Surface
2009
- _nan, _nan, _nan, _nan, # Ip, Ib, I_CD, I_Ohm
2010
- _nan, _nan, _nan, _nan, # nbar, nbar_line, nG, pbar
2011
- _nan, _nan, _nan, # betaN, betaT, betaP
2012
- _nan, _nan, # qstar, q95
2013
- _nan, _nan, _nan, _nan, _nan, _nan, # P_CD, P_sep, P_Thresh, eta_CD, P_elec, P_wallplug
2014
- _nan, _nan, _nan, _nan, # cost, P_Brem, P_syn, P_line
2015
- _nan, # P_line_core
2016
- _nan, _nan, _nan, _nan, _nan, # heat, heat_par, heat_pol, lambda_q, q_target
2017
- _nan, _nan, # P_wall_rad, P_wall_div
2018
- _nan, # Gamma_n
2019
- _nan, _nan, # f_alpha, tau_alpha
2020
- _nan, _nan, # J_TF, J_CS
2021
- _nan, _nan, _nan, _nan, _nan, _nan, _nan, # TF radial build + stresses
2022
- _nan, _nan, _nan, _nan, _nan, _nan, _nan, # CS radial build + stresses
2023
- _nan, _nan, _nan, _nan, # r_minor, r_sep, r_c, r_d
2024
- _nan, _nan, _nan, _nan, # κ, κ_95, δ, δ_95
2025
- _nan, _nan, _nan, _nan, _nan, _nan, _nan, # ΨPI, ΨRampUp, Ψplateau, ΨPF, ΨCS, Vloop, li
2026
- _nan, _nan, _nan, # eta_LH, eta_EC, eta_NBI
2027
- _nan, _nan, _nan, _nan, # P_LH, P_EC, P_NBI, P_ICR
2028
- _nan, _nan, _nan, # I_LH, I_EC, I_NBI
2029
- _nan, _nan, _nan, _nan, _nan, _nan, # f_sc_TF, f_cu_TF, f_He_pipe_TF, f_void_TF, f_He_TF, f_In_TF
2030
- _nan, _nan, _nan, _nan, _nan, _nan, # f_sc_CS, f_cu_CS, f_He_pipe_CS, f_void_CS, f_He_CS, f_In_CS
2031
- _nan, _nan, _nan, _nan, # beta_fast_alpha, betaN_total, tau_sd_alpha, W_fast_alpha
2032
- _nan, _nan, # V_TF_one, V_CS_geom
2033
- _nan, _nan, _nan, _nan, _nan, # V_steel_TF, V_sc_TF, V_cu_TF, V_He_TF, V_In_TF
2034
- _nan, _nan, _nan, _nan, _nan, # V_steel_CS, V_sc_CS, V_cu_CS, V_He_CS, V_In_CS
2035
- _nan, _nan, # L_cable_TF, L_cable_CS
2036
- _nan, _nan, # n_sc_TF, n_sc_CS
2037
- _nan, _nan, # L_sc_strand_TF, L_sc_strand_CS
2038
- _nan, _nan, _nan, _nan, _nan, # M_steel_TF, M_sc_TF, M_cu_TF, M_In_TF, M_total_TF
2039
- _nan, _nan, _nan, _nan, _nan, # M_steel_CS, M_sc_CS, M_cu_CS, M_In_CS, M_total_CS
2040
- _nan, # V_blanket
2041
- _nan, _nan, # t_life_bl_fpy, t_life_div_fpy
2042
- _nan, _nan, # t_life_bl_yr, t_life_div_yr
2043
- _nan, _nan, # T_op_limit, dt_rep_eff
2044
- _nan, _nan, # Av, CF
2045
- _nan, # V_rb_SOL
2046
- _nan, _nan, # V_rb_FW, V_rb_BB
2047
- _nan, _nan, _nan, # V_rb_shield, V_rb_VV, V_rb_gap_TF
2048
- _nan, # V_rb_divertor
2049
- _nan, _nan, _nan, _nan, _nan, _nan, # M_rb_FW, M_rb_BB, M_rb_shield, M_rb_VV, M_rb_divertor, M_rb_total
2050
- )
2020
+ return (B0_solution, _nan, B_pol_solution, # B0, B_CS(nan), B_pol
2021
+ tauE_solution, W_th_solution,
2022
+ Q_solution, Volume_solution, Surface_solution,
2023
+ Ip_solution, Ib_solution, I_CD_solution, I_Ohm_solution,
2024
+ nbar_solution, nbar_line_solution, nG_solution, pbar_solution,
2025
+ betaN_solution, betaT_solution, betaP_solution,
2026
+ qstar_solution, q95_solution,
2027
+ P_CD_solution, P_sep_solution, P_Thresh, eta_CD_solution,
2028
+ P_elec_solution, P_wallplug_solution,
2029
+ _nan, P_Brem_solution, P_syn_solution, P_line_solution, # cost(nan)
2030
+ P_line_core_solution,
2031
+ heat_refined_solution, heat_par_solution, heat_pol_solution,
2032
+ lambda_q_Eich_m, q_target_Eich,
2033
+ P_1rst_wall_rad, P_1rst_wall_div,
2034
+ Gamma_n_solution,
2035
+ f_alpha_solution, tau_alpha,
2036
+ J_max_TF_conducteur, _nan, # J_TF, J_CS(nan)
2037
+ _nan, _nan, _nan, _nan, _nan, _nan, _nan, # c, c_WP_TF, c_Nose_TF, sigma_TF x3, Steel_TF
2038
+ _nan, _nan, _nan, _nan, _nan, _nan, _nan, # d, sigma_CS x3, Steel_CS, B_CS, J_CS
2039
+ R0 - a, R0 - a - b, _nan, _nan, # r_minor, r_sep kept; r_c, r_d depend on c
2040
+ κ, κ_95, δ, δ_95,
2041
+ _nan, _nan, _nan, _nan, _nan, _nan, li_solution, # Psi PI/RampUp/plateau/PF/CS, Vloop; li kept
2042
+ eta_LH_solution, eta_EC_solution, eta_NBI_solution,
2043
+ P_LH_solution, P_EC_solution, P_NBI_solution, P_ICR_solution,
2044
+ I_LH_solution, I_EC_solution, I_NBI_solution,
2045
+ f_sc_TF, f_cu_TF, f_He_pipe_TF, f_void_TF, f_He_TF, f_In_TF,
2046
+ _nan, _nan, _nan, _nan, _nan, _nan, # f_*_CS (CS conductor build)
2047
+ beta_fast_alpha, betaN_total, tau_sd_alpha, W_fast_alpha,
2048
+ _nan, _nan, # V_TF_one, V_CS_geom
2049
+ _nan, _nan, _nan, _nan, _nan, # V_steel/sc/cu/He/In_TF
2050
+ _nan, _nan, _nan, _nan, _nan, # V_steel/sc/cu/He/In_CS
2051
+ _nan, _nan, # L_cable_TF, L_cable_CS
2052
+ _nan, _nan, # n_sc_TF, n_sc_CS
2053
+ _nan, _nan, # L_sc_strand_TF, L_sc_strand_CS
2054
+ _nan, _nan, _nan, _nan, _nan, # M_steel/sc/cu/In/total_TF
2055
+ _nan, _nan, _nan, _nan, _nan, # M_steel/sc/cu/In/total_CS
2056
+ _nan, # V_blanket
2057
+ _nan, _nan, # t_life_bl_fpy, t_life_div_fpy
2058
+ _nan, _nan, # t_life_bl_yr, t_life_div_yr
2059
+ _nan, _nan, # T_op_limit, dt_rep_eff
2060
+ _nan, _nan, # Av, CF
2061
+ _nan, # V_rb_SOL
2062
+ _nan, _nan, # V_rb_FW, V_rb_BB
2063
+ _nan, _nan, _nan, # V_rb_shield, V_rb_VV, V_rb_gap_TF
2064
+ _nan, # V_rb_divertor
2065
+ _nan, _nan, _nan, # M_rb_FW, M_rb_BB, M_rb_shield
2066
+ _nan, _nan, _nan, # M_rb_VV, M_rb_divertor, M_rb_total
2067
+ divertor_solution) # two-point divertor model (kept)
2051
2068
 
2052
2069
  # ==============================================================================
2053
2070
  # MAGNETIC FLUX REQUIREMENTS (Inductive Scenario)
@@ -2682,7 +2699,7 @@ def _write_full_report(config, results, output_path, timestamp, input_file_path=
2682
2699
  """Write an exhaustive run report (all inputs + all outputs) to disk.
2683
2700
 
2684
2701
  Produces ``output_path/output_detailed.txt`` in addition to the
2685
- human-readable ``output_results.txt``. It lists every GlobalConfig field
2702
+ human-readable ``output_highlight.txt``. It lists every GlobalConfig field
2686
2703
  (including values left at their defaults), followed by the full set of
2687
2704
  computed quantities grouped into labelled sections, under a header that
2688
2705
  records the code version, date, git commit, Python version and platform.
@@ -2848,7 +2865,7 @@ def _write_full_report(config, results, output_path, timestamp, input_file_path=
2848
2865
  lines.append("")
2849
2866
  lines.append(" This report lists every input (including defaults) and every")
2850
2867
  lines.append(" computed output. It complements input_parameters.txt (inputs as")
2851
- lines.append(" given) and output_results.txt (human-readable summary).")
2868
+ lines.append(" given) and output_highlight.txt (human-readable summary).")
2852
2869
  lines.append("")
2853
2870
 
2854
2871
  # ===================================================================
@@ -3305,7 +3322,7 @@ def save_run_output(config: GlobalConfig,
3305
3322
  rho_rad_core = config.rho_rad_core
3306
3323
 
3307
3324
  # ── Write results report (console + file) ─────────────────────────────────
3308
- output_file = os.path.join(output_path, "output_results.txt")
3325
+ output_file = os.path.join(output_path, "output_highlight.txt")
3309
3326
  with open(output_file, "w", encoding="utf-8") as f:
3310
3327
 
3311
3328
  class DualWriter:
@@ -2384,13 +2384,23 @@ def plot_scan_results(outputs, param1_values, param2_values,
2384
2384
  iso_matrix_2 = (outputs[iso_param_2]
2385
2385
  if iso_param_2 is not None else None)
2386
2386
 
2387
- # Set NaN where not the dominant limit
2387
+ # ── Dominant (most-violated) stability limit per cell ────────────────────
2388
+ # Each cell is coloured by whichever of the three normalised ratios
2389
+ # (n/n_G, beta_N/beta_lim, q_lim/q95) is the largest, i.e. the most
2390
+ # binding constraint. The selection must be NaN-safe: np.argmax treats the
2391
+ # first NaN it encounters as the running maximum (since every comparison
2392
+ # `x > NaN` is False), which would mis-assign a cell to a layer whose ratio
2393
+ # is actually undefined there. We therefore (i) compete only finite ratios
2394
+ # by replacing NaN with -inf, and (ii) blank cells where *all* three ratios
2395
+ # are NaN (radial-build failure), so they are never falsely coloured.
2388
2396
  conditions = np.array([density_lim, beta_lim, q_lim])
2389
- idx_max = np.argmax(conditions, axis=0)
2390
-
2391
- density_plot = np.where(idx_max == 0, density_lim, np.nan)
2392
- beta_plot = np.where(idx_max == 1, beta_lim, np.nan)
2393
- q_plot = np.where(idx_max == 2, q_lim, np.nan)
2397
+ finite_any = np.any(np.isfinite(conditions), axis=0)
2398
+ conditions_safe = np.where(np.isfinite(conditions), conditions, -np.inf)
2399
+ idx_max = np.argmax(conditions_safe, axis=0)
2400
+
2401
+ density_plot = np.where(finite_any & (idx_max == 0), density_lim, np.nan)
2402
+ beta_plot = np.where(finite_any & (idx_max == 1), beta_lim, np.nan)
2403
+ q_plot = np.where(finite_any & (idx_max == 2), q_lim, np.nan)
2394
2404
 
2395
2405
  # Only show where limits < 2
2396
2406
  mask_valid = limits_all < 2
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: d0fus
3
- Version: 2.4.1
3
+ Version: 2.4.2
4
4
  Summary: Design 0-dimensional for Fusion Systems - Tokamak power plant design and optimization tool
5
5
  Author-email: Timothé Auclair <timothe.auclair@gmail.com>
6
6
  Maintainer-email: Timothé Auclair <timothe.auclair@gmail.com>
@@ -39,7 +39,6 @@ Requires-Dist: black>=23.0.0; extra == "dev"
39
39
  Requires-Dist: flake8>=6.0.0; extra == "dev"
40
40
  Dynamic: license-file
41
41
 
42
-
43
42
  <a name="readme-top"></a>
44
43
 
45
44
  <p align="center">
@@ -430,7 +429,8 @@ See `D0FUS_INPUTS/3_genetic_ITER.txt` for a complete example.
430
429
  ```
431
430
  D0FUS_OUTPUTS/Run_D0FUS_YYYYMMDD_HHMMSS/
432
431
  ├── input_parameters.txt # Copy of input configuration
433
- ├── output_results.txt # Complete calculation results (99 scalars, 8 families)
432
+ ├── output_highlight.txt # Human-readable synthesis of the key results
433
+ ├── output_detailed.txt # Exhaustive report: every input (incl. defaults) + every output
434
434
  └── figures/ # 10 run-specific PNG figures (150 dpi)
435
435
  ├── 01_cross_section.png
436
436
  ├── 02_miller_surfaces.png
@@ -1,4 +1,3 @@
1
-
2
1
  <a name="readme-top"></a>
3
2
 
4
3
  <p align="center">
@@ -389,7 +388,8 @@ See `D0FUS_INPUTS/3_genetic_ITER.txt` for a complete example.
389
388
  ```
390
389
  D0FUS_OUTPUTS/Run_D0FUS_YYYYMMDD_HHMMSS/
391
390
  ├── input_parameters.txt # Copy of input configuration
392
- ├── output_results.txt # Complete calculation results (99 scalars, 8 families)
391
+ ├── output_highlight.txt # Human-readable synthesis of the key results
392
+ ├── output_detailed.txt # Exhaustive report: every input (incl. defaults) + every output
393
393
  └── figures/ # 10 run-specific PNG figures (150 dpi)
394
394
  ├── 01_cross_section.png
395
395
  ├── 02_miller_surfaces.png
@@ -547,4 +547,4 @@ See the [LICENSE](LICENSE) file for details.
547
547
 
548
548
  © 2025 CEA/IRFM
549
549
 
550
- <p align="right">(<a href="#readme-top">back to top</a>)</p>
550
+ <p align="right">(<a href="#readme-top">back to top</a>)</p>
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: d0fus
3
- Version: 2.4.1
3
+ Version: 2.4.2
4
4
  Summary: Design 0-dimensional for Fusion Systems - Tokamak power plant design and optimization tool
5
5
  Author-email: Timothé Auclair <timothe.auclair@gmail.com>
6
6
  Maintainer-email: Timothé Auclair <timothe.auclair@gmail.com>
@@ -39,7 +39,6 @@ Requires-Dist: black>=23.0.0; extra == "dev"
39
39
  Requires-Dist: flake8>=6.0.0; extra == "dev"
40
40
  Dynamic: license-file
41
41
 
42
-
43
42
  <a name="readme-top"></a>
44
43
 
45
44
  <p align="center">
@@ -430,7 +429,8 @@ See `D0FUS_INPUTS/3_genetic_ITER.txt` for a complete example.
430
429
  ```
431
430
  D0FUS_OUTPUTS/Run_D0FUS_YYYYMMDD_HHMMSS/
432
431
  ├── input_parameters.txt # Copy of input configuration
433
- ├── output_results.txt # Complete calculation results (99 scalars, 8 families)
432
+ ├── output_highlight.txt # Human-readable synthesis of the key results
433
+ ├── output_detailed.txt # Exhaustive report: every input (incl. defaults) + every output
434
434
  └── figures/ # 10 run-specific PNG figures (150 dpi)
435
435
  ├── 01_cross_section.png
436
436
  ├── 02_miller_surfaces.png
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "d0fus"
7
- version = "2.4.1"
7
+ version = "2.4.2"
8
8
  description = "Design 0-dimensional for Fusion Systems - Tokamak power plant design and optimization tool"
9
9
  readme = "README.md"
10
10
  license = {text = "CeCILL-C"}
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes