Skip to content

TF Temperature margin improvements: calculation and de-discombobulation - #4689

Open
CoronelBuendia wants to merge 35 commits into
mainfrom
matti/4628-alternative-T-margin
Open

CoronelBuendia wants to merge 35 commits into
mainfrom
matti/4628-alternative-T-margin

Conversation

@CoronelBuendia

@CoronelBuendia CoronelBuendia commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Description

Closes #4628, changing T_margin > T_margin_min to j_tf_wp < j_tf_wp_temp_margin
Closes #4687, removing duplicate/obsolete variables, and removing the inconsistent calculation of T margin and critical current density in CROCO TF coils.
Closes #3674 (for my naïve updating of obsolete variables in the input file given in the issue, this PR does not run into the error, but does fail to converge pretty quickly. Needs more testing to prove it works better.)

  • fails_supercon.IN.DAT.txt Error not encountered, fails to converge VMCON error code = 5 (SolverOutputCondition.NO_SOLUTION)
  • STEP_supercon_fail.IN.DAT.txt Error not encountered during optimisation (but would be if i_plant_availability > 1), and errors in post-processing. The required current density in the superconductor is significantly above the critical current at the first iteration, and it never recovers. Zero or negative TF turn area appears likely. VMCON error code = 5 (SolverOutputCondition.NO_SOLUTION). For this case I find no feasible solution with the warning "superconducting.py:2280) Superconductor current density residual for temperature margin calculation is not sufficiently close to zero: -0.909335 (normalised tolerance: 1e-10)"

