Skip to content

Reject zero-thickness superconducting TF at input validation - #4535

Open
dallonby wants to merge 1 commit into
ukaea:mainfrom
dallonby:fix/zero-thickness-tf-validation
Open

Reject zero-thickness superconducting TF at input validation#4535
dallonby wants to merge 1 commit into
ukaea:mainfrom
dallonby:fix/zero-thickness-tf-validation

Conversation

@dallonby

Copy link
Copy Markdown
Contributor

Closes #4534

Overview

Adds a check_process validation so that the silent zero-thickness-TF failure mode described in the issue becomes an immediate, actionable input error instead of an unexplained downstream solver failure.

Changes

  • process/core/init.py: after the existing ixc 13/140 mutual-exclusion check, raise ProcessValidationError when i_tf_sup is superconducting, neither ixc 13 nor ixc 140 is active, and dr_tf_inboard <= 0. The message tells the user the three ways to fix their file. Stellarators (istell != 0, which calculate dr_tf_inboard during the model run) and IFE are excluded.
  • New tests/unit/core/test_init.py: five tests — the rejected configuration, plus accepted configurations for explicit thickness, ixc 140 active, resistive TF, and stellarator.
  • tests/unit/core/test_input.py (test-suite change, per CONTRIBUTING): the parser tests run init_process on minimal input snippets (e.g. just epsvmc = 1.0) and relied on config validation never examining the TF geometry; their shared fixture scaffold now sets a valid dr_tf_inboard so the parser tests keep testing parsing. No expected values change.

Behavioural impact

Valid configurations are unaffected (all seven shipped regression inputs pass: they each set ixc 13/140 or dr_tf_inboard, or are stellarator/IFE). The only newly-rejected configurations are ones that previously produced a machine with no inboard TF coil.

Verification

  • Full unit suite: 847 passed / 4 skipped; integration suite: 21 passed / 1 skipped (Python 3.12, local).

Found during an independent audit of v3.4.2.

🤖 Generated with Claude Code

Build.calculate_radial_build only derives dr_tf_inboard from the
winding pack and case thicknesses when dr_tf_wp_with_insulation
(ixc = 140) is an iteration variable. If a user supplies the winding
pack thickness as a plain input instead, dr_tf_inboard silently stays
at its default of 0: the TF coil vanishes from the radial build and the
run fails far downstream with unexplained radial-build inconsistency
and multi-GPa TF stresses.

Add a check_process validation that a superconducting TF has a positive
dr_tf_inboard when neither ixc = 13 nor ixc = 140 is active, with an
actionable message. Stellarators (which calculate dr_tf_inboard during
the model run) and IFE are excluded.

Test-suite change, per CONTRIBUTING: the parser tests in
tests/unit/core/test_input.py run init_process on minimal input
snippets and relied on config validation not examining the TF
geometry; their fixture scaffold now sets a valid dr_tf_inboard.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@dallonby
dallonby requested a review from a team as a code owner August 15, 2026 13:43
@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 49.34%. Comparing base (c0ae5b2) to head (2fbe8a8).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4535      +/-   ##
==========================================
+ Coverage   49.32%   49.34%   +0.02%     
==========================================
  Files         150      150              
  Lines       29802    29804       +2     
==========================================
+ Hits        14700    14707       +7     
+ Misses      15102    15097       -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.

@je-cook

je-cook commented Aug 17, 2026

Copy link
Copy Markdown
Collaborator

@ukaea/process-model-review this may adversely effect the optimiser as it is currently allowed to search invalid regions of space I think?

I suppose this is only checking init

@je-cook
je-cook requested a review from a team August 17, 2026 12:52
@mkovari

mkovari commented Aug 17, 2026

Copy link
Copy Markdown
Collaborator

Obviously this needs to be fixed - maybe someone who has looked at this code more recently than me - @chris-ashe or someone?

@dallonby

Copy link
Copy Markdown
Contributor Author

Init only. check_process is called from exactly one place, init_process (init.py:79), which SingleRun.__init__ runs once (main.py:339 then :432) before the Models objects are even built (main.py:340), so before Scan, SolverHandler or VMCON get anywhere near it. Scans don't re-init between points (scan.py just sets the swept variable), VaryRun spawns a fresh SingleRun per iteration, and dr_tf_inboard only gets written during model evaluation when ixc 140 is active (build.py:1684) or for stellarators, both of which the check excludes.

To be sure I wasn't reasoning my way past something, I instrumented it on the branch: 1 call to check_process vs 26 model evaluations (spherical_tokamak_eval, fsolve), 2029 (large_tokamak_nof, VMCON), 4286 (low_aspect_ratio_DEMO) and 16175 (a 3-point scan). One call every time, before the solve. So the optimiser's freedom to wander through invalid regions is untouched; the check only looks at inputs that are constant for the whole run.

Two things I should say explicitly though. It is a deliberate behaviour change for scaffold inputs that rely on the dr_tf_inboard = 0 default, which is why the test_input.py fixture needed a value. For what it's worth, on main those inputs currently either hit an uncaught ZeroDivisionError (tfcoil/base.py:424, circular case) or, with i_tf_case_geom = 1, report a "feasible solution" with a winding pack of -0.34 m and a negative turn count. And I only covered the superconducting case that was reported; a resistive TF with the same zero goes down the same build.py path, so it could be extended in a follow-up if you'd like.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Superconducting TF silently loses all inboard thickness when dr_tf_wp_with_insulation is not an iteration variable

4 participants