Refactor of CS coil modelling (iohcl switch)
@ajpearcey is already working on this.
Since May 20, 2026.
- Dominant language
- Python
- Stars
- 71
- Forks
- 27
- Avg merge
- 2d 18h
- Merged PRs (30d)
- 33
Description
CS coil modelling in PROCESS
The current codebase lacks a single coherent definition of what iohcl means. In practice it is used to control:
- whether a CS coil is counted in PF/CS circuit bookkeeping
- whether some CS electrical calculations are performed
- whether certain PF coil locations are allowed
- whether some CS-specific output should appear
Switch
==iohcl==controls whether a central solenoid is present. A value of 1 denotes that this coil is present, and should be assigned a non-zero thicknessdr_cs. A value of==iohcl=== 0 denotes that no central solenoid is present, in which case the thicknessdr_csshould be zero. No PF coils should be located at positions defined byi_pf_location(j)= 1 if no central solenoid is present.
The documentation tell us that we can either model "no CS at all" or include a CS, but the code and outputs show that it really behaves more like “CS not actively driving during flat-top” in at least some paths.
As a result, CS geometry can still exist in the radial build while PF/CS electrical logic and output partially assume the CS is absent, leading to inconsistent state, confusing output, and poorly implemented branching. All while the user may think they have not included a CS at all.
This needs a proper refactor and a clearer model of the intended operating modes.
Desired model states
There are at least three physically distinct cases we want to represent:
- CS present and driving current during flat-top
- CS present, used for start-up / ramp-up, but not used to drive flat-top current
(e.g. NBI or another system sustains flat-top current) - No CS coil present at all
Issues in current code
PFCoil still constructs CS state even when iohcl == 0
In pfcoil.py, the PF model:
- conditionally increments the PF+CS coil count only if
iohcl != 0 - but still computes CS pulse-start current density unconditionally
- and still calls
self.cs_coil.calculate_cs_geometry(...)unconditionally insidePFCoil.pfcoil()
This means CS-related state is still created in memory even in the “no CS” branch, and the branching happens too late / inconsistently.
CS logic is split across PFCoil and CSCoil
PFCoil owns significant CS logic directly:
- CS current-density ratios and waveform logic
- CS filament count / use in
efc - CS flux / volt-second calculations
- CS-specific conditional branches keyed on
iohcl
At the same time, there is already a CSCoil path (calculate_cs_geometry, place_cs_filaments, ohcalc, output routines), so CS responsibility is split between classes instead of being isolated cleanly.
This makes it unclear where the authoritative CS state machine should live.
build.py treats CS as physically present in the radial build
build.py always includes CS quantities in the inboard radial build output:
Central solenoidCS precompressionCS precompresion to TF coil radial gap
and the cumulative radius logic includes these quantities directly.
The sample output shows these CS components appearing in the radial build:
dr_csdr_cs_precompdr_cs_tf_gap
4) Output becomes inconsistent when iohcl == 0
OUT.DAT includes CS-specific PF output still being emitted in the no-CS case, including:
- CS current ratios:
f_j_cs_start_pulse_end_flat_top = 0.9f_j_cs_start_end_flat_top = 1.0
CS coilentries in volt-second summaries- “Number of PF circuits including CS and plasma”
- CS-labelled PF waveform output
At the same time, pfcoil.py also has a branch that prints “No central solenoid included” when iohcl == 0.
So the present behaviour mixes “no CS” with “CS still exists”.
Steps to resolve
- Start from the premise of 3 CS states outlined above
- Centralise the branching for CS (might not be so straight forward)
- If it's possible, refactor CS calculations out of PFCoil class
- otherwise implement appropriate branching
- Refactor CS output to CSCoil class
dr_csis purely an input value, but can we instead size it based on the v-s required?- Update docs.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.