Summary of naming / refactoring changes:

  • Removes the duplicated temp_margin variable on tfcoil
  • Deprecates the tmargmin variable (applied to both CS and TF coils)
  • Centres all TF coil temperature margin terms on:
    • temp_tf_superconductor_margin_min (input) temperature margin associated with constraint 36
    • temp_tf_superconductor_margin actual temperature margin
  • Adds j_tf_wp_temp_margin : allowable TF coil winding pack current density, for specified temperature margin (A/m²), in line with j_tf_wp_critical (eqcon 33) and j_tf_wp_quench_heat_max(eqcon 35)
  • Refactors some functions in superconducting TF (apologies, I just couldn't)
  • Removes current_sharing_rebco as this is no longer used (T margin calculated consistently based on superconductor and critical current density parameterisation)
  • var_label formatting in reporting/constraints.py now accepts $ $ math labels

Summary of technical changes:

  • Changes constraint equation 35 (T_margin > T_margin_min) to the numerical cheaper and more robust (j_tf_wp < j_tf_wp_temp_margin), bringing it in line with the formulations in constraint equations 33 and 35.
  • Only explicitly calculates temperature margin in post-processing, or if availability_model >= 2
    • This is basically to avoid the root-finding operation for the current-sharing temperature at all costs
    • This is only necessary at present because:
      • of the availability models which require temperature margin.
      • we had discussed beforehand not to introduce a new iteration variable. If the availability models are heavily used, it would be wiser numerically to add a temperature margin variable, because this side-steps the need for calculating the temperature margin altogether. Constraint 33 only calculates the critical current at operational temperature, so no root-finding required
      • If the temperature margin calculation fails in post-processing (usually degenerate cases, np.nan is returned)
  • Changes the implementation of calculate_superconductor_temperature_margin from an unbounded Newton root-finding to a bounded least squares optimisation with a check on the minimum value ~ 0.
  • Removes the inconsistent use of superconducting current density parameterisations in CROCO TF coil (here and here).

I have not looked at the CS coil, but it may benefit from similar treatment.

Checklist

I confirm that I have completed the following checks:

  • My changes follow the PROCESS style guide
  • I have justified any large differences in the regression tests caused by this pull request in the comments.
  • I have added new tests where appropriate for the changes I have made.
  • If I have had to change any existing unit or integration tests, I have justified this change in the pull request comments.
  • If I have made documentation changes, I have checked they render correctly.
  • I have added documentation for my change, if appropriate.

@CoronelBuendia
CoronelBuendia requested a review from a team as a code owner October 15, 2026 15:23
@github-actions

Copy link
Copy Markdown

⚠️ improve_quality_job warning!

Files changed by this PR have introduced 1 more linting errors when compared to main

Please fix these

To check what these are, run hatch run lint:fmt_extra on your branch and on main

@CoronelBuendia CoronelBuendia added TF Coil Toroidal field coil Bug Something isnt working labels Oct 16, 2026
@codecov-commenter

codecov-commenter commented Oct 16, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 47.82609% with 60 lines in your changes missing coverage. Please review.
✅ Project coverage is 50.23%. Comparing base (0b69cfc) to head (c9535a7).

Files with missing lines Patch % Lines
process/models/tfcoil/superconducting.py 44.68% 52 Missing ⚠️
...cess/core/io/plot/summary/reporting/constraints.py 22.22% 7 Missing ⚠️
process/models/availability.py 66.66% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4689      +/-   ##
==========================================
- Coverage   50.26%   50.23%   -0.03%     
==========================================
  Files         181      181              
  Lines       30629    30623       -6     
==========================================
- Hits        15395    15384      -11     
- Misses      15234    15239       +5     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@CoronelBuendia
CoronelBuendia force-pushed the matti/4628-alternative-T-margin branch from d5a5cc4 to b431ce8 Compare October 16, 2026 13:09
@CoronelBuendia CoronelBuendia changed the title WIP: Temperature margin improvements: calculation and de-discombobulation WIP: TF Temperature margin improvements: calculation and de-discombobulation Oct 16, 2026
@CoronelBuendia

CoronelBuendia commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor Author

Regression test failures

Obviously, the values, bounds and residuals of constraint 36 (if present in the test input file) are now all different (A/m^2 vs. K). So large_tokamak_eval and large_tokamak_nof have 3 differences (all constraint 36 values).

This means the variable name change and the T margin calculation are valid.

The low_aspect_ratio_DEMO file is a little trickier to explain. Looking at just the > 5% failures for now:

Variable                                	       Ref	       New	  % Change
--------------------------------------------------------------------------------
ineq_bound_con036                       	       1.5	  1.83e+07	1217819982.09
ineq_value_con036                       	       1.5	  1.83e+07	1217819969.00
ineq_con068                             	  9.63e-12	  3.35e-10	   3382.73
res_eq_con002                           	 -9.47e-10	   1.1e-08	   1262.94
eq_con002                               	 -3.35e-12	  3.89e-11	   1262.91
ineq_con062                             	  2.59e-10	 -1.45e-11	   -105.59
ineq_con036                             	  9.88e-09	  8.76e-10	    -91.13
stress_z_cs_self_midplane_profile[2]    	 -3.25e+04	 -3.88e+03	     88.07
stress_z_cs_self_midplane_profile[3]    	 -3.25e+04	 -3.88e+03	     88.07
f_j_cs_start_end_flat_top               	   -0.0102	  -0.00351	     65.72
cs_t2                                   	  1.91e+06	  6.57e+05	    -65.54
cs_t3                                   	  1.91e+06	  6.57e+05	    -65.54
ineq_con035                             	  8.54e-11	  3.89e-11	    -54.46
ineq_con034                             	   2.3e-10	  1.06e-10	    -54.01
ineq_con031                             	  4.78e-11	  2.68e-11	    -43.89
ineq_con005                             	  2.26e-11	   1.3e-11	    -42.29
ineq_con090                             	   1.8e-10	  1.07e-10	    -40.71
res_eq_con093                           	  -1.4e+09	 -1.85e+09	    -32.21
ineq_con060                             	  1.52e-10	  1.98e-10	     30.24
ineq_con016                             	  3.31e-10	  2.52e-10	    -23.85
pfc1t4                                  	  -8.6e+05	 -9.84e+05	    -14.47
pfc0t4                                  	  1.14e+06	  1.05e+06	     -8.07
ineq_con027                             	     0.488	      0.52	      6.43
ineq_value_con027                       	     0.358	     0.336	     -6.13
j_cs_critical_pulse_start               	  3.65e+07	  3.87e+07	      5.98

The ineq_con values are different, but still at residual levels, because the solver has taken a different path. This is probably because the gradients are different with the new approach (possibly less noise due to Newton solve of T margin at each iteration). Getting rid of these residual values, we see:

Variable                                	       Ref	       New	  % Change
--------------------------------------------------------------------------------
stress_z_cs_self_midplane_profile[2]    	 -3.25e+04	 -3.88e+03	     88.07
stress_z_cs_self_midplane_profile[3]    	 -3.25e+04	 -3.88e+03	     88.07
f_j_cs_start_end_flat_top               	   -0.0102	  -0.00351	     65.72
cs_t2                                   	  1.91e+06	  6.57e+05	    -65.54
cs_t3                                   	  1.91e+06	  6.57e+05	    -65.54
pfc1t4                                  	  -8.6e+05	 -9.84e+05	    -14.47
pfc0t4                                  	  1.14e+06	  1.05e+06	     -8.07
j_cs_critical_pulse_start               	  3.65e+07	  3.87e+07	      5.98

all of which relate to the CS coil, which I'm reasonably confident I left alone here. So clearly the optimiser has settled on a different solution vector. Why this disproportionately affects the CS I am guessing because R_0 = 8.0 (lower bound) is due to ever slightly thicker TF coil (~1.3e-5 m), meaning the CS coil gets pushed inwards a bit and has to compensate to achieve the same flux.

Here is the comparison (new in 57 iterations - left, old in 70 iterations - right):
image
image

What the fudge pile

ST eval

name='pres_plasma_pedestal_thermal', ref=8288.649976426672, new=7172.8701719077, percentage_change=-13.461538461538424)

@CoronelBuendia CoronelBuendia changed the title WIP: TF Temperature margin improvements: calculation and de-discombobulation TF Temperature margin improvements: calculation and de-discombobulation Oct 20, 2026
@timothy-nunn timothy-nunn self-assigned this Oct 21, 2026
@timothy-nunn
timothy-nunn requested a review from a team October 21, 2026 08:53
@CoronelBuendia
CoronelBuendia force-pushed the matti/4628-alternative-T-margin branch from 353f95b to c9535a7 Compare October 21, 2026 10:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bug Something isnt working TF Coil Toroidal field coil

Projects

None yet

3 participants