Reject zero-thickness superconducting TF at input validation - #4535
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #4535 +/- ##
==========================================
- Coverage 49.47% 49.47% -0.01%
==========================================
Files 150 151 +1
Lines 30069 30078 +9
==========================================
+ Hits 14878 14882 +4
- Misses 15191 15196 +5 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
@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 |
|
Obviously this needs to be fixed - maybe someone who has looked at this code more recently than me - @chris-ashe or someone? |
|
Init only. To be sure I wasn't reasoning my way past something, I instrumented it on the branch: 1 call to Two things I should say explicitly though. It is a deliberate behaviour change for scaffold inputs that rely on the |
| data.stellarator.istell == 0 | ||
| and data.ife.ife == 0 | ||
| and data.tfcoil.i_tf_sup == TFConductorModel.SUPERCONDUCTING | ||
| and not (data.numerics.ixc[: data.numerics.n_iteration_variables] == 13).any() |
There was a problem hiding this comment.
I think this condition should be removed because on the first iteration with ixc = 13 the IN.DAT-defined value of dr_tf_inboard is used which would cause the model errors this condition is designed to protect against.
There was a problem hiding this comment.
This would also require a slight change to the error message below.
| if ( | ||
| data.stellarator.istell == 0 | ||
| and data.ife.ife == 0 | ||
| and data.tfcoil.i_tf_sup == TFConductorModel.SUPERCONDUCTING |
There was a problem hiding this comment.
Hopefully someone from @ukaea/process-model-review can confirm, but I think we can probably test this condition for superconducting and resistive TF coils. Resistive TF still uses dr_tf_inboard and it would not surprise me if it being 0 or negative would be equally problematic here too.
| def data_structure_obj(): | ||
| return DataStructure() | ||
| data = DataStructure() | ||
| # These parser tests run init_process on minimal input snippets; give the | ||
| # scaffold a valid TF thickness so configuration validation (which rejects | ||
| # a zero-thickness superconducting TF) does not reject the scaffold. | ||
| data.build.dr_tf_inboard = 1.0 | ||
| return data |
There was a problem hiding this comment.
I want to avoid having to do specific setup in this test wherever possible. A better option for me is to turn off check_process since its not actually useful for this test.
@pytest.fixture(autouse=True)
def turn_off_check_process(monkeypatch):
monkeypatch.setattr(init, "check_process", lambda *_: None)Rebasing to include #4553 (now merged onto main) will also be useful because that will check none of these tests fail because of the above change.
|
@je-cook the only impact on the "solver" (on the solution) will be that some users may need to update their initial point if they currently have |
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>
…er tests skip validation - The check no longer exempts ixc = 13: the input value seeds the first model evaluation either way; an exactly-zero value was only caught later by the generic iteration-variable check, and a negative value was not caught at all (the 1/value scaling in load_iteration_variables inverts the variable's bounds). Rejecting at input validation covers both with an actionable message. - The error message drops "or use ixc = 13" accordingly. - The conductor-model condition is removed: dr_tf_inboard is only derived under ixc = 140 or for stellarators, neither of which depends on i_tf_sup, so resistive TF coils had the same silent zero-thickness path. - test_input.py keeps its scaffold unchanged and instead disables check_process with an autouse monkeypatch fixture, as suggested; the parser tests no longer carry TF geometry. - Tests updated: resistive zero-thickness now rejected (plus an accepted positive-thickness case), and ixc = 13 with zero or negative input is rejected. Unit suite 855 passed / 4 skipped; integration 21 passed / 1 skipped (all shipped regression inputs pass the widened check). Rebased onto main (includes ukaea#4553). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Thanks — all four points taken, in a89dcb2 (rebased onto main, so #4553's One precision on the ixc = 13 case, because it slightly strengthens your change: with The conductor-model condition is removed rather than widened: Unit 855 passed / 4 skipped; integration 21 passed / 1 skipped — all shipped inputs pass the widened check. |
2fbe8a8 to
a89dcb2
Compare
| the generic iteration-variable check, and a negative value is not | ||
| rejected at all (the 1/value scaling inverts the variable's bounds). | ||
| """ | ||
| for bad_value in (0.0, -0.5): |
There was a problem hiding this comment.
Sorry that I missed this in my first review, I would prefer that this was parametrize'd rather than using a for loop over bad values
|
|
||
| @pytest.fixture(autouse=True) | ||
| def turn_off_check_process(monkeypatch): | ||
| """These are parser tests; configuration validation is not under test.""" |
There was a problem hiding this comment.
| """These are parser tests; configuration validation is not under test.""" | |
| """These are parser tests; configuration validation is not a part of test.""" |
|
Thanks @dallonby, I think I was actually wrong about the ixc = 13 case because the input parser would reject a negative value. Nevertheless I still think keeping the validation logic as is makes sense as it does no harm. |
…estion Also corrects the test docstring: a negative dr_tf_inboard cannot come from an input file (the parser bounds it to [0, 10]); check_process guards the data structure however it was populated. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
timothy-nunn
left a comment
There was a problem hiding this comment.
Just a change we made yesterday that has not quite filtered through. Otherwise all looks good, thank you for finding this bug and providing a fix!
Closes #4534
Overview
Adds a
check_processvalidation 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, raiseProcessValidationErrorwheni_tf_supis superconducting, neither ixc 13 nor ixc 140 is active, anddr_tf_inboard <= 0. The message tells the user the three ways to fix their file. Stellarators (istell != 0, which calculatedr_tf_inboardduring the model run) and IFE are excluded.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 runinit_processon minimal input snippets (e.g. justepsvmc = 1.0) and relied on config validation never examining the TF geometry; their shared fixture scaffold now sets a validdr_tf_inboardso 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
Found during an independent audit of v3.4.2.
🤖 Generated with Claude Code