From b2db669c5663f7d9e8550998a276f4d760838bd8 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Fri, 17 Apr 2026 11:15:42 +0100 Subject: [PATCH 01/37] Add CROCOAveragedTurnGeometry class and update CROCOSuperconductingTFCoil to use averaged turn geometry calculations --- process/models/tfcoil/superconducting.py | 221 ++++++++++++++++++++--- 1 file changed, 192 insertions(+), 29 deletions(-) diff --git a/process/models/tfcoil/superconducting.py b/process/models/tfcoil/superconducting.py index 21f2a2242..beb169e4e 100644 --- a/process/models/tfcoil/superconducting.py +++ b/process/models/tfcoil/superconducting.py @@ -3011,6 +3011,20 @@ def tf_cable_in_conduit_integer_turn_geometry( # ------------- +@dataclass +class CROCOAveragedTurnGeometry: + a_tf_turn_cable_space_no_void: float + a_tf_turn_steel: float + a_tf_turn_insulation: float + n_tf_coil_turns: int + c_tf_turn: float + dx_tf_turn_general: float + dr_tf_turn: float + dx_tf_turn: float + t_conductor: float + dx_tf_turn_cable_space_average: float + + class CROCOSuperconductingTFCoil(SuperconductingTFCoil): """Cross Conductor Superconducting TF Coil class.""" @@ -3027,26 +3041,12 @@ def run(self, output: bool = False): # Setting the WP turn geometry / areas if tfcoil_variables.i_tf_turns_integer == 0: # Non-ingeger number of turns - ( - tfcoil_variables.a_tf_turn_cable_space_no_void, - tfcoil_variables.a_tf_turn_steel, - tfcoil_variables.a_tf_turn_insulation, - tfcoil_variables.n_tf_coil_turns, - tfcoil_variables.dx_tf_turn_general, - tfcoil_variables.c_tf_turn, - tfcoil_variables.dx_tf_turn_general, - superconducting_tf_coil_variables.dr_tf_turn, - superconducting_tf_coil_variables.dx_tf_turn, - tfcoil_variables.t_conductor, - superconducting_tf_coil_variables.radius_tf_turn_cable_space_corners, - superconducting_tf_coil_variables.dx_tf_turn_cable_space_average, - superconducting_tf_coil_variables.a_tf_turn_cable_space_effective, - superconducting_tf_coil_variables.f_a_tf_turn_cable_space_cooling, - ) = self.tf_cable_in_conduit_averaged_turn_geometry( + avg_turn_geometry = CROCOAveragedTurnGeometry + + avg_turn_geometry = self.tf_croco_averaged_turn_geometry( j_tf_wp=tfcoil_variables.j_tf_wp, dx_tf_turn_steel=tfcoil_variables.dx_tf_turn_steel, dx_tf_turn_insulation=tfcoil_variables.dx_tf_turn_insulation, - i_tf_sc_mat=tfcoil_variables.i_tf_sc_mat, dx_tf_turn_general=tfcoil_variables.dx_tf_turn_general, c_tf_turn=tfcoil_variables.c_tf_turn, i_dx_tf_turn_general_input=tfcoil_variables.i_dx_tf_turn_general_input, @@ -3054,8 +3054,24 @@ def run(self, output: bool = False): dx_tf_turn_cable_space_general=tfcoil_variables.dx_tf_turn_cable_space_general, layer_ins=tfcoil_variables.layer_ins, a_tf_wp_no_insulation=superconducting_tf_coil_variables.a_tf_wp_no_insulation, - dia_tf_turn_coolant_channel=tfcoil_variables.dia_tf_turn_coolant_channel, - f_a_tf_turn_cable_space_extra_void=tfcoil_variables.f_a_tf_turn_cable_space_extra_void, + ) + + tfcoil_variables.a_tf_turn_cable_space_no_void = ( + avg_turn_geometry.a_tf_turn_cable_space_no_void + ) + tfcoil_variables.a_tf_turn_steel = avg_turn_geometry.a_tf_turn_steel + tfcoil_variables.a_tf_turn_insulation = ( + avg_turn_geometry.a_tf_turn_insulation + ) + tfcoil_variables.n_tf_coil_turns = avg_turn_geometry.n_tf_coil_turns + tfcoil_variables.dx_tf_turn_general = avg_turn_geometry.dx_tf_turn_general + tfcoil_variables.c_tf_turn = avg_turn_geometry.c_tf_turn + tfcoil_variables.dx_tf_turn_general = avg_turn_geometry.dx_tf_turn_general + superconducting_tf_coil_variables.dr_tf_turn = avg_turn_geometry.dr_tf_turn + superconducting_tf_coil_variables.dx_tf_turn = avg_turn_geometry.dx_tf_turn + tfcoil_variables.t_conductor = avg_turn_geometry.t_conductor + superconducting_tf_coil_variables.dx_tf_turn_cable_space_average = ( + avg_turn_geometry.dx_tf_turn_cable_space_average ) else: @@ -3406,16 +3422,16 @@ def run(self, output: bool = False): else: strain = tfcoil_variables.str_wp - tfcoil_variables.temp_tf_superconductor_margin = self.calculate_superconductor_temperature_margin( - i_tf_superconductor=tfcoil_variables.i_tf_sc_mat, - j_superconductor=superconducting_tf_coil_variables.j_tf_superconductor, - b_tf_inboard_peak=tfcoil_variables.b_tf_inboard_peak_with_ripple, - strain=strain, - bc20m=superconducting_tf_coil_variables.b_tf_superconductor_critical_zero_temp_strain, - tc0m=superconducting_tf_coil_variables.temp_tf_superconductor_critical_zero_field_strain, - c0=1.0e10, - temp_tf_coolant_peak_field=tfcoil_variables.tftmp, - ) + # tfcoil_variables.temp_tf_superconductor_margin = self.calculate_superconductor_temperature_margin( + # i_tf_superconductor=tfcoil_variables.i_tf_sc_mat, + # j_superconductor=superconducting_tf_coil_variables.j_tf_superconductor, + # b_tf_inboard_peak=tfcoil_variables.b_tf_inboard_peak_with_ripple, + # strain=strain, + # bc20m=superconducting_tf_coil_variables.b_tf_superconductor_critical_zero_temp_strain, + # tc0m=superconducting_tf_coil_variables.temp_tf_superconductor_critical_zero_field_strain, + # c0=1.0e10, + # temp_tf_coolant_peak_field=tfcoil_variables.tftmp, + # ) # Do current density protection calculation # Only setup for Nb3Sn at present. @@ -3455,6 +3471,153 @@ def run(self, output: bool = False): if output: self.outtf() + def tf_croco_averaged_turn_geometry( + self, + j_tf_wp: float, + dx_tf_turn_steel: float, + dx_tf_turn_insulation: float, + dx_tf_turn_general: float, + c_tf_turn: float, + i_dx_tf_turn_general_input: bool, + i_dx_tf_turn_cable_space_general_input: bool, + dx_tf_turn_cable_space_general: float, + layer_ins: float, + a_tf_wp_no_insulation: float, + ) -> CROCOAveragedTurnGeometry: + """Subroutine straight from Python, see comments in tf_averaged_turn_geom_wrapper + Setting the TF WP turn geometry for SC magnets from the number + the current per turn. + This calculation has two purposes, first to check if a turn can exist + (positive cable space) and the second to provide its dimensions, + areas and the (float) number of turns + + Parameters + ---------- + j_tf_wp : float + Current density in the TF winding pack (in A/m²). + + dx_tf_turn_steel : float + Thickness of the steel layer in the TF turn (in meters). + + dx_tf_turn_insulation : float + Thickness of the insulation layer in the TF turn (in meters). + + i_tf_sc_mat : int + Identifier for the superconducting material type. + + dx_tf_turn_general : float + General dimension of the TF turn (in meters). + + c_tf_turn : float + Current per turn in the TF coil (in Amperes). + + i_dx_tf_turn_general_input : bool + Flag indicating if the general turn dimension is provided as input. + + i_dx_tf_turn_cable_space_general_input : bool + Flag indicating if the cable space dimension is provided as input. + + dx_tf_turn_cable_space_general : float + General dimension of the cable space in the TF turn (in meters). + + layer_ins : float + Thickness of the insulation layer in the TF turn (in meters). + + a_tf_wp_no_insulation : float + Area of the TF winding pack without insulation (in square meters). + + dia_tf_turn_coolant_channel : float + Diameter of the coolant channel in the TF turn (in meters). + + f_a_tf_turn_cable_space_extra_void : float + Fraction of extra void space in the cable space of the TF turn. + + Returns + ------- + CROCOAveragedTurnGeometry + A dataclass containing the calculated geometry of the TF turn, including: + - a_tf_turn: Area of the TF turn (in square meters). + - dx_tf_turn: Dimension of the TF turn (in meters). + - dr_tf_turn: Dimension of the TF turn (in meters). + - t_conductor: Thickness of the conductor in the TF turn (in meters). + - n_tf_coil_turns: Number of turns in the TF coil (not necessarily an integer). + - a_tf_turn_insulation: Area of the insulation in the TF turn (in square meters). + - a_tf_turn_cable_space_no_void: Area of the cable space in the TF turn without voids (in square meters). + - a_tf_turn_steel: Area of the steel in the TF turn (in square meters). + - a_tf_turn_cable_space_effective: Effective area of the cable space in the TF turn after accounting for cooling channels and voids (in square meters). + - f_a_tf_turn_cable_space_cooling: Fraction of the cable space used for cooling. + + """ + # Turn dimension is a an input + if i_dx_tf_turn_general_input: + # Turn area [m2] + a_tf_turn = dx_tf_turn_general**2 + + # Current per turn [A] + c_tf_turn = a_tf_turn * j_tf_wp + + # Turn cable dimension is an input + elif i_dx_tf_turn_cable_space_general_input: + # Turn squared dimension [m] + dx_tf_turn_general = dx_tf_turn_cable_space_general + 2.0e0 * ( + dx_tf_turn_insulation + dx_tf_turn_steel + ) + + # Turn area [m2] + a_tf_turn = dx_tf_turn_general**2 + + # Current per turn [A] + c_tf_turn = a_tf_turn * j_tf_wp + + # Current per turn is an input + else: + # Turn area [m2] + # Allow for additional inter-layer insulation MDK 13/11/18 + # Area of turn including conduit and inter-layer insulation + a_tf_turn = c_tf_turn / j_tf_wp + + # Dimension of square cross-section of each turn including inter-turn insulation [m] + dx_tf_turn_general = np.sqrt(a_tf_turn) + + # Square turn assumption + dr_tf_turn = dx_tf_turn_general + dx_tf_turn = dx_tf_turn_general + + # See derivation in the following document + # k:\power plant physics and technology\process\hts\hts coil module for process.docx + t_conductor = ( + -layer_ins + np.sqrt(layer_ins**2 + 4.0e00 * a_tf_turn) + ) / 2 - 2.0e0 * dx_tf_turn_insulation + + # Total number of turns per TF coil (not required to be an integer) + n_tf_coil_turns = a_tf_wp_no_insulation / a_tf_turn + + # Area of inter-turn insulation: single turn [m2] + a_tf_turn_insulation = a_tf_turn - t_conductor**2 + + a_tf_turn_cable_space_no_void = copy.copy( + tfcoil_variables.a_tf_turn_cable_space_no_void + ) + + # Diameter of circular cable space inside conduit [m] + dx_tf_turn_cable_space_average = t_conductor - 2.0e0 * dx_tf_turn_steel + + # Cross-sectional area of conduit jacket per turn [m2] + a_tf_turn_steel = t_conductor**2 - a_tf_turn_cable_space_no_void + + return CROCOAveragedTurnGeometry( + a_tf_turn_cable_space_no_void=a_tf_turn_cable_space_no_void, + a_tf_turn_steel=a_tf_turn_steel, + a_tf_turn_insulation=a_tf_turn_insulation, + n_tf_coil_turns=n_tf_coil_turns, + c_tf_turn=c_tf_turn, + dx_tf_turn_general=dx_tf_turn_general, + dr_tf_turn=dr_tf_turn, + dx_tf_turn=dx_tf_turn, + t_conductor=t_conductor, + dx_tf_turn_cable_space_average=dx_tf_turn_cable_space_average, + ) + def supercon_croco( self, a_tf_turn, b_tf_inboard_peak_symmetric, iop, thelium, output: bool ): From 07c0aa93d4239b1552a32ebb4f751e2da39589e7 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Fri, 17 Apr 2026 11:25:50 +0100 Subject: [PATCH 02/37] Remove unused i_tf_sc_mat parameter from CICCSuperconductingTFCoil and related tests --- process/models/tfcoil/superconducting.py | 99 +++++++++-------------- tests/unit/models/tfcoil/test_sctfcoil.py | 7 -- 2 files changed, 40 insertions(+), 66 deletions(-) diff --git a/process/models/tfcoil/superconducting.py b/process/models/tfcoil/superconducting.py index beb169e4e..e57614c11 100644 --- a/process/models/tfcoil/superconducting.py +++ b/process/models/tfcoil/superconducting.py @@ -1607,7 +1607,6 @@ def run(self, output: bool = False): j_tf_wp=tfcoil_variables.j_tf_wp, dx_tf_turn_steel=tfcoil_variables.dx_tf_turn_steel, dx_tf_turn_insulation=tfcoil_variables.dx_tf_turn_insulation, - i_tf_sc_mat=tfcoil_variables.i_tf_sc_mat, dx_tf_turn_general=tfcoil_variables.dx_tf_turn_general, c_tf_turn=tfcoil_variables.c_tf_turn, i_dx_tf_turn_general_input=tfcoil_variables.i_dx_tf_turn_general_input, @@ -2603,7 +2602,6 @@ def tf_cable_in_conduit_averaged_turn_geometry( j_tf_wp: float, dx_tf_turn_steel: float, dx_tf_turn_insulation: float, - i_tf_sc_mat: int, dx_tf_turn_general: float, c_tf_turn: float, i_dx_tf_turn_general_input: bool, @@ -2632,9 +2630,6 @@ def tf_cable_in_conduit_averaged_turn_geometry( dx_tf_turn_insulation : float Thickness of the insulation layer in the TF turn (in meters). - i_tf_sc_mat : int - Identifier for the superconducting material type. - dx_tf_turn_general : float General dimension of the TF turn (in meters). @@ -2742,68 +2737,54 @@ def tf_cable_in_conduit_averaged_turn_geometry( tfcoil_variables.a_tf_turn_cable_space_no_void ) - # ITER like turn structure - if i_tf_sc_mat != 6: - # Radius of rounded corners of cable space inside conduit [m] - radius_tf_turn_cable_space_corners = dx_tf_turn_steel * 0.75e0 + # Radius of rounded corners of cable space inside conduit [m] + radius_tf_turn_cable_space_corners = dx_tf_turn_steel * 0.75e0 - # Dimension of square cable space inside conduit [m] - dx_tf_turn_cable_space_average = t_conductor - 2.0e0 * dx_tf_turn_steel + # Dimension of square cable space inside conduit [m] + dx_tf_turn_cable_space_average = t_conductor - 2.0e0 * dx_tf_turn_steel - # Cross-sectional area of cable space per turn - # taking account of rounded inside corners [m2] - a_tf_turn_cable_space_no_void = ( - dx_tf_turn_cable_space_average**2 - - (4.0e0 - np.pi) * radius_tf_turn_cable_space_corners**2 - ) + # Cross-sectional area of cable space per turn + # taking account of rounded inside corners [m2] + a_tf_turn_cable_space_no_void = ( + dx_tf_turn_cable_space_average**2 + - (4.0e0 - np.pi) * radius_tf_turn_cable_space_corners**2 + ) - # Calculate the true effective cable space by taking away the cooling - # channel and the extra void fraction + # Calculate the true effective cable space by taking away the cooling + # channel and the extra void fraction - a_tf_turn_cable_space_effective = ( - a_tf_turn_cable_space_no_void - - - # Coolant channel area - ( - (np.pi / 4.0e0) - * dia_tf_turn_coolant_channel - * dia_tf_turn_coolant_channel - ) - # Additional void area deduction - - (a_tf_turn_cable_space_no_void * f_a_tf_turn_cable_space_extra_void) - ) + a_tf_turn_cable_space_effective = ( + a_tf_turn_cable_space_no_void + - + # Coolant channel area + ((np.pi / 4.0e0) * dia_tf_turn_coolant_channel * dia_tf_turn_coolant_channel) + # Additional void area deduction + - (a_tf_turn_cable_space_no_void * f_a_tf_turn_cable_space_extra_void) + ) - f_a_tf_turn_cable_space_cooling = 1 - ( - a_tf_turn_cable_space_effective / a_tf_turn_cable_space_no_void - ) + f_a_tf_turn_cable_space_cooling = 1 - ( + a_tf_turn_cable_space_effective / a_tf_turn_cable_space_no_void + ) - if a_tf_turn_cable_space_no_void <= 0.0e0: - if t_conductor < 0.0e0: - logger.error( - "Negative cable space dimension. %s %s", - a_tf_turn_cable_space_no_void, - dx_tf_turn_cable_space_average, - ) - else: - logger.error( - "Cable space area problem; artificially set rounded corner " + if a_tf_turn_cable_space_no_void <= 0.0e0: + if t_conductor < 0.0e0: + logger.error( + "Negative cable space dimension. %s %s", + a_tf_turn_cable_space_no_void, + dx_tf_turn_cable_space_average, + ) + else: + logger.error( + "Cable space area problem; artificially set rounded corner " "radius to 0. %s %s", - a_tf_turn_cable_space_no_void, - dx_tf_turn_cable_space_average, - ) - radius_tf_turn_cable_space_corners = 0.0e0 - a_tf_turn_cable_space_no_void = dx_tf_turn_cable_space_average**2 - - # Cross-sectional area of conduit jacket per turn [m2] - a_tf_turn_steel = t_conductor**2 - a_tf_turn_cable_space_no_void - - # REBCO turn structure - elif i_tf_sc_mat == 6: - # Diameter of circular cable space inside conduit [m] - dx_tf_turn_cable_space_average = t_conductor - 2.0e0 * dx_tf_turn_steel + a_tf_turn_cable_space_no_void, + dx_tf_turn_cable_space_average, + ) + radius_tf_turn_cable_space_corners = 0.0e0 + a_tf_turn_cable_space_no_void = dx_tf_turn_cable_space_average**2 - # Cross-sectional area of conduit jacket per turn [m2] - a_tf_turn_steel = t_conductor**2 - a_tf_turn_cable_space_no_void + # Cross-sectional area of conduit jacket per turn [m2] + a_tf_turn_steel = t_conductor**2 - a_tf_turn_cable_space_no_void return CICCAveragedTurnGeometry( a_tf_turn_cable_space_no_void=a_tf_turn_cable_space_no_void, diff --git a/tests/unit/models/tfcoil/test_sctfcoil.py b/tests/unit/models/tfcoil/test_sctfcoil.py index 3bb4fe104..036c315bd 100644 --- a/tests/unit/models/tfcoil/test_sctfcoil.py +++ b/tests/unit/models/tfcoil/test_sctfcoil.py @@ -1241,8 +1241,6 @@ class TfAveragedTurnGeomParam(NamedTuple): dx_tf_turn_cable_space_average: Any = None - i_tf_sc_mat: Any = None - j_tf_wp: Any = None dx_tf_turn_steel: Any = None @@ -1283,7 +1281,6 @@ class TfAveragedTurnGeomParam(NamedTuple): dr_tf_turn=0, dx_tf_turn=0, dx_tf_turn_cable_space_average=0, - i_tf_sc_mat=5, j_tf_wp=26493137.688284047, dx_tf_turn_steel=0.0080000000000000019, dx_tf_turn_insulation=0.00080000000000000004, @@ -1309,7 +1306,6 @@ class TfAveragedTurnGeomParam(NamedTuple): dr_tf_turn=0.049532469413859428, dx_tf_turn=0.049532469413859428, dx_tf_turn_cable_space_average=0.031932469413859424, - i_tf_sc_mat=5, j_tf_wp=26493137.688284047, dx_tf_turn_steel=0.0080000000000000019, dx_tf_turn_insulation=0.00080000000000000004, @@ -1335,7 +1331,6 @@ class TfAveragedTurnGeomParam(NamedTuple): dr_tf_turn=0.05872, dx_tf_turn=0.05872, dx_tf_turn_cable_space_average=0.04109, - i_tf_sc_mat=1, j_tf_wp=2.301e07, dx_tf_turn_steel=8.015e-03, dx_tf_turn_insulation=8.0e-4, @@ -1361,7 +1356,6 @@ class TfAveragedTurnGeomParam(NamedTuple): dr_tf_turn=0.05872, dx_tf_turn=0.05872, dx_tf_turn_cable_space_average=0.04109, - i_tf_sc_mat=1, j_tf_wp=2.673e07, dx_tf_turn_steel=8.148e-03, dx_tf_turn_insulation=8.0e-4, @@ -1399,7 +1393,6 @@ def test_tf_cable_in_conduit_averaged_turn_geometry( j_tf_wp=tfaveragedturngeomparam.j_tf_wp, dx_tf_turn_steel=tfaveragedturngeomparam.dx_tf_turn_steel, dx_tf_turn_insulation=tfaveragedturngeomparam.dx_tf_turn_insulation, - i_tf_sc_mat=tfaveragedturngeomparam.i_tf_sc_mat, dx_tf_turn_general=tfaveragedturngeomparam.dx_tf_turn_general, c_tf_turn=tfaveragedturngeomparam.c_tf_turn, i_dx_tf_turn_general_input=tfaveragedturngeomparam.i_dx_tf_turn_general_input, From f322a3ac18c8b39159bfd0a5bdd791575fc84391 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Fri, 17 Apr 2026 11:30:36 +0100 Subject: [PATCH 03/37] Refactor CICCSuperconductingTFCoil to simplify cable calculations by removing unnecessary conditionals --- process/models/tfcoil/superconducting.py | 31 +++++++++++------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/process/models/tfcoil/superconducting.py b/process/models/tfcoil/superconducting.py index e57614c11..2cbded70e 100644 --- a/process/models/tfcoil/superconducting.py +++ b/process/models/tfcoil/superconducting.py @@ -1693,24 +1693,21 @@ def run(self, output: bool = False): # Calculate number of cables in turn if CICC conductor # --------------------------------------------------- - if ( - SuperconductorModel(tfcoil_variables.i_tf_sc_mat) - != SuperconductorModel.CROCO_REBCO - ): - superconducting_tf_coil_variables.n_tf_turn_superconducting_cables = self.calculate_cable_in_conduit_strand_count( - a_cable_space=superconducting_tf_coil_variables.a_tf_turn_cable_space_effective, - dia_superconductor_strand=superconducting_tf_coil_variables.dia_tf_turn_superconducting_cable, - ) - ( - superconducting_tf_coil_variables.len_tf_coil_superconductor, - superconducting_tf_coil_variables.len_tf_superconductor_total, - ) = self.calculate_cable_in_conduit_superconductor_length( - n_tf_coils=tfcoil_variables.n_tf_coils, - n_tf_coil_turns=tfcoil_variables.n_tf_coil_turns, - len_tf_coil=tfcoil_variables.len_tf_coil, - n_tf_turn_superconducting_cables=superconducting_tf_coil_variables.n_tf_turn_superconducting_cables, - ) + superconducting_tf_coil_variables.n_tf_turn_superconducting_cables = self.calculate_cable_in_conduit_strand_count( + a_cable_space=superconducting_tf_coil_variables.a_tf_turn_cable_space_effective, + dia_superconductor_strand=superconducting_tf_coil_variables.dia_tf_turn_superconducting_cable, + ) + + ( + superconducting_tf_coil_variables.len_tf_coil_superconductor, + superconducting_tf_coil_variables.len_tf_superconductor_total, + ) = self.calculate_cable_in_conduit_superconductor_length( + n_tf_coils=tfcoil_variables.n_tf_coils, + n_tf_coil_turns=tfcoil_variables.n_tf_coil_turns, + len_tf_coil=tfcoil_variables.len_tf_coil, + n_tf_turn_superconducting_cables=superconducting_tf_coil_variables.n_tf_turn_superconducting_cables, + ) # Areas and fractions # ------------------- From 07e5966933d4938010fa07ffbf750a1d3e0a25fc Mon Sep 17 00:00:00 2001 From: mn3981 Date: Fri, 17 Apr 2026 12:13:54 +0100 Subject: [PATCH 04/37] Update main_plot to handle different superconducting turn types and improve cable geometry plotting --- process/core/io/plot/summary.py | 40 ++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/process/core/io/plot/summary.py b/process/core/io/plot/summary.py index b340d0ab2..bc5b0508b 100644 --- a/process/core/io/plot/summary.py +++ b/process/core/io/plot/summary.py @@ -73,7 +73,12 @@ PlasmaShapeModelType, ) from process.models.superconductors import SuperconductorModel -from process.models.tfcoil.base import TFCoilShapeModel, TFPlasmaCaseType +from process.models.tfcoil.base import ( + TFCoilShapeModel, + TFConductorModel, + TFPlasmaCaseType, +) +from process.models.tfcoil.superconducting import SuperconductingTFTurnType @dataclass @@ -14415,7 +14420,7 @@ def main_plot( plot_lower_vertical_build(ax18b, m_file, colour_scheme) # Can only plot WP and turn structure if superconducting coil at the moment - if m_file.get("i_tf_sup", scan=scan) == 1: + if m_file.get("i_tf_sup", scan=scan) == TFConductorModel.SUPERCONDUCTING: # TF coil with WP ax19 = figs[24].add_subplot(221, aspect="equal") ax19.set_position([ @@ -14429,10 +14434,33 @@ def main_plot( # TF coil turn structure ax20 = figs[25].add_subplot(325, aspect="equal") ax20.set_position([0.025, 0.5, 0.4, 0.4]) - plot_tf_cable_in_conduit_turn(ax20, figs[25], m_file, scan) - plot_205 = figs[25].add_subplot(223, aspect="equal") - plot_205.set_position([0.075, 0.1, 0.3, 0.3]) - plot_cable_in_conduit_cable(plot_205, figs[25], m_file, scan) + plot_tf_cable_in_conduit_turn(ax20, figs[24], m_file, scan) + + if ( + m_file.get("i_tf_turn_type", scan=scan) + == SuperconductingTFTurnType.CROSS_CONDUCTOR + ): + plot_205 = figs[24].add_subplot(223, aspect="equal") + plot_205.set_position([0.075, 0.1, 0.3, 0.3]) + plot_corc_cable_geometry( + plot_205, + dia_croco_strand=m_file.get("dia_croco_strand", scan=scan), + dx_croco_strand_copper=m_file.get("dx_croco_strand_copper", scan=scan), + dr_hts_tape=m_file.get("dr_hts_tape", scan=scan), + dx_croco_strand_tape_stack=m_file.get( + "dx_croco_strand_tape_stack", scan=scan + ), + n_croco_strand_hts_tapes=m_file.get( + "n_croco_strand_hts_tapes", scan=scan + ), + ) + elif ( + m_file.get("i_tf_turn_type", scan=scan) + == SuperconductingTFTurnType.CABLE_IN_CONDUIT + ): + plot_205 = figs[24].add_subplot(223, aspect="equal") + plot_205.set_position([0.075, 0.1, 0.3, 0.3]) + plot_cable_in_conduit_cable(plot_205, figs[24], m_file, scan) else: ax19 = figs[24].add_subplot(211, aspect="equal") ax19.set_position([0.06, 0.55, 0.675, 0.4]) From 4c5eabe2ec47bcd7a61754c65982438496e04be2 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Fri, 17 Apr 2026 14:32:46 +0100 Subject: [PATCH 05/37] Add output_croco_info method to CROCOSuperconductingTFCoil for detailed cable and conductor information --- process/core/output.py | 1 + process/models/tfcoil/superconducting.py | 544 ++++++++++++----------- 2 files changed, 274 insertions(+), 271 deletions(-) diff --git a/process/core/output.py b/process/core/output.py index 6a2fc187e..98b718dfb 100644 --- a/process/core/output.py +++ b/process/core/output.py @@ -80,6 +80,7 @@ def write(models, data, _outfile): models.cicc_sctfcoil.output() elif tf_turn_type == SuperconductingTFTurnType.CROSS_CONDUCTOR: models.croco_sctfcoil.output() + models.croco_sctfcoil.output_croco_info() else: raise ValueError( "Unsupported superconducting TF turn type: " diff --git a/process/models/tfcoil/superconducting.py b/process/models/tfcoil/superconducting.py index 2cbded70e..804d8af9b 100644 --- a/process/models/tfcoil/superconducting.py +++ b/process/models/tfcoil/superconducting.py @@ -3448,6 +3448,7 @@ def run(self, output: bool = False): if output: self.outtf() + self.output_croco_info() def tf_croco_averaged_turn_geometry( self, @@ -3710,277 +3711,6 @@ def supercon_croco( + superconducting_tf_coil_variables.conductor_rebco_area ) - if tfcoil_variables.temp_margin <= 0.0e0: - logger.error( - f"""Negative TFC temperature margin - temp_margin: {tfcoil_variables.temp_margin} - b_tf_inboard_peak_symmetric: {b_tf_inboard_peak_symmetric}""" - ) - - po.oheadr(self.outfile, "Superconducting TF Coils") - po.ovarin(self.outfile, "Superconductor switch", "(isumat)", 6) - po.ocmmnt( - self.outfile, "Superconductor used: REBCO HTS tape in CroCo strand" - ) - - po.ovarre( - self.outfile, - "Thickness of REBCO layer in tape (m)", - "(dx_hts_tape_rebco)", - rebco_variables.dx_hts_tape_rebco, - ) - po.ovarre( - self.outfile, - "Thickness of copper layer in tape (m)", - "(dx_hts_tape_copper)", - rebco_variables.dx_hts_tape_copper, - ) - po.ovarre( - self.outfile, - "Thickness of Hastelloy layer in tape (m) ", - "(dx_hts_tape_hastelloy)", - rebco_variables.dx_hts_tape_hastelloy, - ) - - po.ovarre( - self.outfile, - "Mean width of tape (m)", - "(dr_hts_tape)", - rebco_variables.dr_hts_tape, - "OP ", - ) - po.ovarre( - self.outfile, - "Diameter of a CroCo strand (m) ", - "(dia_croco_strand)", - rebco_variables.dia_croco_strand, - "OP ", - ) - po.ovarre( - self.outfile, - "Inner diameter of CroCo copper tube (m) ", - "(dia_croco_strand_tape_region)", - rebco_variables.dia_croco_strand_tape_region, - "OP ", - ) - po.ovarre( - self.outfile, - "Thickness of of o copper tube (m) ", - "(dx_croco_strand_copper)", - rebco_variables.dx_croco_strand_copper, - ) - - po.ovarre( - self.outfile, - "Thickness of each HTS tape ", - "(dx_hts_tape_total)", - rebco_variables.dx_hts_tape_total, - "OP ", - ) - po.ovarre( - self.outfile, - "Thickness of stack of rebco_variables.n_croco_strand_hts_tapes (m) ", - "(dx_croco_strand_tape_stack)", - rebco_variables.dx_croco_strand_tape_stack, - "OP ", - ) - po.ovarre( - self.outfile, - "Number of rebco_variables.n_croco_strand_hts_tapes in strand", - "(n_croco_strand_hts_tapes)", - rebco_variables.n_croco_strand_hts_tapes, - "OP ", - ) - po.oblnkl(self.outfile) - po.ovarre( - self.outfile, - "Area of REBCO in strand (m2)", - "(a_croco_strand_rebco)", - rebco_variables.a_croco_strand_rebco, - "OP ", - ) - po.ovarre( - self.outfile, - "Area of copper in strand (m2)", - "(a_croco_strand_copper_total)", - rebco_variables.a_croco_strand_copper_total, - "OP ", - ) - po.ovarre( - self.outfile, - "Area of hastelloy substrate in strand (m2) ", - "(a_croco_strand_hastelloy)", - rebco_variables.a_croco_strand_hastelloy, - "OP ", - ) - po.ovarre( - self.outfile, - "Area of solder in strand (m2) ", - "(a_croco_strand_solder)", - rebco_variables.a_croco_strand_solder, - "OP ", - ) - po.ovarre( - self.outfile, - "Total: area of CroCo strand (m2) ", - "(croco_strand_area)", - superconducting_tf_coil_variables.croco_strand_area, - "OP ", - ) - if ( - abs( - superconducting_tf_coil_variables.croco_strand_area - - ( - rebco_variables.a_croco_strand_rebco - + rebco_variables.a_croco_strand_copper_total - + rebco_variables.a_croco_strand_hastelloy - + rebco_variables.a_croco_strand_solder - ) - ) - > 1e-6 - ): - po.ocmmnt(self.outfile, "ERROR: Areas in CroCo strand do not add up") - logger.error("Areas in CroCo strand do not add up - see OUT.DAT") - - po.oblnkl(self.outfile) - po.ocmmnt(self.outfile, "Cable information") - po.ovarin( - self.outfile, - "Number of CroCo strands in the cable (fixed) ", - "", - 6, - "OP ", - ) - po.ovarre( - self.outfile, - "Total area of cable space (m2)", - "(a_tf_turn_cable_space_no_void)", - tfcoil_variables.a_tf_turn_cable_space_no_void, - "OP ", - ) - - po.oblnkl(self.outfile) - po.ocmmnt( - self.outfile, - "Conductor information (includes jacket, not including insulation)", - ) - po.ovarre( - self.outfile, - "Width of square conductor (cable + steel jacket) (m)", - "(t_conductor)", - tfcoil_variables.t_conductor, - "OP ", - ) - po.ovarre( - self.outfile, - "Area of conductor (m2)", - "(area)", - superconducting_tf_coil_variables.conductor_area, - "OP ", - ) - po.ovarre( - self.outfile, - "REBCO area of conductor (mm2)", - "(a_croco_strand_rebco)", - superconducting_tf_coil_variables.conductor_rebco_area, - "OP ", - ) - po.ovarre( - self.outfile, - "Area of central copper bar (mm2)", - "(copper_bar_area)", - superconducting_tf_coil_variables.conductor_copper_bar_area, - "OP ", - ) - po.ovarre( - self.outfile, - "Total copper area of conductor, total (mm2)", - "(a_croco_strand_copper_total)", - superconducting_tf_coil_variables.conductor_copper_area, - "OP ", - ) - po.ovarre( - self.outfile, - "Hastelloy area of conductor (mm2)", - "(a_croco_strand_hastelloy)", - superconducting_tf_coil_variables.conductor_hastelloy_area, - "OP ", - ) - po.ovarre( - self.outfile, - "Solder area of conductor (mm2)", - "(a_croco_strand_solder)", - superconducting_tf_coil_variables.conductor_solder_area, - "OP ", - ) - po.ovarre( - self.outfile, - "Jacket area of conductor (mm2)", - "(jacket_area)", - superconducting_tf_coil_variables.conductor_jacket_area, - "OP ", - ) - po.ovarre( - self.outfile, - "Helium area of conductor (mm2)", - "(helium_area)", - superconducting_tf_coil_variables.conductor_helium_area, - "OP ", - ) - if abs(total - superconducting_tf_coil_variables.conductor_area) > 1e-8: - po.ovarre( - self.outfile, - "ERROR: conductor areas do not add up:", - "(total)", - total, - "OP ", - ) - logger.error(f"conductor areas do not add up. total: {total}") - - po.ovarre( - self.outfile, - "Critical current of CroCo strand (A)", - "(croco_strand_critical_current)", - superconducting_tf_coil_variables.croco_strand_critical_current, - "OP ", - ) - po.ovarre( - self.outfile, - "Critical current of conductor (A) ", - "(conductor_critical_current)", - superconducting_tf_coil_variables.conductor_critical_current, - "OP ", - ) - - if global_variables.run_tests == 1: - po.oblnkl(self.outfile) - po.ocmmnt( - self.outfile, - "PROCESS TF Coil peak field fit. Values for t, z and y:", - ) - po.oblnkl(self.outfile) - po.ovarre( - self.outfile, - "Dimensionless winding pack width", - "(tf_fit_t)", - superconducting_tf_coil_variables.tf_fit_t, - "OP ", - ) - po.ovarre( - self.outfile, - "Dimensionless winding pack radial thickness", - "(tf_fit_z)", - superconducting_tf_coil_variables.tf_fit_z, - "OP ", - ) - po.ovarre( - self.outfile, - "Ratio of actual peak field to nominal axisymmetric peak field", - "(f_b_tf_inboard_peak_ripple_symmetric)", - superconducting_tf_coil_variables.f_b_tf_inboard_peak_ripple_symmetric, - "OP ", - ) - po.oblnkl(self.outfile) po.ovarre( self.outfile, @@ -4096,6 +3826,278 @@ def croco_voltage() -> float: return croco_voltage + def output_croco_info(self): + total = ( + superconducting_tf_coil_variables.conductor_copper_area + + superconducting_tf_coil_variables.conductor_hastelloy_area + + superconducting_tf_coil_variables.conductor_solder_area + + superconducting_tf_coil_variables.conductor_jacket_area + + superconducting_tf_coil_variables.conductor_helium_area + + superconducting_tf_coil_variables.conductor_rebco_area + ) + + po.oheadr(self.outfile, "Superconducting TF Coils") + po.ovarin(self.outfile, "Superconductor switch", "(isumat)", 6) + po.ocmmnt(self.outfile, "Superconductor used: REBCO HTS tape in CroCo strand") + + po.ovarre( + self.outfile, + "Thickness of REBCO layer in tape (m)", + "(dx_hts_tape_rebco)", + rebco_variables.dx_hts_tape_rebco, + ) + po.ovarre( + self.outfile, + "Thickness of copper layer in tape (m)", + "(dx_hts_tape_copper)", + rebco_variables.dx_hts_tape_copper, + ) + po.ovarre( + self.outfile, + "Thickness of Hastelloy layer in tape (m) ", + "(dx_hts_tape_hastelloy)", + rebco_variables.dx_hts_tape_hastelloy, + ) + + po.ovarre( + self.outfile, + "Mean width of tape (m)", + "(dr_hts_tape)", + rebco_variables.dr_hts_tape, + "OP ", + ) + po.ovarre( + self.outfile, + "Diameter of a CroCo strand (m) ", + "(dia_croco_strand)", + rebco_variables.dia_croco_strand, + "OP ", + ) + po.ovarre( + self.outfile, + "Inner diameter of CroCo copper tube (m) ", + "(dia_croco_strand_tape_region)", + rebco_variables.dia_croco_strand_tape_region, + "OP ", + ) + po.ovarre( + self.outfile, + "Thickness of of o copper tube (m) ", + "(dx_croco_strand_copper)", + rebco_variables.dx_croco_strand_copper, + ) + + po.ovarre( + self.outfile, + "Thickness of each HTS tape ", + "(dx_hts_tape_total)", + rebco_variables.dx_hts_tape_total, + "OP ", + ) + po.ovarre( + self.outfile, + "Thickness of stack of rebco_variables.n_croco_strand_hts_tapes (m) ", + "(dx_croco_strand_tape_stack)", + rebco_variables.dx_croco_strand_tape_stack, + "OP ", + ) + po.ovarre( + self.outfile, + "Number of rebco_variables.n_croco_strand_hts_tapes in strand", + "(n_croco_strand_hts_tapes)", + rebco_variables.n_croco_strand_hts_tapes, + "OP ", + ) + po.oblnkl(self.outfile) + po.ovarre( + self.outfile, + "Area of REBCO in strand (m2)", + "(a_croco_strand_rebco)", + rebco_variables.a_croco_strand_rebco, + "OP ", + ) + po.ovarre( + self.outfile, + "Area of copper in strand (m2)", + "(a_croco_strand_copper_total)", + rebco_variables.a_croco_strand_copper_total, + "OP ", + ) + po.ovarre( + self.outfile, + "Area of hastelloy substrate in strand (m2) ", + "(a_croco_strand_hastelloy)", + rebco_variables.a_croco_strand_hastelloy, + "OP ", + ) + po.ovarre( + self.outfile, + "Area of solder in strand (m2) ", + "(a_croco_strand_solder)", + rebco_variables.a_croco_strand_solder, + "OP ", + ) + po.ovarre( + self.outfile, + "Total: area of CroCo strand (m2) ", + "(croco_strand_area)", + superconducting_tf_coil_variables.croco_strand_area, + "OP ", + ) + if ( + abs( + superconducting_tf_coil_variables.croco_strand_area + - ( + rebco_variables.a_croco_strand_rebco + + rebco_variables.a_croco_strand_copper_total + + rebco_variables.a_croco_strand_hastelloy + + rebco_variables.a_croco_strand_solder + ) + ) + > 1e-6 + ): + po.ocmmnt(self.outfile, "ERROR: Areas in CroCo strand do not add up") + logger.error("Areas in CroCo strand do not add up - see OUT.DAT") + + po.oblnkl(self.outfile) + po.ocmmnt(self.outfile, "Cable information") + po.ovarin( + self.outfile, + "Number of CroCo strands in the cable (fixed) ", + "", + 6, + "OP ", + ) + po.ovarre( + self.outfile, + "Total area of cable space (m2)", + "(a_tf_turn_cable_space_no_void)", + tfcoil_variables.a_tf_turn_cable_space_no_void, + "OP ", + ) + + po.oblnkl(self.outfile) + po.ocmmnt( + self.outfile, + "Conductor information (includes jacket, not including insulation)", + ) + po.ovarre( + self.outfile, + "Width of square conductor (cable + steel jacket) (m)", + "(t_conductor)", + tfcoil_variables.t_conductor, + "OP ", + ) + po.ovarre( + self.outfile, + "Area of conductor (m2)", + "(area)", + superconducting_tf_coil_variables.conductor_area, + "OP ", + ) + po.ovarre( + self.outfile, + "REBCO area of conductor (mm2)", + "(a_croco_strand_rebco)", + superconducting_tf_coil_variables.conductor_rebco_area, + "OP ", + ) + po.ovarre( + self.outfile, + "Area of central copper bar (mm2)", + "(copper_bar_area)", + superconducting_tf_coil_variables.conductor_copper_bar_area, + "OP ", + ) + po.ovarre( + self.outfile, + "Total copper area of conductor, total (mm2)", + "(a_croco_strand_copper_total)", + superconducting_tf_coil_variables.conductor_copper_area, + "OP ", + ) + po.ovarre( + self.outfile, + "Hastelloy area of conductor (mm2)", + "(a_croco_strand_hastelloy)", + superconducting_tf_coil_variables.conductor_hastelloy_area, + "OP ", + ) + po.ovarre( + self.outfile, + "Solder area of conductor (mm2)", + "(a_croco_strand_solder)", + superconducting_tf_coil_variables.conductor_solder_area, + "OP ", + ) + po.ovarre( + self.outfile, + "Jacket area of conductor (mm2)", + "(jacket_area)", + superconducting_tf_coil_variables.conductor_jacket_area, + "OP ", + ) + po.ovarre( + self.outfile, + "Helium area of conductor (mm2)", + "(helium_area)", + superconducting_tf_coil_variables.conductor_helium_area, + "OP ", + ) + if abs(total - superconducting_tf_coil_variables.conductor_area) > 1e-8: + po.ovarre( + self.outfile, + "ERROR: conductor areas do not add up:", + "(total)", + total, + "OP ", + ) + logger.error(f"conductor areas do not add up. total: {total}") + + po.ovarre( + self.outfile, + "Critical current of CroCo strand (A)", + "(croco_strand_critical_current)", + superconducting_tf_coil_variables.croco_strand_critical_current, + "OP ", + ) + po.ovarre( + self.outfile, + "Critical current of conductor (A) ", + "(conductor_critical_current)", + superconducting_tf_coil_variables.conductor_critical_current, + "OP ", + ) + + if global_variables.run_tests == 1: + po.oblnkl(self.outfile) + po.ocmmnt( + self.outfile, + "PROCESS TF Coil peak field fit. Values for t, z and y:", + ) + po.oblnkl(self.outfile) + po.ovarre( + self.outfile, + "Dimensionless winding pack width", + "(tf_fit_t)", + superconducting_tf_coil_variables.tf_fit_t, + "OP ", + ) + po.ovarre( + self.outfile, + "Dimensionless winding pack radial thickness", + "(tf_fit_z)", + superconducting_tf_coil_variables.tf_fit_z, + "OP ", + ) + po.ovarre( + self.outfile, + "Ratio of actual peak field to nominal axisymmetric peak field", + "(f_b_tf_inboard_peak_ripple_symmetric)", + superconducting_tf_coil_variables.f_b_tf_inboard_peak_ripple_symmetric, + "OP ", + ) + @staticmethod def lambda_term(tau: float, omega: float) -> float: From d0be4d045fd79c8e1531cb3af716a20c6d7c8c0c Mon Sep 17 00:00:00 2001 From: mn3981 Date: Fri, 17 Apr 2026 15:59:14 +0100 Subject: [PATCH 06/37] Add plot_tf_croco_turn function for visualizing TF coil CICC turn structure with CroCo cable layout --- process/core/io/plot/summary.py | 364 +++++++++++++++++++++++++++++--- 1 file changed, 338 insertions(+), 26 deletions(-) diff --git a/process/core/io/plot/summary.py b/process/core/io/plot/summary.py index bc5b0508b..a648cc017 100644 --- a/process/core/io/plot/summary.py +++ b/process/core/io/plot/summary.py @@ -7509,6 +7509,293 @@ def _pack_strands_rectangular_with_obstacles( ) +def plot_tf_croco_turn(axis: plt.Axes, fig, mfile: MFile, scan: int): + """Plots inboard TF coil CICC individual turn structure with croco cable layout.""" + # Import the TF turn variables then multiply into mm + i_tf_turns_integer = mfile.get("i_tf_turns_integer", scan=scan) + # If integer turns switch is on then the turns can have non square dimensions + if i_tf_turns_integer == 1: + turn_width = mfile.get("dr_tf_turn", scan=scan) + turn_height = mfile.get("dx_tf_turn", scan=scan) + cable_space_width_radial = mfile.get("dr_tf_turn_cable_space", scan=scan) + cable_space_width_toroidal = mfile.get("dx_tf_turn_cable_space", scan=scan) + + elif i_tf_turns_integer == 0: + turn_width = mfile.get("dx_tf_turn_general", scan=scan) + cable_space_width = mfile.get("dx_tf_turn_cable_space_average", scan=scan) + + steel_thickness = mfile.get("dx_tf_turn_steel", scan=scan) + insulation_thickness = mfile.get("dx_tf_turn_insulation", scan=scan) + + a_tf_turn_cable_space_no_void = mfile.get("a_tf_turn_cable_space_no_void", scan=scan) + radius_tf_turn_cable_space_corners = mfile.get( + "radius_tf_turn_cable_space_corners", scan=scan + ) + + a_tf_wp_coolant_channels = mfile.get("a_tf_wp_coolant_channels", scan=scan) + + f_a_tf_turn_cable_space_extra_void = mfile.get( + "f_a_tf_turn_cable_space_extra_void", scan=scan + ) + a_tf_turn_steel = mfile.get("a_tf_turn_steel", scan=scan) + a_tf_turn_cable_space_effective = mfile.get( + "a_tf_turn_cable_space_effective", scan=scan + ) + + he_pipe_diameter = mfile.get("dia_tf_turn_coolant_channel", scan=scan) + dia_croco_strand = mfile.get("dia_croco_strand", scan=scan) + + # Plot the total turn shape + if i_tf_turns_integer == 0: + axis.add_patch( + Rectangle( + [0, 0], + turn_width, + turn_width, + facecolor="red", + edgecolor="black", + ), + ) + # Plot the steel conduit + axis.add_patch( + Rectangle( + [insulation_thickness, insulation_thickness], + (turn_width - 2 * insulation_thickness), + (turn_width - 2 * insulation_thickness), + facecolor="grey", + edgecolor="black", + ), + ) + + # Plot the central cable space + axis.add_patch( + Circle( + [(turn_width / 2), (turn_width / 2)], + 1.5 * dia_croco_strand, + facecolor="white", + edgecolor="black", + linewidth=1.2, + ), + ) + + # PLot the central copper cyclinder + axis.add_patch( + Circle( + [(turn_width / 2), (turn_width / 2)], + dia_croco_strand / 2, + facecolor="#B87333", + edgecolor="#B87333", + linewidth=1.2, + ), + ) + + # Plot six surrounding Croco cables in a hexagonal layout. + center_x = turn_width / 2 + center_y = turn_width / 2 + ring_radius = dia_croco_strand + for angle in np.linspace(0, 2 * np.pi, 6, endpoint=False): + plot_corc_cable_geometry( + axis=axis, + r_centre=center_x + ring_radius * np.cos(angle), + z_centre=center_y + ring_radius * np.sin(angle), + dia_croco_strand=mfile.get("dia_croco_strand", scan=scan), + dx_croco_strand_copper=mfile.get("dx_croco_strand_copper", scan=scan), + dr_hts_tape=mfile.get("dr_hts_tape", scan=scan), + dx_croco_strand_tape_stack=mfile.get( + "dx_croco_strand_tape_stack", scan=scan + ), + n_croco_strand_hts_tapes=mfile.get( + "n_croco_strand_hts_tapes", scan=scan + ), + show_legend=False, + ) + + # Cable strand packing parameters + strand_diameter = mfile.get("dia_tf_turn_superconducting_cable", scan=scan) + void_fraction = mfile.get("f_a_tf_turn_cable_space_extra_void", scan=scan) + + # Cable space bounds + cable_bounds = [ + insulation_thickness + steel_thickness, + insulation_thickness + steel_thickness, + turn_width - 2 * (insulation_thickness + steel_thickness), + turn_width - 2 * (insulation_thickness + steel_thickness), + ] + + axis.set_xlim(-turn_width * 0.05, turn_width * 1.05) + axis.set_ylim(-turn_width * 0.05, turn_width * 1.05) + + axis.minorticks_on() + axis.set_title("WP Turn Structure") + axis.set_xlabel("r [m]") + axis.set_ylabel("x [m]") + + # Add info about the steel casing surrounding the WP + textstr_turn_insulation = ( + f"$\\mathbf{{Turn \\ Insulation:}}$\n\n$\\Delta r:${insulation_thickness:.3e} m" + ) + + axis.text( + 0.4, + 0.9, + textstr_turn_insulation, + fontsize=9, + verticalalignment="top", + horizontalalignment="left", + transform=fig.transFigure, + bbox={ + "boxstyle": "round", + "facecolor": "red", + "alpha": 1.0, + "linewidth": 2, + }, + ) + + # Add info about the steel casing surrounding the WP + textstr_turn_steel = ( + f"$\\mathbf{{Steel \\ Conduit:}}$\n\n$\\Delta r:${steel_thickness:.3e} m\n" + f"$A$: {a_tf_turn_steel:.3e} m$^2$" + ) + + axis.text( + 0.65, + 0.9, + textstr_turn_steel, + fontsize=9, + verticalalignment="top", + horizontalalignment="left", + transform=fig.transFigure, + bbox={ + "boxstyle": "round", + "facecolor": "grey", + "alpha": 1.0, + "linewidth": 2, + }, + ) + + if i_tf_turns_integer == 0: + # Add info about the steel casing surrounding the WP + textstr_turn_cable_space = ( + f"$\\mathbf{{Cable \\ Space:}}$\n\n" + f"$\\Delta r:$ {cable_space_width:.3e} m\n" + f"Corner radius, $r$: {radius_tf_turn_cable_space_corners:.3e} m\n" + f"Cable area with no cooling \nchannel or gaps: {a_tf_turn_cable_space_no_void:.3e} m$^2$\n" + f"Extra cable space area void fraction: {f_a_tf_turn_cable_space_extra_void}\n" + f"True cable space area: {a_tf_turn_cable_space_effective:.3e} m$^2$" + ) + elif i_tf_turns_integer == 1: + textstr_turn_cable_space = ( + f"$\\mathbf{{Cable \\ Space:}}$\n\n" + f"Cable space: \n$\\Delta r$: {cable_space_width_radial:.3e} m \n" + f"$\\Delta x$: {cable_space_width_toroidal:.3e} m \n" + f"Corner radius, $r$: {radius_tf_turn_cable_space_corners:.3e} m\n" + f"Cable area with no cooling channel or gaps: {a_tf_turn_cable_space_no_void:.3e} m$^2$\n" + f"Extra cable space area void fraction: {f_a_tf_turn_cable_space_extra_void}\n" + f"True cable space area: {a_tf_turn_cable_space_effective:.3e} m$^2$" + ) + + axis.text( + 0.40, + 0.7, + textstr_turn_cable_space, + fontsize=9, + verticalalignment="top", + horizontalalignment="left", + transform=fig.transFigure, + bbox={ + "boxstyle": "round", + "facecolor": "royalblue", + "alpha": 1.0, + "linewidth": 2, + }, + ) + + if i_tf_turns_integer == 0: + textstr_turn = ( + f"$\\mathbf{{Turn:}}$\n\n" + f"$\\Delta r$: {turn_width:.3e} m\n" + f"$\\Delta x$: {turn_width:.3e} m" + ) + + if i_tf_turns_integer == 1: + textstr_turn = ( + f"$\\mathbf{{Turn:}}$\n\n" + f"$\\Delta r$: {turn_width:.3e} m\n" + f"$\\Delta x$: {turn_height:.3e} m" + ) + + axis.text( + 0.525, + 0.9, + textstr_turn, + fontsize=9, + verticalalignment="top", + horizontalalignment="left", + transform=fig.transFigure, + bbox={ + "boxstyle": "round", + "facecolor": "wheat", + "alpha": 1.0, + "linewidth": 2, + }, + ) + + # Add info about the steel casing surrounding the WP + textstr_turn_cooling = ( + f"$\\mathbf{{Cooling:}}$\n\n" + f"$\\varnothing$: {he_pipe_diameter:.3e} m\n" + f"Total area of all coolant channels: {a_tf_wp_coolant_channels:.4f} m$^2$" + ) + + axis.text( + 0.45, + 0.8, + textstr_turn_cooling, + fontsize=9, + verticalalignment="top", + horizontalalignment="left", + transform=fig.transFigure, + bbox={ + "boxstyle": "round", + "facecolor": "white", + "alpha": 1.0, + "linewidth": 2, + }, + ) + + textstr_superconductor = ( + f"$\\mathbf{{Superconductor:}}$\n \n" + f"Superconductor used: {SuperconductorModel(mfile.get('i_tf_sc_mat', scan=scan)).full_name}\n" + f"Critical field at zero \ntemperature and strain: {mfile.get('b_tf_superconductor_critical_zero_temp_strain', scan=scan):.4f} T\n" + f"Critical temperature at \nzero field and strain: {mfile.get('temp_tf_superconductor_critical_zero_field_strain', scan=scan):.4f} K\n" + f"Temperature at conductor: {mfile.get('tftmp', scan=scan):.4f} K\n" + f"$I_{{\\text{{TF,turn critical}}}}$: {mfile.get('c_turn_cables_critical', scan=scan):,.2f} A\n" + f"$I_{{\\text{{TF,turn}}}}$: {mfile.get('c_tf_turn', scan=scan):,.2f} A\n" + f"Critcal current ratio: {mfile.get('f_c_tf_turn_operating_critical', scan=scan):,.4f}\n" + f"Superconductor temperature \nmargin: {mfile.get('temp_tf_superconductor_margin', scan=scan):,.4f} K\n" + f"\n$\\mathbf{{Quench:}}$\n \n" + f"Quench dump time: {mfile.get('t_tf_superconductor_quench', scan=scan):.4e} s\n" + f"Quench detection time: {mfile.get('t_tf_quench_detection', scan=scan):.4e} s\n" + f"User input max temperature \nduring quench: {mfile.get('temp_tf_conductor_quench_max', scan=scan):.2f} K\n" + f"Required maxium WP current \ndensity for heat protection:\n{mfile.get('j_tf_wp_quench_heat_max', scan=scan):.2e} A/m$^2$\n" + ) + axis.text( + 0.75, + 0.9, + textstr_superconductor, + fontsize=9, + verticalalignment="top", + horizontalalignment="left", + transform=fig.transFigure, + bbox={ + "boxstyle": "round", + "facecolor": "#6dd3f7", # light blue for superconductors + "alpha": 1.0, + "linewidth": 2, + }, + ) + + def plot_cable_in_conduit_cable(axis: plt.Axes, fig, mfile: MFile, scan: int): """Plots TF coil CICC cable cross-section. @@ -12116,11 +12403,14 @@ def interp1d_profile(profile, mfile: MFile, scan: int): def plot_corc_cable_geometry( axis, + r_centre: float, + z_centre: float, dia_croco_strand: float, dx_croco_strand_copper: float, dr_hts_tape: float, dx_croco_strand_tape_stack: float, n_croco_strand_hts_tapes: int, + show_legend: bool = True, ): """Plot the geometry of a CroCo strand cable. @@ -12128,6 +12418,10 @@ def plot_corc_cable_geometry( ---------- axis : matplotlib.axes._axes.Axes The matplotlib axis to plot on. + r_centre : float + Radial position of the strand centre (in meters). + z_centre : float + Vertical position of the strand centre (in meters). dia_croco_strand : float Diameter of the CroCo strand (in meters). dx_croco_strand_copper : float @@ -12139,64 +12433,69 @@ def plot_corc_cable_geometry( n_croco_strand_hts_tapes : int Number of HTS tape layers in the stack. """ + legend_label = None if show_legend else "_nolegend_" + # Plot a circle with the given diameter and copper edges circle = Circle( - (0, 0), - radius=(dia_croco_strand / 2) * 1000, - edgecolor="#B87333", + (r_centre, z_centre), + radius=(dia_croco_strand / 2), + edgecolor="black", facecolor="#B87333", - linewidth=2, - label="Copper jacket", + linewidth=0.5, + label="Copper jacket" if show_legend else legend_label, ) axis.add_patch(circle) # Plot an inner circle with copper edges circle = Circle( - (0, 0), - radius=((dia_croco_strand / 2) - dx_croco_strand_copper) * 1000, + (r_centre, z_centre), + radius=((dia_croco_strand / 2) - dx_croco_strand_copper), edgecolor="grey", facecolor="grey", linewidth=2, - label="Solder", + label="Solder" if show_legend else legend_label, ) axis.add_patch(circle) # Plot a rectangular tape stack in the middle rect = Rectangle( - (-dr_hts_tape / 2 * 1000, -(dx_croco_strand_tape_stack / 2) * 1000), - width=dr_hts_tape * 1000, - height=dx_croco_strand_tape_stack * 1000, + (r_centre - dr_hts_tape / 2, z_centre - dx_croco_strand_tape_stack / 2), + width=dr_hts_tape, + height=dx_croco_strand_tape_stack, edgecolor="blue", facecolor="blue", linewidth=2, - label="HTS Tape Stack", + label="HTS Tape Stack" if show_legend else legend_label, ) axis.add_patch(rect) # Slice the tape stack into n_croco_strand_hts_tapes layers for i in range(int(n_croco_strand_hts_tapes)): - y_start = -(dx_croco_strand_tape_stack / 2) * 1000 + i * ( - dx_croco_strand_tape_stack / n_croco_strand_hts_tapes * 1000 + y_start = ( + z_centre + - (dx_croco_strand_tape_stack / 2) + + i * (dx_croco_strand_tape_stack / n_croco_strand_hts_tapes) ) rect = Rectangle( - (-dr_hts_tape / 2 * 1000, y_start), - width=dr_hts_tape * 1000, - height=(dx_croco_strand_tape_stack / n_croco_strand_hts_tapes) * 1000, + (r_centre - dr_hts_tape / 2, y_start), + width=dr_hts_tape, + height=(dx_croco_strand_tape_stack / n_croco_strand_hts_tapes), edgecolor="black", facecolor="blue", linewidth=1, ) axis.add_patch(rect) - axis.set_xlim(-dia_croco_strand * 0.75 * 1000, dia_croco_strand * 0.75 * 1000) - axis.set_ylim(-dia_croco_strand * 1000, dia_croco_strand * 1000) + axis.set_xlim(-dia_croco_strand * 0.75, dia_croco_strand * 0.75) + axis.set_ylim(-dia_croco_strand * 0.75, dia_croco_strand * 0.75) axis.set_aspect("equal", adjustable="datalim") axis.set_title("CroCo Strand Geometry") axis.grid(True) - axis.set_xlabel("X-axis (mm)") - axis.set_ylabel("Y-axis (mm)") + axis.set_xlabel("X-axis (m)") + axis.set_ylabel("Y-axis (m)") axis.minorticks_on() - axis.legend(loc="upper right") + if show_legend: + axis.legend(loc="upper right") def reaction_plot_grid( @@ -14431,10 +14730,21 @@ def main_plot( ]) # Half height, a bit wider, top left plot_superconducting_tf_wp(ax19, m_file, scan, figs[24]) - # TF coil turn structure - ax20 = figs[25].add_subplot(325, aspect="equal") - ax20.set_position([0.025, 0.5, 0.4, 0.4]) - plot_tf_cable_in_conduit_turn(ax20, figs[24], m_file, scan) + if ( + m_file.get("i_tf_turn_type", scan=scan) + == SuperconductingTFTurnType.CROSS_CONDUCTOR + ): + ax20 = figs[24].add_subplot(325, aspect="equal") + ax20.set_position([0.025, 0.5, 0.4, 0.4]) + plot_tf_croco_turn(ax20, figs[24], m_file, scan) + elif ( + m_file.get("i_tf_turn_type", scan=scan) + == SuperconductingTFTurnType.CABLE_IN_CONDUIT + ): + # TF coil turn structure + ax20 = figs[24].add_subplot(325, aspect="equal") + ax20.set_position([0.025, 0.5, 0.4, 0.4]) + plot_tf_cable_in_conduit_turn(ax20, figs[24], m_file, scan) if ( m_file.get("i_tf_turn_type", scan=scan) @@ -14444,6 +14754,8 @@ def main_plot( plot_205.set_position([0.075, 0.1, 0.3, 0.3]) plot_corc_cable_geometry( plot_205, + r_centre=0.0, + z_centre=0.0, dia_croco_strand=m_file.get("dia_croco_strand", scan=scan), dx_croco_strand_copper=m_file.get("dx_croco_strand_copper", scan=scan), dr_hts_tape=m_file.get("dr_hts_tape", scan=scan), From 4697d55f5b97248d86ee8113f5527e5fef30b01c Mon Sep 17 00:00:00 2001 From: mn3981 Date: Fri, 17 Apr 2026 16:00:47 +0100 Subject: [PATCH 07/37] Remove unsupported integer turn geometry handling for CroCo conductor in CROCOSuperconductingTFCoil --- process/models/tfcoil/superconducting.py | 30 +++--------------------- 1 file changed, 3 insertions(+), 27 deletions(-) diff --git a/process/models/tfcoil/superconducting.py b/process/models/tfcoil/superconducting.py index 804d8af9b..792009266 100644 --- a/process/models/tfcoil/superconducting.py +++ b/process/models/tfcoil/superconducting.py @@ -3052,33 +3052,9 @@ def run(self, output: bool = False): avg_turn_geometry.dx_tf_turn_cable_space_average ) - else: - # Integer number of turns - ( - superconducting_tf_coil_variables.radius_tf_turn_cable_space_corners, - superconducting_tf_coil_variables.dr_tf_turn, - superconducting_tf_coil_variables.dx_tf_turn, - tfcoil_variables.a_tf_turn_cable_space_no_void, - tfcoil_variables.a_tf_turn_steel, - tfcoil_variables.a_tf_turn_insulation, - tfcoil_variables.c_tf_turn, - tfcoil_variables.n_tf_coil_turns, - superconducting_tf_coil_variables.t_conductor_radial, - superconducting_tf_coil_variables.t_conductor_toroidal, - tfcoil_variables.t_conductor, - superconducting_tf_coil_variables.dr_tf_turn_cable_space, - superconducting_tf_coil_variables.dx_tf_turn_cable_space, - superconducting_tf_coil_variables.dx_tf_turn_cable_space_average, - ) = self.tf_cable_in_conduit_integer_turn_geometry( - dr_tf_wp_with_insulation=tfcoil_variables.dr_tf_wp_with_insulation, - dx_tf_wp_insulation=tfcoil_variables.dx_tf_wp_insulation, - dx_tf_wp_insertion_gap=tfcoil_variables.dx_tf_wp_insertion_gap, - n_tf_wp_layers=tfcoil_variables.n_tf_wp_layers, - dx_tf_wp_toroidal_min=superconducting_tf_coil_variables.dx_tf_wp_toroidal_min, - n_tf_wp_pancakes=tfcoil_variables.n_tf_wp_pancakes, - c_tf_coil=superconducting_tf_coil_variables.c_tf_coil, - dx_tf_turn_steel=tfcoil_variables.dx_tf_turn_steel, - dx_tf_turn_insulation=tfcoil_variables.dx_tf_turn_insulation, + elif tfcoil_variables.i_tf_turns_integer == 1: + raise ProcessValueError( + "Integer turn geometry not implemented for CroCo conductor." ) # Calculate number of cables in turn if CICC conductor From 251380002ac50455098aadb2c8ab7e7a9c8f4134 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Fri, 17 Apr 2026 17:43:30 +0100 Subject: [PATCH 08/37] Refactor CROCOSuperconductingTFCoil to streamline conductor area calculations and remove unused variable --- .../data_structure/superconducting_tf_coil_variables.py | 1 - process/models/superconductors.py | 2 +- process/models/tfcoil/superconducting.py | 7 ++----- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/process/data_structure/superconducting_tf_coil_variables.py b/process/data_structure/superconducting_tf_coil_variables.py index 82ae7d2e3..285a607f6 100644 --- a/process/data_structure/superconducting_tf_coil_variables.py +++ b/process/data_structure/superconducting_tf_coil_variables.py @@ -247,7 +247,6 @@ conductor_rebco_area: float = None conductor_rebco_fraction: float = None conductor_critical_current: float = None -conductor_acs: float = None conductor_area: float = None """Area of cable space inside jacket""" diff --git a/process/models/superconductors.py b/process/models/superconductors.py index ab9b120da..4f3079cc1 100644 --- a/process/models/superconductors.py +++ b/process/models/superconductors.py @@ -1172,7 +1172,7 @@ def croco(j_crit_sc, conductor_area, dia_croco_strand, dx_croco_strand_copper): conductor_copper_fraction = conductor_copper_area / conductor_area # Helium area is set by the user. - # conductor_helium_area = cable_helium_fraction * conductor_acs + # conductor_helium_area = cable_helium_fraction * tfcoil_variables.a_tf_turn_cable_space_no_void conductor_helium_area = np.pi / 2.0 * dia_croco_strand**2 conductor_helium_fraction = conductor_helium_area / conductor_area diff --git a/process/models/tfcoil/superconducting.py b/process/models/tfcoil/superconducting.py index 792009266..edb517ef5 100644 --- a/process/models/tfcoil/superconducting.py +++ b/process/models/tfcoil/superconducting.py @@ -3601,11 +3601,8 @@ def supercon_croco( tfcoil_variables.t_conductor / 3.0e0 - tfcoil_variables.dx_tf_turn_steel * (2.0e0 / 3.0e0) ) - superconducting_tf_coil_variables.conductor_acs = ( - 9.0e0 / 4.0e0 * np.pi * rebco_variables.dia_croco_strand**2 - ) tfcoil_variables.a_tf_turn_cable_space_no_void = ( - superconducting_tf_coil_variables.conductor_acs + 9.0e0 / 4.0e0 * np.pi * rebco_variables.dia_croco_strand**2 ) superconducting_tf_coil_variables.conductor_area = ( tfcoil_variables.t_conductor**2 @@ -3613,7 +3610,7 @@ def supercon_croco( superconducting_tf_coil_variables.conductor_jacket_area = ( superconducting_tf_coil_variables.conductor_area - - superconducting_tf_coil_variables.conductor_acs + - tfcoil_variables.a_tf_turn_cable_space_no_void ) tfcoil_variables.a_tf_turn_steel = ( superconducting_tf_coil_variables.conductor_jacket_area From bcd9706b57e8e0254116bee856adf9e49a045190 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Fri, 17 Apr 2026 17:50:08 +0100 Subject: [PATCH 09/37] Post rebase summary file changes --- process/core/io/plot/summary.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/process/core/io/plot/summary.py b/process/core/io/plot/summary.py index a648cc017..c31da47d4 100644 --- a/process/core/io/plot/summary.py +++ b/process/core/io/plot/summary.py @@ -14734,23 +14734,23 @@ def main_plot( m_file.get("i_tf_turn_type", scan=scan) == SuperconductingTFTurnType.CROSS_CONDUCTOR ): - ax20 = figs[24].add_subplot(325, aspect="equal") + ax20 = figs[25].add_subplot(325, aspect="equal") ax20.set_position([0.025, 0.5, 0.4, 0.4]) - plot_tf_croco_turn(ax20, figs[24], m_file, scan) + plot_tf_croco_turn(ax20, figs[25], m_file, scan) elif ( m_file.get("i_tf_turn_type", scan=scan) == SuperconductingTFTurnType.CABLE_IN_CONDUIT ): # TF coil turn structure - ax20 = figs[24].add_subplot(325, aspect="equal") + ax20 = figs[25].add_subplot(325, aspect="equal") ax20.set_position([0.025, 0.5, 0.4, 0.4]) - plot_tf_cable_in_conduit_turn(ax20, figs[24], m_file, scan) + plot_tf_cable_in_conduit_turn(ax20, figs[25], m_file, scan) if ( m_file.get("i_tf_turn_type", scan=scan) == SuperconductingTFTurnType.CROSS_CONDUCTOR ): - plot_205 = figs[24].add_subplot(223, aspect="equal") + plot_205 = figs[25].add_subplot(223, aspect="equal") plot_205.set_position([0.075, 0.1, 0.3, 0.3]) plot_corc_cable_geometry( plot_205, @@ -14770,9 +14770,9 @@ def main_plot( m_file.get("i_tf_turn_type", scan=scan) == SuperconductingTFTurnType.CABLE_IN_CONDUIT ): - plot_205 = figs[24].add_subplot(223, aspect="equal") + plot_205 = figs[25].add_subplot(223, aspect="equal") plot_205.set_position([0.075, 0.1, 0.3, 0.3]) - plot_cable_in_conduit_cable(plot_205, figs[24], m_file, scan) + plot_cable_in_conduit_cable(plot_205, figs[25], m_file, scan) else: ax19 = figs[24].add_subplot(211, aspect="equal") ax19.set_position([0.06, 0.55, 0.675, 0.4]) From 0336f2bfe1dedc28936f6708873755043e166b2c Mon Sep 17 00:00:00 2001 From: mn3981 Date: Fri, 17 Apr 2026 18:07:52 +0100 Subject: [PATCH 10/37] Add effective cable space area calculation in CROCOSuperconductingTFCoil --- process/models/tfcoil/superconducting.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/process/models/tfcoil/superconducting.py b/process/models/tfcoil/superconducting.py index edb517ef5..61007c01f 100644 --- a/process/models/tfcoil/superconducting.py +++ b/process/models/tfcoil/superconducting.py @@ -3601,9 +3601,16 @@ def supercon_croco( tfcoil_variables.t_conductor / 3.0e0 - tfcoil_variables.dx_tf_turn_steel * (2.0e0 / 3.0e0) ) + # Area of the full cable circle in the turn tfcoil_variables.a_tf_turn_cable_space_no_void = ( 9.0e0 / 4.0e0 * np.pi * rebco_variables.dia_croco_strand**2 ) + # Area of the full cable spac circle minus the central copper strand + superconducting_tf_coil_variables.a_tf_turn_cable_space_effective = ( + tfcoil_variables.a_tf_turn_cable_space_no_void + - 0.25e0 * np.pi * rebco_variables.dia_croco_strand**2 + ) + superconducting_tf_coil_variables.conductor_area = ( tfcoil_variables.t_conductor**2 ) # does this not assume it's a sqaure??? From c6daae6cf532363ab4328854b80fd14dd4e2d32a Mon Sep 17 00:00:00 2001 From: mn3981 Date: Fri, 17 Apr 2026 18:16:00 +0100 Subject: [PATCH 11/37] Refactor CROCOSuperconductingTFCoil to update Croco cable diameter variable names and calculations --- process/core/io/plot/summary.py | 12 +++++------ .../superconducting_tf_coil_variables.py | 5 +++++ process/models/tfcoil/superconducting.py | 21 +++++++++++-------- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/process/core/io/plot/summary.py b/process/core/io/plot/summary.py index c31da47d4..f2f8bc088 100644 --- a/process/core/io/plot/summary.py +++ b/process/core/io/plot/summary.py @@ -7543,7 +7543,7 @@ def plot_tf_croco_turn(axis: plt.Axes, fig, mfile: MFile, scan: int): ) he_pipe_diameter = mfile.get("dia_tf_turn_coolant_channel", scan=scan) - dia_croco_strand = mfile.get("dia_croco_strand", scan=scan) + dia_tf_turn_croco_cable = mfile.get("dia_tf_turn_croco_cable", scan=scan) # Plot the total turn shape if i_tf_turns_integer == 0: @@ -7571,7 +7571,7 @@ def plot_tf_croco_turn(axis: plt.Axes, fig, mfile: MFile, scan: int): axis.add_patch( Circle( [(turn_width / 2), (turn_width / 2)], - 1.5 * dia_croco_strand, + 1.5 * dia_tf_turn_croco_cable, facecolor="white", edgecolor="black", linewidth=1.2, @@ -7582,7 +7582,7 @@ def plot_tf_croco_turn(axis: plt.Axes, fig, mfile: MFile, scan: int): axis.add_patch( Circle( [(turn_width / 2), (turn_width / 2)], - dia_croco_strand / 2, + dia_tf_turn_croco_cable / 2, facecolor="#B87333", edgecolor="#B87333", linewidth=1.2, @@ -7592,13 +7592,13 @@ def plot_tf_croco_turn(axis: plt.Axes, fig, mfile: MFile, scan: int): # Plot six surrounding Croco cables in a hexagonal layout. center_x = turn_width / 2 center_y = turn_width / 2 - ring_radius = dia_croco_strand + ring_radius = dia_tf_turn_croco_cable for angle in np.linspace(0, 2 * np.pi, 6, endpoint=False): plot_corc_cable_geometry( axis=axis, r_centre=center_x + ring_radius * np.cos(angle), z_centre=center_y + ring_radius * np.sin(angle), - dia_croco_strand=mfile.get("dia_croco_strand", scan=scan), + dia_croco_strand=mfile.get("dia_tf_turn_croco_cable", scan=scan), dx_croco_strand_copper=mfile.get("dx_croco_strand_copper", scan=scan), dr_hts_tape=mfile.get("dr_hts_tape", scan=scan), dx_croco_strand_tape_stack=mfile.get( @@ -14756,7 +14756,7 @@ def main_plot( plot_205, r_centre=0.0, z_centre=0.0, - dia_croco_strand=m_file.get("dia_croco_strand", scan=scan), + dia_croco_strand=m_file.get("dia_tf_turn_croco_cable", scan=scan), dx_croco_strand_copper=m_file.get("dx_croco_strand_copper", scan=scan), dr_hts_tape=m_file.get("dr_hts_tape", scan=scan), dx_croco_strand_tape_stack=m_file.get( diff --git a/process/data_structure/superconducting_tf_coil_variables.py b/process/data_structure/superconducting_tf_coil_variables.py index 285a607f6..27a444fc9 100644 --- a/process/data_structure/superconducting_tf_coil_variables.py +++ b/process/data_structure/superconducting_tf_coil_variables.py @@ -183,6 +183,9 @@ dia_tf_turn_superconducting_cable: float = None """Diameter of the superconducting cable in the TF turn [m]""" +dia_tf_turn_croco_cable: float = None +"""Diameter of the Croco cable in the TF turn [m]""" + n_tf_turn_superconducting_cables: int = None """Number of superconducting cables in the TF turn""" @@ -312,6 +315,7 @@ def init_superconducting_tf_coil_variables(): a_tf_turn_cable_space_effective, \ dr_tf_wp_no_insulation, \ dia_tf_turn_superconducting_cable, \ + dia_tf_turn_croco_cable, \ n_tf_turn_superconducting_cables, \ len_tf_coil_superconductor, \ len_tf_superconductor_total, \ @@ -374,6 +378,7 @@ def init_superconducting_tf_coil_variables(): a_tf_turn_cable_space_effective = 0.0 dr_tf_wp_no_insulation = 0.0 dia_tf_turn_superconducting_cable = 0.00073 + dia_tf_turn_croco_cable = 0.0 n_tf_turn_superconducting_cables = 0 len_tf_coil_superconductor = 0.0 len_tf_superconductor_total = 0.0 diff --git a/process/models/tfcoil/superconducting.py b/process/models/tfcoil/superconducting.py index 61007c01f..696359d99 100644 --- a/process/models/tfcoil/superconducting.py +++ b/process/models/tfcoil/superconducting.py @@ -3594,21 +3594,24 @@ def supercon_croco( j_crit_sc: float = 0.0 # Find critical current density in superconducting cable, j_crit_cable j_crit_sc, _ = superconductors.jcrit_rebco(thelium, b_tf_inboard_peak_symmetric) - # tfcoil_variables.a_tf_turn_cable_space_no_void : Cable space - inside area (m2) - # Set new rebco_variables.dia_croco_strand - # allowing for scaling of rebco_variables.dia_croco_strand - rebco_variables.dia_croco_strand = ( + + superconducting_tf_coil_variables.dia_tf_turn_croco_cable = ( tfcoil_variables.t_conductor / 3.0e0 - tfcoil_variables.dx_tf_turn_steel * (2.0e0 / 3.0e0) ) # Area of the full cable circle in the turn tfcoil_variables.a_tf_turn_cable_space_no_void = ( - 9.0e0 / 4.0e0 * np.pi * rebco_variables.dia_croco_strand**2 + 9.0e0 + / 4.0e0 + * np.pi + * superconducting_tf_coil_variables.dia_tf_turn_croco_cable**2 ) # Area of the full cable spac circle minus the central copper strand superconducting_tf_coil_variables.a_tf_turn_cable_space_effective = ( tfcoil_variables.a_tf_turn_cable_space_no_void - - 0.25e0 * np.pi * rebco_variables.dia_croco_strand**2 + - 0.25e0 + * np.pi + * superconducting_tf_coil_variables.dia_tf_turn_croco_cable**2 ) superconducting_tf_coil_variables.conductor_area = ( @@ -3645,7 +3648,7 @@ def supercon_croco( ) = superconductors.croco( j_crit_sc, superconducting_tf_coil_variables.conductor_area, - rebco_variables.dia_croco_strand, + superconducting_tf_coil_variables.dia_tf_turn_croco_cable, rebco_variables.dx_croco_strand_copper, ) @@ -3849,8 +3852,8 @@ def output_croco_info(self): po.ovarre( self.outfile, "Diameter of a CroCo strand (m) ", - "(dia_croco_strand)", - rebco_variables.dia_croco_strand, + "(dia_tf_turn_croco_cable)", + superconducting_tf_coil_variables.dia_tf_turn_croco_cable, "OP ", ) po.ovarre( From f10195cc6170669feace15426865a4f4b5d6f0a8 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Fri, 17 Apr 2026 18:54:53 +0100 Subject: [PATCH 12/37] Enhance CroCo cable geometry calculations by adding tape stack height parameter and adjusting plot parameters --- process/core/io/plot/summary.py | 5 ++++- process/data_structure/rebco_variables.py | 5 +---- process/models/superconductors.py | 4 ++++ 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/process/core/io/plot/summary.py b/process/core/io/plot/summary.py index f2f8bc088..532968398 100644 --- a/process/core/io/plot/summary.py +++ b/process/core/io/plot/summary.py @@ -7609,6 +7609,9 @@ def plot_tf_croco_turn(axis: plt.Axes, fig, mfile: MFile, scan: int): ), show_legend=False, ) + print(mfile.get("dr_hts_tape", scan=scan)) + print(mfile.get("dx_croco_strand_tape_stack", scan=scan)) + print(mfile.get("n_croco_strand_hts_tapes", scan=scan)) # Cable strand packing parameters strand_diameter = mfile.get("dia_tf_turn_superconducting_cable", scan=scan) @@ -12482,7 +12485,7 @@ def plot_corc_cable_geometry( height=(dx_croco_strand_tape_stack / n_croco_strand_hts_tapes), edgecolor="black", facecolor="blue", - linewidth=1, + linewidth=1e-3, ) axis.add_patch(rect) diff --git a/process/data_structure/rebco_variables.py b/process/data_structure/rebco_variables.py index b5c1e2b2e..fcfd7f029 100644 --- a/process/data_structure/rebco_variables.py +++ b/process/data_structure/rebco_variables.py @@ -13,8 +13,6 @@ dx_hts_tape_total: float = None """thickness of tape, inc. all layers (hts, copper, substrate, etc.) (m)""" -dia_croco_strand: float = None -"""Outer diameter of CroCo strand (m)""" dia_croco_strand_tape_region: float = None """Inner diameter of CroCo strand tape region (m)""" @@ -66,7 +64,6 @@ def init_rebco_variables(): dx_hts_tape_copper, \ dx_hts_tape_hastelloy, \ dr_hts_tape, \ - dia_croco_strand, \ dia_croco_strand_tape_region, \ dx_croco_strand_copper, \ copper_rrr, \ @@ -87,7 +84,7 @@ def init_rebco_variables(): dx_hts_tape_copper = 100.0e-6 dx_hts_tape_hastelloy = 50.0e-6 dr_hts_tape = 4.0e-3 - dia_croco_strand = 0.0 + dia_croco_strand_tape_region = 0.0 dx_croco_strand_copper = 2.5e-3 copper_rrr = 100.0 diff --git a/process/models/superconductors.py b/process/models/superconductors.py index 4f3079cc1..afa4eada3 100644 --- a/process/models/superconductors.py +++ b/process/models/superconductors.py @@ -1041,6 +1041,7 @@ def calculate_croco_cable_geometry( float, # a_croco_strand_rebco float, # a_croco_strand float, # dr_hts_tape + float, # dx_croco_strand_tape_stack ]: """Calculate geometry and areas for a CroCo cable strand. @@ -1069,6 +1070,7 @@ def calculate_croco_cable_geometry( - a_croco_strand_rebco: Total REBCO area in CroCo strand (m²) - a_croco_strand: Total area of CroCo strand (m²) - dr_hts_tape: Width of the tape (m) + - dx_croco_strand_tape_stack: Height of the tape stack in the CroCo strand (m) """ # Calculate the inner diameter of the CroCo strand tape region dia_croco_strand_tape_region = dia_croco_strand - 2.0 * dx_croco_strand_copper @@ -1118,6 +1120,7 @@ def calculate_croco_cable_geometry( a_croco_strand_rebco, a_croco_strand, dr_hts_tape, + dx_croco_strand_tape_stack, ) @@ -1146,6 +1149,7 @@ def croco(j_crit_sc, conductor_area, dia_croco_strand, dx_croco_strand_copper): a_croco_strand_rebco, a_croco_strand, rebco_variables.dr_hts_tape, + rebco_variables.dx_croco_strand_tape_stack, ) = calculate_croco_cable_geometry( dia_croco_strand, dx_croco_strand_copper, From fc164ffd882420a2a8e4d4932eefc46053d975cb Mon Sep 17 00:00:00 2001 From: mn3981 Date: Mon, 20 Apr 2026 13:58:28 +0100 Subject: [PATCH 13/37] Add CroCo cable geometry data class and summary box for plotting --- process/core/io/plot/summary.py | 37 +++++++++++++++++++++++- process/models/superconductors.py | 14 +++++++++ process/models/tfcoil/superconducting.py | 7 +++++ 3 files changed, 57 insertions(+), 1 deletion(-) diff --git a/process/core/io/plot/summary.py b/process/core/io/plot/summary.py index 532968398..5c148ce4d 100644 --- a/process/core/io/plot/summary.py +++ b/process/core/io/plot/summary.py @@ -7584,7 +7584,7 @@ def plot_tf_croco_turn(axis: plt.Axes, fig, mfile: MFile, scan: int): [(turn_width / 2), (turn_width / 2)], dia_tf_turn_croco_cable / 2, facecolor="#B87333", - edgecolor="#B87333", + edgecolor="black", linewidth=1.2, ), ) @@ -12501,6 +12501,40 @@ def plot_corc_cable_geometry( axis.legend(loc="upper right") +def plot_tf_corc_cable_summary_box(axis, fig, mfile: MFile, scan: int): + + textstr_cable = ( + f"$\\mathbf{{CroCo \\ Cable:}}$\n \n" + f"Cable diameter: {mfile.get('dia_tf_turn_croco_cable', scan=scan) * 1e3:,.4f} mm\n" + f"Copper width: {mfile.get('dx_croco_strand_copper', scan=scan) * 1e3:,.4f} mm\n" + f"Diameter of solder tape region: {mfile.get('dia_croco_strand_tape_region', scan=scan) * 1e3:,.4f} mm\n" + f"Height of tape stack: {mfile.get('dx_croco_strand_tape_stack', scan=scan) * 1e3:,.4f} mm\n" + f"Width of HTS tape / tape stack: {mfile.get('dr_hts_tape', scan=scan) * 1e3:,.4f} mm\n" + f"Number of HTS tape layers: {int(mfile.get('n_croco_strand_hts_tapes', scan=scan))}\n \n" + f"Total copper area: {mfile.get('a_croco_strand_copper_total', scan=scan) * 1e6:,.4f} mm²\n" + f"Total hastelloy area: {mfile.get('a_croco_strand_hastelloy', scan=scan) * 1e6:,.4f} mm²\n" + f"Total solder area: {mfile.get('a_croco_strand_solder', scan=scan) * 1e6:,.4f} mm²\n" + f"Total superconductor area: {mfile.get('a_croco_strand_rebco', scan=scan) * 1e6:,.4f} mm²\n" + f"Total strand area: {mfile.get('a_croco_strand', scan=scan) * 1e6:,.4f} mm²\n" + ) + + axis.text( + 0.4, + 0.4, + textstr_cable, + fontsize=9, + verticalalignment="top", + horizontalalignment="left", + transform=fig.transFigure, + bbox={ + "boxstyle": "round", + "facecolor": "#cccccc", # grayish color + "alpha": 1.0, + "linewidth": 2, + }, + ) + + def reaction_plot_grid( rminor, rmajor, @@ -14769,6 +14803,7 @@ def main_plot( "n_croco_strand_hts_tapes", scan=scan ), ) + plot_tf_corc_cable_summary_box(plot_205, figs[25], m_file, scan) elif ( m_file.get("i_tf_turn_type", scan=scan) == SuperconductingTFTurnType.CABLE_IN_CONDUIT diff --git a/process/models/superconductors.py b/process/models/superconductors.py index afa4eada3..db8e93999 100644 --- a/process/models/superconductors.py +++ b/process/models/superconductors.py @@ -1,6 +1,7 @@ """Module for superconductor types, materials, and models.""" import logging +from dataclasses import dataclass from enum import IntEnum from types import DynamicClassAttribute @@ -1026,6 +1027,19 @@ def bottura_scaling( return j_scaling, b_critical, temp_critical +@dataclass +class CroCoCableGeometry: + dia_croco_strand_tape_region: float + n_croco_strand_hts_tapes: float + a_croco_strand_copper_total: float + a_croco_strand_hastelloy: float + a_croco_strand_solder: float + a_croco_strand_rebco: float + a_croco_strand: float + dr_hts_tape: float + dx_croco_strand_tape_stack: float + + def calculate_croco_cable_geometry( dia_croco_strand: float, dx_croco_strand_copper: float, diff --git a/process/models/tfcoil/superconducting.py b/process/models/tfcoil/superconducting.py index 696359d99..56d2958c6 100644 --- a/process/models/tfcoil/superconducting.py +++ b/process/models/tfcoil/superconducting.py @@ -3892,6 +3892,13 @@ def output_croco_info(self): "OP ", ) po.oblnkl(self.outfile) + po.ovarre( + self.outfile, + "Area of total CroCo strand (m2)", + "(a_croco_strand)", + rebco_variables.a_croco_strand, + "OP ", + ) po.ovarre( self.outfile, "Area of REBCO in strand (m2)", From 1c1ae7694428d9dd8ea15392bb93f7f76cbf6bea Mon Sep 17 00:00:00 2001 From: mn3981 Date: Mon, 20 Apr 2026 15:02:38 +0100 Subject: [PATCH 14/37] Add HTS tape geometry plotting function and update CroCo cable plot parameters --- process/core/io/plot/summary.py | 139 ++++++++++++++++++++++++++++---- 1 file changed, 125 insertions(+), 14 deletions(-) diff --git a/process/core/io/plot/summary.py b/process/core/io/plot/summary.py index 5c148ce4d..e438b69ff 100644 --- a/process/core/io/plot/summary.py +++ b/process/core/io/plot/summary.py @@ -7607,11 +7607,11 @@ def plot_tf_croco_turn(axis: plt.Axes, fig, mfile: MFile, scan: int): n_croco_strand_hts_tapes=mfile.get( "n_croco_strand_hts_tapes", scan=scan ), + dx_hts_tape_rebco=mfile.get("dx_hts_tape_rebco", scan=scan), + dx_hts_tape_copper=mfile.get("dx_hts_tape_copper", scan=scan), + dx_hts_tape_hastelloy=mfile.get("dx_hts_tape_hastelloy", scan=scan), show_legend=False, ) - print(mfile.get("dr_hts_tape", scan=scan)) - print(mfile.get("dx_croco_strand_tape_stack", scan=scan)) - print(mfile.get("n_croco_strand_hts_tapes", scan=scan)) # Cable strand packing parameters strand_diameter = mfile.get("dia_tf_turn_superconducting_cable", scan=scan) @@ -12413,6 +12413,9 @@ def plot_corc_cable_geometry( dr_hts_tape: float, dx_croco_strand_tape_stack: float, n_croco_strand_hts_tapes: int, + dx_hts_tape_rebco: float, + dx_hts_tape_copper: float, + dx_hts_tape_hastelloy: float, show_legend: bool = True, ): """Plot the geometry of a CroCo strand cable. @@ -12465,9 +12468,11 @@ def plot_corc_cable_geometry( (r_centre - dr_hts_tape / 2, z_centre - dx_croco_strand_tape_stack / 2), width=dr_hts_tape, height=dx_croco_strand_tape_stack, - edgecolor="blue", - facecolor="blue", - linewidth=2, + edgecolor="black", + facecolor=None, + linewidth=0.1, + alpha=0.5, + linestyle="--", label="HTS Tape Stack" if show_legend else legend_label, ) axis.add_patch(rect) @@ -12479,15 +12484,16 @@ def plot_corc_cable_geometry( - (dx_croco_strand_tape_stack / 2) + i * (dx_croco_strand_tape_stack / n_croco_strand_hts_tapes) ) - rect = Rectangle( - (r_centre - dr_hts_tape / 2, y_start), - width=dr_hts_tape, - height=(dx_croco_strand_tape_stack / n_croco_strand_hts_tapes), - edgecolor="black", - facecolor="blue", - linewidth=1e-3, + plot_hts_tape_geometry( + axis=axis, + r_left=r_centre - (dr_hts_tape / 2), + z_bottom=y_start, + dr_hts_tape=dr_hts_tape, + dx_hts_tape_rebco=dx_hts_tape_rebco, + dx_hts_tape_copper=dx_hts_tape_copper, + dx_hts_tape_hastelloy=dx_hts_tape_hastelloy, + show_legend=False, ) - axis.add_patch(rect) axis.set_xlim(-dia_croco_strand * 0.75, dia_croco_strand * 0.75) axis.set_ylim(-dia_croco_strand * 0.75, dia_croco_strand * 0.75) @@ -12501,6 +12507,97 @@ def plot_corc_cable_geometry( axis.legend(loc="upper right") +def plot_hts_tape_geometry( + axis, + r_left: float, + z_bottom: float, + dr_hts_tape: float, + dx_hts_tape_rebco: float, + dx_hts_tape_copper: float, + dx_hts_tape_hastelloy: float, + show_legend: bool = True, +): + + legend_label = None if show_legend else "_nolegend_" + # Plot a rectangular tape stack in the middle + rect = Rectangle( + (r_left, z_bottom), + width=dr_hts_tape, + height=dx_hts_tape_copper / 2, + edgecolor=None, + facecolor="#B87333", + linewidth=2, + label="Copper" if show_legend else legend_label, + ) + axis.add_patch(rect) + rect = Rectangle( + (r_left, z_bottom + dx_hts_tape_copper / 2), + width=dr_hts_tape, + height=dx_hts_tape_hastelloy / 2, + edgecolor=None, + facecolor="grey", + linewidth=2, + label="Hastelloy" if show_legend else legend_label, + ) + axis.add_patch(rect) + rect = Rectangle( + (r_left, z_bottom + dx_hts_tape_copper / 2 + dx_hts_tape_hastelloy / 2), + width=dr_hts_tape, + height=dx_hts_tape_rebco, + edgecolor=None, + facecolor="blue", + linewidth=2, + label="REBCO" if show_legend else legend_label, + ) + axis.add_patch(rect) + rect = Rectangle( + ( + r_left, + z_bottom + + dx_hts_tape_copper / 2 + + dx_hts_tape_hastelloy / 2 + + dx_hts_tape_rebco, + ), + width=dr_hts_tape, + height=dx_hts_tape_hastelloy / 2, + edgecolor=None, + facecolor="grey", + linewidth=2, + label="Hastelloy" if show_legend else legend_label, + ) + axis.add_patch(rect) + rect = Rectangle( + ( + r_left, + z_bottom + + dx_hts_tape_copper / 2 + + dx_hts_tape_hastelloy / 2 + + dx_hts_tape_rebco + + dx_hts_tape_hastelloy / 2, + ), + width=dr_hts_tape, + height=dx_hts_tape_copper / 2, + edgecolor=None, + facecolor="#B87333", + linewidth=2, + label="Copper" if show_legend else legend_label, + ) + axis.add_patch(rect) + + axis.set_title("HTS Tape Geometry") + axis.grid(True) + axis.set_xlabel("X-axis (m)") + axis.set_ylabel("Y-axis (m)") + axis.set_xlim(r_left * 0.9, dr_hts_tape * 1.1) + axis.set_ylim( + z_bottom * 0.9, + (dx_hts_tape_copper + dx_hts_tape_hastelloy + dx_hts_tape_rebco) * 1.1, + ) + axis.minorticks_on() + if show_legend: + axis.legend(loc="upper right") + + def plot_tf_corc_cable_summary_box(axis, fig, mfile: MFile, scan: int): textstr_cable = ( @@ -14802,8 +14899,22 @@ def main_plot( n_croco_strand_hts_tapes=m_file.get( "n_croco_strand_hts_tapes", scan=scan ), + dx_hts_tape_rebco=m_file.get("dx_hts_tape_rebco", scan=scan), + dx_hts_tape_copper=m_file.get("dx_hts_tape_copper", scan=scan), + dx_hts_tape_hastelloy=m_file.get("dx_hts_tape_hastelloy", scan=scan), + show_legend=True, ) plot_tf_corc_cable_summary_box(plot_205, figs[25], m_file, scan) + plot_hts_tape_geometry( + axis=figs[25].add_subplot(339), + r_left=0.0, + z_bottom=0.0, + dr_hts_tape=m_file.get("dr_hts_tape", scan=scan), + dx_hts_tape_rebco=m_file.get("dx_hts_tape_rebco", scan=scan), + dx_hts_tape_copper=m_file.get("dx_hts_tape_copper", scan=scan), + dx_hts_tape_hastelloy=m_file.get("dx_hts_tape_hastelloy", scan=scan), + show_legend=True, + ) elif ( m_file.get("i_tf_turn_type", scan=scan) == SuperconductingTFTurnType.CABLE_IN_CONDUIT From d4922dcd10e3373ec0b634aec21c5c0358862df1 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Wed, 13 May 2026 09:42:40 +0100 Subject: [PATCH 15/37] Refactor CroCo strand calculations to use N_CROCO_STRANDS_TURN constant for improved maintainability --- process/core/io/plot/summary.py | 3 --- process/models/superconductors.py | 14 +++++++++----- process/models/tfcoil/superconducting.py | 11 +++++++---- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/process/core/io/plot/summary.py b/process/core/io/plot/summary.py index e438b69ff..50d0035c9 100644 --- a/process/core/io/plot/summary.py +++ b/process/core/io/plot/summary.py @@ -7625,9 +7625,6 @@ def plot_tf_croco_turn(axis: plt.Axes, fig, mfile: MFile, scan: int): turn_width - 2 * (insulation_thickness + steel_thickness), ] - axis.set_xlim(-turn_width * 0.05, turn_width * 1.05) - axis.set_ylim(-turn_width * 0.05, turn_width * 1.05) - axis.minorticks_on() axis.set_title("WP Turn Structure") axis.set_xlabel("r [m]") diff --git a/process/models/superconductors.py b/process/models/superconductors.py index db8e93999..490b69b52 100644 --- a/process/models/superconductors.py +++ b/process/models/superconductors.py @@ -13,6 +13,8 @@ logger = logging.getLogger(__name__) +N_CROCO_STRANDS_TURN = 6 + class SuperconductorType(IntEnum): """Enumeration of superconductor types.""" @@ -1183,10 +1185,12 @@ def croco(j_crit_sc, conductor_area, dia_croco_strand, dx_croco_strand_copper): # Conductor properties # conductor%number_croco = conductor%acs*(1.0-cable_helium_fraction-copper_bar) # /a_croco_strand - conductor_critical_current = croco_strand_critical_current * 6.0 + conductor_critical_current = croco_strand_critical_current * N_CROCO_STRANDS_TURN # Area of core = area of strand conductor_copper_bar_area = a_croco_strand - conductor_copper_area = a_croco_strand_copper_total * 6.0 + conductor_copper_bar_area + conductor_copper_area = ( + a_croco_strand_copper_total * N_CROCO_STRANDS_TURN + conductor_copper_bar_area + ) conductor_copper_fraction = conductor_copper_area / conductor_area # Helium area is set by the user. @@ -1194,13 +1198,13 @@ def croco(j_crit_sc, conductor_area, dia_croco_strand, dx_croco_strand_copper): conductor_helium_area = np.pi / 2.0 * dia_croco_strand**2 conductor_helium_fraction = conductor_helium_area / conductor_area - conductor_hastelloy_area = a_croco_strand_hastelloy * 6.0 + conductor_hastelloy_area = a_croco_strand_hastelloy * N_CROCO_STRANDS_TURN conductor_hastelloy_fraction = conductor_hastelloy_area / conductor_area - conductor_solder_area = a_croco_strand_solder * 6.0 + conductor_solder_area = a_croco_strand_solder * N_CROCO_STRANDS_TURN conductor_solder_fraction = conductor_solder_area / conductor_area - conductor_rebco_area = a_croco_strand_rebco * 6.0 + conductor_rebco_area = a_croco_strand_rebco * N_CROCO_STRANDS_TURN conductor_rebco_fraction = conductor_rebco_area / conductor_area return ( diff --git a/process/models/tfcoil/superconducting.py b/process/models/tfcoil/superconducting.py index 56d2958c6..959e25f7e 100644 --- a/process/models/tfcoil/superconducting.py +++ b/process/models/tfcoil/superconducting.py @@ -22,7 +22,11 @@ tfcoil_variables, ) from process.models import superconductors -from process.models.superconductors import SuperconductorMaterial, SuperconductorModel +from process.models.superconductors import ( + N_CROCO_STRANDS_TURN, + SuperconductorMaterial, + SuperconductorModel, +) from process.models.tfcoil import quench from process.models.tfcoil.base import TFCoil, TFPlasmaCaseType @@ -3019,9 +3023,8 @@ def run(self, output: bool = False): # Setting the WP turn geometry / areas if tfcoil_variables.i_tf_turns_integer == 0: # Non-ingeger number of turns - avg_turn_geometry = CROCOAveragedTurnGeometry - avg_turn_geometry = self.tf_croco_averaged_turn_geometry( + avg_turn_geometry: CROCOAveragedTurnGeometry = self.tf_croco_averaged_turn_geometry( j_tf_wp=tfcoil_variables.j_tf_wp, dx_tf_turn_steel=tfcoil_variables.dx_tf_turn_steel, dx_tf_turn_insulation=tfcoil_variables.dx_tf_turn_insulation, @@ -3955,7 +3958,7 @@ def output_croco_info(self): self.outfile, "Number of CroCo strands in the cable (fixed) ", "", - 6, + N_CROCO_STRANDS_TURN, "OP ", ) po.ovarre( From 9c2673af57a0cc2fd4da707bc36d38efe5d8019b Mon Sep 17 00:00:00 2001 From: mn3981 Date: Wed, 13 May 2026 10:15:10 +0100 Subject: [PATCH 16/37] Refactor CroCo cable geometry calculations to return CroCoCableGeometry object and update related variables in CROCOSuperconductingTFCoil --- process/core/io/plot/summary.py | 3 + process/models/superconductors.py | 91 +++++++++++------------ process/models/tfcoil/superconducting.py | 93 ++++++++++-------------- 3 files changed, 83 insertions(+), 104 deletions(-) diff --git a/process/core/io/plot/summary.py b/process/core/io/plot/summary.py index 50d0035c9..2862f57b3 100644 --- a/process/core/io/plot/summary.py +++ b/process/core/io/plot/summary.py @@ -7627,6 +7627,9 @@ def plot_tf_croco_turn(axis: plt.Axes, fig, mfile: MFile, scan: int): axis.minorticks_on() axis.set_title("WP Turn Structure") + axis.set_xlim(-turn_width * 0.025, turn_width * 1.025) + axis.set_ylim(-turn_width * 0.025, turn_width * 1.025) + axis.set_aspect("equal", adjustable="box") axis.set_xlabel("r [m]") axis.set_ylabel("x [m]") diff --git a/process/models/superconductors.py b/process/models/superconductors.py index 490b69b52..a5da57821 100644 --- a/process/models/superconductors.py +++ b/process/models/superconductors.py @@ -1048,17 +1048,7 @@ def calculate_croco_cable_geometry( dx_hts_tape_rebco: float, dx_hts_tape_copper: float, dx_hts_tape_hastelloy: float, -) -> tuple[ - float, # dia_croco_strand_tape_region - float, # n_croco_strand_hts_tapes - float, # a_croco_strand_copper_total - float, # a_croco_strand_hastelloy - float, # a_croco_strand_solder - float, # a_croco_strand_rebco - float, # a_croco_strand - float, # dr_hts_tape - float, # dx_croco_strand_tape_stack -]: +) -> CroCoCableGeometry: """Calculate geometry and areas for a CroCo cable strand. Parameters @@ -1076,17 +1066,16 @@ def calculate_croco_cable_geometry( Returns ------- - tuple[float, float, float, float, float, float, float, float] - Tuple containing: - - dia_croco_strand_tape_region: Inner diameter of CroCo strand tape region (m) - - n_croco_strand_hts_tapes: Number of HTS tapes in CroCo strand - - a_croco_strand_copper_total: Total copper area in CroCo strand (m²) - - a_croco_strand_hastelloy: Total Hastelloy area in CroCo strand (m²) - - a_croco_strand_solder: Total solder area in CroCo strand (m²) - - a_croco_strand_rebco: Total REBCO area in CroCo strand (m²) - - a_croco_strand: Total area of CroCo strand (m²) - - dr_hts_tape: Width of the tape (m) - - dx_croco_strand_tape_stack: Height of the tape stack in the CroCo strand (m) + CroCoCableGeometry + - dia_croco_strand_tape_region: Inner diameter of CroCo strand tape region (m) + - n_croco_strand_hts_tapes: Number of HTS tapes in CroCo strand + - a_croco_strand_copper_total: Total copper area in CroCo strand (m²) + - a_croco_strand_hastelloy: Total Hastelloy area in CroCo strand (m²) + - a_croco_strand_solder: Total solder area in CroCo strand (m²) + - a_croco_strand_rebco: Total REBCO area in CroCo strand (m²) + - a_croco_strand: Total area of CroCo strand (m²) + - dr_hts_tape: Width of the tape (m) + - dx_croco_strand_tape_stack: Height of the tape stack in the CroCo strand (m) """ # Calculate the inner diameter of the CroCo strand tape region dia_croco_strand_tape_region = dia_croco_strand - 2.0 * dx_croco_strand_copper @@ -1127,16 +1116,16 @@ def calculate_croco_cable_geometry( # Total area of the CroCo strand a_croco_strand = np.pi / 4.0 * dia_croco_strand**2 - return ( - dia_croco_strand_tape_region, - n_croco_strand_hts_tapes, - a_croco_strand_copper_total, - a_croco_strand_hastelloy, - a_croco_strand_solder, - a_croco_strand_rebco, - a_croco_strand, - dr_hts_tape, - dx_croco_strand_tape_stack, + return CroCoCableGeometry( + dia_croco_strand_tape_region=dia_croco_strand_tape_region, + n_croco_strand_hts_tapes=n_croco_strand_hts_tapes, + a_croco_strand_copper_total=a_croco_strand_copper_total, + a_croco_strand_hastelloy=a_croco_strand_hastelloy, + a_croco_strand_solder=a_croco_strand_solder, + a_croco_strand_rebco=a_croco_strand_rebco, + a_croco_strand=a_croco_strand, + dr_hts_tape=dr_hts_tape, + dx_croco_strand_tape_stack=dx_croco_strand_tape_stack, ) @@ -1156,22 +1145,28 @@ def croco(j_crit_sc, conductor_area, dia_croco_strand, dx_croco_strand_copper): dx_croco_strand_copper : """ - ( - rebco_variables.dia_croco_strand_tape_region, - rebco_variables.n_croco_strand_hts_tapes, - a_croco_strand_copper_total, - a_croco_strand_hastelloy, - a_croco_strand_solder, - a_croco_strand_rebco, - a_croco_strand, - rebco_variables.dr_hts_tape, - rebco_variables.dx_croco_strand_tape_stack, - ) = calculate_croco_cable_geometry( - dia_croco_strand, - dx_croco_strand_copper, - rebco_variables.dx_hts_tape_rebco, - rebco_variables.dx_hts_tape_copper, - rebco_variables.dx_hts_tape_hastelloy, + croco_cable_geometry: CroCoCableGeometry = calculate_croco_cable_geometry( + dia_croco_strand=dia_croco_strand, + dx_croco_strand_copper=dx_croco_strand_copper, + dx_hts_tape_rebco=rebco_variables.dx_hts_tape_rebco, + dx_hts_tape_copper=rebco_variables.dx_hts_tape_copper, + dx_hts_tape_hastelloy=rebco_variables.dx_hts_tape_hastelloy, + ) + + rebco_variables.dia_croco_strand_tape_region = ( + croco_cable_geometry.dia_croco_strand_tape_region + ) + rebco_variables.n_croco_strand_hts_tapes = ( + croco_cable_geometry.n_croco_strand_hts_tapes + ) + a_croco_strand_copper_total = croco_cable_geometry.a_croco_strand_copper_total + a_croco_strand_hastelloy = croco_cable_geometry.a_croco_strand_hastelloy + a_croco_strand_solder = croco_cable_geometry.a_croco_strand_solder + a_croco_strand_rebco = croco_cable_geometry.a_croco_strand_rebco + a_croco_strand = croco_cable_geometry.a_croco_strand + rebco_variables.dr_hts_tape = croco_cable_geometry.dr_hts_tape + rebco_variables.dx_croco_strand_tape_stack = ( + croco_cable_geometry.dx_croco_strand_tape_stack ) rebco_variables.a_croco_strand_copper_total = a_croco_strand_copper_total diff --git a/process/models/tfcoil/superconducting.py b/process/models/tfcoil/superconducting.py index 959e25f7e..ef16b52bd 100644 --- a/process/models/tfcoil/superconducting.py +++ b/process/models/tfcoil/superconducting.py @@ -3060,27 +3060,6 @@ def run(self, output: bool = False): "Integer turn geometry not implemented for CroCo conductor." ) - # Calculate number of cables in turn if CICC conductor - # --------------------------------------------------- - if ( - SuperconductorModel(tfcoil_variables.i_tf_sc_mat) - != SuperconductorModel.CROCO_REBCO - ): - superconducting_tf_coil_variables.n_tf_turn_superconducting_cables = self.calculate_cable_in_conduit_strand_count( - a_cable_space=superconducting_tf_coil_variables.a_tf_turn_cable_space_effective, - dia_superconductor_strand=superconducting_tf_coil_variables.dia_tf_turn_superconducting_cable, - ) - - ( - superconducting_tf_coil_variables.len_tf_coil_superconductor, - superconducting_tf_coil_variables.len_tf_superconductor_total, - ) = self.calculate_cable_in_conduit_superconductor_length( - n_tf_coils=tfcoil_variables.n_tf_coils, - n_tf_coil_turns=tfcoil_variables.n_tf_coil_turns, - len_tf_coil=tfcoil_variables.len_tf_coil, - n_tf_turn_superconducting_cables=superconducting_tf_coil_variables.n_tf_turn_superconducting_cables, - ) - # Areas and fractions # ------------------- # Central helium channel down the conductor core [m2] @@ -3142,6 +3121,43 @@ def run(self, output: bool = False): / tfcoil_variables.a_tf_inboard_total ) + superconducting_tf_coil_variables.dia_tf_turn_croco_cable = ( + tfcoil_variables.t_conductor / 3.0e0 + - tfcoil_variables.dx_tf_turn_steel * (2.0e0 / 3.0e0) + ) + + # Area of the full cable circle in the turn + tfcoil_variables.a_tf_turn_cable_space_no_void = ( + 9.0e0 + / 4.0e0 + * np.pi + * superconducting_tf_coil_variables.dia_tf_turn_croco_cable**2 + ) + # Area of the full cable spac circle minus the central copper strand + superconducting_tf_coil_variables.a_tf_turn_cable_space_effective = ( + tfcoil_variables.a_tf_turn_cable_space_no_void + - 0.25e0 + * np.pi + * superconducting_tf_coil_variables.dia_tf_turn_croco_cable**2 + ) + + superconducting_tf_coil_variables.conductor_area = ( + tfcoil_variables.t_conductor**2 + ) # does this not assume it's a sqaure??? + + superconducting_tf_coil_variables.conductor_jacket_area = ( + superconducting_tf_coil_variables.conductor_area + - tfcoil_variables.a_tf_turn_cable_space_no_void + ) + tfcoil_variables.a_tf_turn_steel = ( + superconducting_tf_coil_variables.conductor_jacket_area + ) + + superconducting_tf_coil_variables.conductor_jacket_fraction = ( + superconducting_tf_coil_variables.conductor_jacket_area + / superconducting_tf_coil_variables.conductor_area + ) + # Negative areas or fractions error reporting if ( tfcoil_variables.a_tf_wp_conductor <= 0.0e0 @@ -3598,41 +3614,6 @@ def supercon_croco( # Find critical current density in superconducting cable, j_crit_cable j_crit_sc, _ = superconductors.jcrit_rebco(thelium, b_tf_inboard_peak_symmetric) - superconducting_tf_coil_variables.dia_tf_turn_croco_cable = ( - tfcoil_variables.t_conductor / 3.0e0 - - tfcoil_variables.dx_tf_turn_steel * (2.0e0 / 3.0e0) - ) - # Area of the full cable circle in the turn - tfcoil_variables.a_tf_turn_cable_space_no_void = ( - 9.0e0 - / 4.0e0 - * np.pi - * superconducting_tf_coil_variables.dia_tf_turn_croco_cable**2 - ) - # Area of the full cable spac circle minus the central copper strand - superconducting_tf_coil_variables.a_tf_turn_cable_space_effective = ( - tfcoil_variables.a_tf_turn_cable_space_no_void - - 0.25e0 - * np.pi - * superconducting_tf_coil_variables.dia_tf_turn_croco_cable**2 - ) - - superconducting_tf_coil_variables.conductor_area = ( - tfcoil_variables.t_conductor**2 - ) # does this not assume it's a sqaure??? - - superconducting_tf_coil_variables.conductor_jacket_area = ( - superconducting_tf_coil_variables.conductor_area - - tfcoil_variables.a_tf_turn_cable_space_no_void - ) - tfcoil_variables.a_tf_turn_steel = ( - superconducting_tf_coil_variables.conductor_jacket_area - ) - - superconducting_tf_coil_variables.conductor_jacket_fraction = ( - superconducting_tf_coil_variables.conductor_jacket_area - / superconducting_tf_coil_variables.conductor_area - ) ( superconducting_tf_coil_variables.croco_strand_area, superconducting_tf_coil_variables.croco_strand_critical_current, From fa34f2e895a762f667f503d12518a6ef354ef33f Mon Sep 17 00:00:00 2001 From: mn3981 Date: Wed, 13 May 2026 10:23:01 +0100 Subject: [PATCH 17/37] Refactor CROCOSuperconductingTFCoil to utilize calculate_croco_cable_geometry for improved cable geometry calculations --- process/models/tfcoil/superconducting.py | 32 ++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/process/models/tfcoil/superconducting.py b/process/models/tfcoil/superconducting.py index ef16b52bd..aabb68986 100644 --- a/process/models/tfcoil/superconducting.py +++ b/process/models/tfcoil/superconducting.py @@ -24,8 +24,10 @@ from process.models import superconductors from process.models.superconductors import ( N_CROCO_STRANDS_TURN, + CroCoCableGeometry, SuperconductorMaterial, SuperconductorModel, + calculate_croco_cable_geometry, ) from process.models.tfcoil import quench from process.models.tfcoil.base import TFCoil, TFPlasmaCaseType @@ -3158,6 +3160,36 @@ def run(self, output: bool = False): / superconducting_tf_coil_variables.conductor_area ) + croco_cable_geometry: CroCoCableGeometry = calculate_croco_cable_geometry( + dia_croco_strand=superconducting_tf_coil_variables.dia_tf_turn_croco_cable, + dx_croco_strand_copper=rebco_variables.dx_croco_strand_copper, + dx_hts_tape_rebco=rebco_variables.dx_hts_tape_rebco, + dx_hts_tape_copper=rebco_variables.dx_hts_tape_copper, + dx_hts_tape_hastelloy=rebco_variables.dx_hts_tape_hastelloy, + ) + + rebco_variables.dia_croco_strand_tape_region = ( + croco_cable_geometry.dia_croco_strand_tape_region + ) + rebco_variables.n_croco_strand_hts_tapes = ( + croco_cable_geometry.n_croco_strand_hts_tapes + ) + a_croco_strand_copper_total = croco_cable_geometry.a_croco_strand_copper_total + a_croco_strand_hastelloy = croco_cable_geometry.a_croco_strand_hastelloy + a_croco_strand_solder = croco_cable_geometry.a_croco_strand_solder + a_croco_strand_rebco = croco_cable_geometry.a_croco_strand_rebco + a_croco_strand = croco_cable_geometry.a_croco_strand + rebco_variables.dr_hts_tape = croco_cable_geometry.dr_hts_tape + rebco_variables.dx_croco_strand_tape_stack = ( + croco_cable_geometry.dx_croco_strand_tape_stack + ) + + rebco_variables.a_croco_strand_copper_total = a_croco_strand_copper_total + rebco_variables.a_croco_strand_hastelloy = a_croco_strand_hastelloy + rebco_variables.a_croco_strand_solder = a_croco_strand_solder + rebco_variables.a_croco_strand_rebco = a_croco_strand_rebco + rebco_variables.a_croco_strand = a_croco_strand + # Negative areas or fractions error reporting if ( tfcoil_variables.a_tf_wp_conductor <= 0.0e0 From 678c1b408635f1726c3817b059f02752e4cda0bd Mon Sep 17 00:00:00 2001 From: mn3981 Date: Wed, 13 May 2026 11:21:34 +0100 Subject: [PATCH 18/37] Refactor variable names for TF coil components - Updated variable names related to HTS tape and CroCo strand in the input variables, iteration variables, and data structures to use the "tf_" prefix for clarity and consistency. - Adjusted references in the solver, models, and plotting functions to align with the new naming convention. - Ensured backward compatibility by updating obsolete variable mappings. - Modified documentation to reflect changes in variable names and their descriptions. --- process/core/input.py | 14 +- process/core/io/obsolete_vars.py | 12 +- process/core/io/plot/summary.py | 70 ++++----- process/core/solver/constraints.py | 2 +- process/core/solver/iteration_variables.py | 6 +- process/data_structure/numerics.py | 6 +- process/data_structure/rebco_variables.py | 6 +- .../superconducting_tf_coil_variables.py | 98 +++++++++++- process/models/pfcoil.py | 6 +- process/models/stellarator/coils/quench.py | 2 +- process/models/superconductors.py | 39 +++-- process/models/tfcoil/base.py | 4 +- process/models/tfcoil/superconducting.py | 140 ++++++++++-------- 13 files changed, 252 insertions(+), 153 deletions(-) diff --git a/process/core/input.py b/process/core/input.py index 8bedcfb05..8c1dea62d 100644 --- a/process/core/input.py +++ b/process/core/input.py @@ -298,7 +298,7 @@ def __post_init__(self): "copper_rrr": InputVariable( data_structure.rebco_variables, float, range=(1.0, 10000.0) ), - "dx_hts_tape_copper": InputVariable( + "dx_tf_hts_tape_copper": InputVariable( data_structure.rebco_variables, float, range=(0.0, 0.001) ), "copperaoh_m2": InputVariable( @@ -329,7 +329,7 @@ def __post_init__(self): "crane_arm_h": InputVariable("buildings", float, range=(1.0, 100.0)), "crane_clrnc_h": InputVariable("buildings", float, range=(0.0, 10.0)), "crane_clrnc_v": InputVariable("buildings", float, range=(0.0, 10.0)), - "dx_croco_strand_copper": InputVariable( + "dx_tf_croco_strand_copper": InputVariable( data_structure.rebco_variables, float, range=(0.001, 0.1) ), "cryomag_h": InputVariable("buildings", float, range=(1.0, 100.0)), @@ -623,7 +623,7 @@ def __post_init__(self): "gas_buildings_w": InputVariable("buildings", float, range=(10.0, 1000.0)), "ground_clrnc": InputVariable("buildings", float, range=(0.0, 10.0)), "n_ecrh_harmonic": InputVariable("current_drive", float, range=(1.0, 10.0)), - "dx_hts_tape_hastelloy": InputVariable( + "dx_tf_hts_tape_hastelloy": InputVariable( data_structure.rebco_variables, float, range=(1e-08, 0.001) ), "hccl": InputVariable("buildings", float, range=(0.0, 10.0)), @@ -846,7 +846,7 @@ def __post_init__(self): "reactor_hall_w": InputVariable("buildings", float, range=(10.0, 1000.0)), "reactor_roof_thk": InputVariable("buildings", float, range=(0.25, 25.0)), "reactor_wall_thk": InputVariable("buildings", float, range=(0.25, 25.0)), - "dx_hts_tape_rebco": InputVariable( + "dx_tf_hts_tape_rebco": InputVariable( data_structure.rebco_variables, float, range=(1e-08, 0.0001), @@ -981,10 +981,10 @@ def __post_init__(self): "t_turn_tf_max": InputVariable( data_structure.tfcoil_variables, float, range=(0.0, 1.0) ), - "dx_hts_tape_total": InputVariable( + "dx_tf_hts_tape_total": InputVariable( data_structure.rebco_variables, float, range=(0.0, 0.1) ), - "dr_hts_tape": InputVariable( + "dr_tf_hts_tape": InputVariable( data_structure.rebco_variables, float, range=(0.0, 0.1) ), "tauee_in": InputVariable( @@ -1213,7 +1213,7 @@ def __post_init__(self): "ccls_ma": InputVariable(data_structure.pfcoil_variables, float, array=True), "cfind": InputVariable("costs", float, array=True), "i_blkt_coolant_type": InputVariable("fwbs", int, choices=[1, 2]), - "coppera_m2_max": InputVariable( + "tf_coppera_m2_max": InputVariable( data_structure.rebco_variables, float, range=(1.0e6, 1.0e10) ), "cost_model": InputVariable("costs", int, choices=[0, 1, 2]), diff --git a/process/core/io/obsolete_vars.py b/process/core/io/obsolete_vars.py index 4d0197d86..5e46aeb56 100644 --- a/process/core/io/obsolete_vars.py +++ b/process/core/io/obsolete_vars.py @@ -420,12 +420,12 @@ "t_structural_vertical": "dz_cs_turn_conduit", "t_cable_tf": "dx_tf_turn_cable_space_general", "t_turn_tf": "dx_tf_turn_general", - "copper_thick": "dx_hts_tape_copper", - "croco_thick": "dx_croco_strand_copper", - "hastelloy_thickness": "dx_hts_tape_hastelloy", - "rebco_thickness": "dx_hts_tape_rebco", - "tape_thickness": "dx_hts_tape_total", - "tape_width": "dr_hts_tape", + "copper_thick": "dx_tf_hts_tape_copper", + "croco_thick": "dx_tf_croco_strand_copper", + "hastelloy_thickness": "dx_tf_hts_tape_hastelloy", + "rebco_thickness": "dx_tf_hts_tape_rebco", + "tape_thickness": "dx_tf_hts_tape_total", + "tape_width": "dr_tf_hts_tape", "beta": "beta_total_vol_avg", "beta_max": "beta_vol_avg_max", "beta_min": "beta_vol_avg_min", diff --git a/process/core/io/plot/summary.py b/process/core/io/plot/summary.py index 2862f57b3..3754a1f64 100644 --- a/process/core/io/plot/summary.py +++ b/process/core/io/plot/summary.py @@ -7599,32 +7599,20 @@ def plot_tf_croco_turn(axis: plt.Axes, fig, mfile: MFile, scan: int): r_centre=center_x + ring_radius * np.cos(angle), z_centre=center_y + ring_radius * np.sin(angle), dia_croco_strand=mfile.get("dia_tf_turn_croco_cable", scan=scan), - dx_croco_strand_copper=mfile.get("dx_croco_strand_copper", scan=scan), - dr_hts_tape=mfile.get("dr_hts_tape", scan=scan), + dx_croco_strand_copper=mfile.get("dx_tf_croco_strand_copper", scan=scan), + dr_hts_tape=mfile.get("dr_tf_hts_tape", scan=scan), dx_croco_strand_tape_stack=mfile.get( - "dx_croco_strand_tape_stack", scan=scan + "dx_tf_croco_strand_tape_stack", scan=scan ), n_croco_strand_hts_tapes=mfile.get( - "n_croco_strand_hts_tapes", scan=scan + "n_tf_croco_strand_hts_tapes", scan=scan ), - dx_hts_tape_rebco=mfile.get("dx_hts_tape_rebco", scan=scan), - dx_hts_tape_copper=mfile.get("dx_hts_tape_copper", scan=scan), - dx_hts_tape_hastelloy=mfile.get("dx_hts_tape_hastelloy", scan=scan), + dx_hts_tape_rebco=mfile.get("dx_tf_hts_tape_rebco", scan=scan), + dx_hts_tape_copper=mfile.get("dx_tf_hts_tape_copper", scan=scan), + dx_hts_tape_hastelloy=mfile.get("dx_tf_hts_tape_hastelloy", scan=scan), show_legend=False, ) - # Cable strand packing parameters - strand_diameter = mfile.get("dia_tf_turn_superconducting_cable", scan=scan) - void_fraction = mfile.get("f_a_tf_turn_cable_space_extra_void", scan=scan) - - # Cable space bounds - cable_bounds = [ - insulation_thickness + steel_thickness, - insulation_thickness + steel_thickness, - turn_width - 2 * (insulation_thickness + steel_thickness), - turn_width - 2 * (insulation_thickness + steel_thickness), - ] - axis.minorticks_on() axis.set_title("WP Turn Structure") axis.set_xlim(-turn_width * 0.025, turn_width * 1.025) @@ -12603,16 +12591,16 @@ def plot_tf_corc_cable_summary_box(axis, fig, mfile: MFile, scan: int): textstr_cable = ( f"$\\mathbf{{CroCo \\ Cable:}}$\n \n" f"Cable diameter: {mfile.get('dia_tf_turn_croco_cable', scan=scan) * 1e3:,.4f} mm\n" - f"Copper width: {mfile.get('dx_croco_strand_copper', scan=scan) * 1e3:,.4f} mm\n" - f"Diameter of solder tape region: {mfile.get('dia_croco_strand_tape_region', scan=scan) * 1e3:,.4f} mm\n" - f"Height of tape stack: {mfile.get('dx_croco_strand_tape_stack', scan=scan) * 1e3:,.4f} mm\n" - f"Width of HTS tape / tape stack: {mfile.get('dr_hts_tape', scan=scan) * 1e3:,.4f} mm\n" - f"Number of HTS tape layers: {int(mfile.get('n_croco_strand_hts_tapes', scan=scan))}\n \n" - f"Total copper area: {mfile.get('a_croco_strand_copper_total', scan=scan) * 1e6:,.4f} mm²\n" - f"Total hastelloy area: {mfile.get('a_croco_strand_hastelloy', scan=scan) * 1e6:,.4f} mm²\n" - f"Total solder area: {mfile.get('a_croco_strand_solder', scan=scan) * 1e6:,.4f} mm²\n" - f"Total superconductor area: {mfile.get('a_croco_strand_rebco', scan=scan) * 1e6:,.4f} mm²\n" - f"Total strand area: {mfile.get('a_croco_strand', scan=scan) * 1e6:,.4f} mm²\n" + f"Copper width: {mfile.get('dx_tf_croco_strand_copper', scan=scan) * 1e3:,.4f} mm\n" + f"Diameter of solder tape region: {mfile.get('dia_tf_croco_strand_tape_region', scan=scan) * 1e3:,.4f} mm\n" + f"Height of tape stack: {mfile.get('dx_tf_croco_strand_tape_stack', scan=scan) * 1e3:,.4f} mm\n" + f"Width of HTS tape / tape stack: {mfile.get('dr_tf_hts_tape', scan=scan) * 1e3:,.4f} mm\n" + f"Number of HTS tape layers: {int(mfile.get('n_tf_croco_strand_hts_tapes', scan=scan))}\n \n" + f"Total copper area: {mfile.get('a_tf_croco_strand_copper_total', scan=scan) * 1e6:,.4f} mm²\n" + f"Total hastelloy area: {mfile.get('a_tf_croco_strand_hastelloy', scan=scan) * 1e6:,.4f} mm²\n" + f"Total solder area: {mfile.get('a_tf_croco_strand_solder', scan=scan) * 1e6:,.4f} mm²\n" + f"Total superconductor area: {mfile.get('a_tf_croco_strand_rebco', scan=scan) * 1e6:,.4f} mm²\n" + f"Total strand area: {mfile.get('a_tf_croco_strand', scan=scan) * 1e6:,.4f} mm²\n" ) axis.text( @@ -14891,17 +14879,19 @@ def main_plot( r_centre=0.0, z_centre=0.0, dia_croco_strand=m_file.get("dia_tf_turn_croco_cable", scan=scan), - dx_croco_strand_copper=m_file.get("dx_croco_strand_copper", scan=scan), - dr_hts_tape=m_file.get("dr_hts_tape", scan=scan), + dx_croco_strand_copper=m_file.get( + "dx_tf_croco_strand_copper", scan=scan + ), + dr_hts_tape=m_file.get("dr_tf_hts_tape", scan=scan), dx_croco_strand_tape_stack=m_file.get( - "dx_croco_strand_tape_stack", scan=scan + "dx_tf_croco_strand_tape_stack", scan=scan ), n_croco_strand_hts_tapes=m_file.get( - "n_croco_strand_hts_tapes", scan=scan + "n_tf_croco_strand_hts_tapes", scan=scan ), - dx_hts_tape_rebco=m_file.get("dx_hts_tape_rebco", scan=scan), - dx_hts_tape_copper=m_file.get("dx_hts_tape_copper", scan=scan), - dx_hts_tape_hastelloy=m_file.get("dx_hts_tape_hastelloy", scan=scan), + dx_hts_tape_rebco=m_file.get("dx_tf_hts_tape_rebco", scan=scan), + dx_hts_tape_copper=m_file.get("dx_tf_hts_tape_copper", scan=scan), + dx_hts_tape_hastelloy=m_file.get("dx_tf_hts_tape_hastelloy", scan=scan), show_legend=True, ) plot_tf_corc_cable_summary_box(plot_205, figs[25], m_file, scan) @@ -14909,10 +14899,10 @@ def main_plot( axis=figs[25].add_subplot(339), r_left=0.0, z_bottom=0.0, - dr_hts_tape=m_file.get("dr_hts_tape", scan=scan), - dx_hts_tape_rebco=m_file.get("dx_hts_tape_rebco", scan=scan), - dx_hts_tape_copper=m_file.get("dx_hts_tape_copper", scan=scan), - dx_hts_tape_hastelloy=m_file.get("dx_hts_tape_hastelloy", scan=scan), + dr_hts_tape=m_file.get("dr_tf_hts_tape", scan=scan), + dx_hts_tape_rebco=m_file.get("dx_tf_hts_tape_rebco", scan=scan), + dx_hts_tape_copper=m_file.get("dx_tf_hts_tape_copper", scan=scan), + dx_hts_tape_hastelloy=m_file.get("dx_tf_hts_tape_hastelloy", scan=scan), show_legend=True, ) elif ( diff --git a/process/core/solver/constraints.py b/process/core/solver/constraints.py index 63c62150e..71a506a68 100644 --- a/process/core/solver/constraints.py +++ b/process/core/solver/constraints.py @@ -1541,7 +1541,7 @@ def constraint_equation_75(constraint_registration, _data): """ return leq( data_structure.rebco_variables.coppera_m2, - data_structure.rebco_variables.coppera_m2_max, + data_structure.rebco_variables.tf_coppera_m2_max, constraint_registration, ) diff --git a/process/core/solver/iteration_variables.py b/process/core/solver/iteration_variables.py index 4341296fa..b16e2e5cd 100644 --- a/process/core/solver/iteration_variables.py +++ b/process/core/solver/iteration_variables.py @@ -226,10 +226,10 @@ class IterationVariable: array_index=13, ), 138: IterationVariable( - "dx_hts_tape_rebco", data_structure.physics_variables, 0.01e-6, 100.0e-6 + "dx_tf_hts_tape_rebco", data_structure.physics_variables, 0.01e-6, 100.0e-6 ), 139: IterationVariable( - "dx_hts_tape_copper", data_structure.rebco_variables, 1.0e-6, 1.0e-3 + "dx_tf_hts_tape_copper", data_structure.rebco_variables, 1.0e-6, 1.0e-3 ), 140: IterationVariable( "dr_tf_wp_with_insulation", data_structure.tfcoil_variables, 0.001, 2.0 @@ -249,7 +249,7 @@ class IterationVariable: 155: IterationVariable("pfusife", "ife", 5.0e2, 3.0e3), 156: IterationVariable("rrin", "ife", 1.0, 1.0e1), 158: IterationVariable( - "dx_croco_strand_copper", data_structure.rebco_variables, 1.0e-3, 1.0e-1 + "dx_tf_croco_strand_copper", data_structure.rebco_variables, 1.0e-3, 1.0e-1 ), 162: IterationVariable("r_cp_top", "build", 0.0010, 10.0), 169: IterationVariable( diff --git a/process/data_structure/numerics.py b/process/data_structure/numerics.py index 79f1feb67..8494b3c04 100644 --- a/process/data_structure/numerics.py +++ b/process/data_structure/numerics.py @@ -333,8 +333,8 @@ * (135) f_nd_impurity_electrons(13) : Xenon density fraction relative to electron density * (136) f_nd_impurity_electrons(14) : Tungsten density fraction relative to electron density * (137) NOT USED -* (138) dx_hts_tape_rebco : thickness of REBCO layer in tape (m) -* (139) dx_hts_tape_copper : thickness of copper layer in tape (m) +* (138) dx_tf_hts_tape_rebco : thickness of REBCO layer in tape (m) +* (139) dx_tf_hts_tape_copper : thickness of copper layer in tape (m) * (140) dr_tf_wp_with_insulation : radial thickness of TFC winding pack (m) * (141) NOT USED * (142) nd_plasma_separatrix_electron : electron density at separatrix [m-3] @@ -353,7 +353,7 @@ * (155) pfusife : IFE input fusion power (MW) (ifedrv=3 only) * (156) rrin : Input IFE repetition rate (Hz) (ifedrv=3 only) * (157) NOT USED -* (158) dx_croco_strand_copper : Thickness of CroCo copper tube (m) +* (158) dx_tf_croco_strand_copper : Thickness of CroCo copper tube (m) * (159) NOT USED * (160) NOT USED * (161) NOT USED diff --git a/process/data_structure/rebco_variables.py b/process/data_structure/rebco_variables.py index fcfd7f029..65f1d79c2 100644 --- a/process/data_structure/rebco_variables.py +++ b/process/data_structure/rebco_variables.py @@ -1,4 +1,4 @@ -dx_hts_tape_rebco: float = None +dx_tf_hts_tape_rebco: float = None """thickness of REBCO layer in tape (m) (`iteration variable 138`)""" dx_hts_tape_copper: float = None @@ -60,7 +60,7 @@ def init_rebco_variables(): """Initialise the REBCO variables""" global \ - dx_hts_tape_rebco, \ + dx_tf_hts_tape_rebco, \ dx_hts_tape_copper, \ dx_hts_tape_hastelloy, \ dr_hts_tape, \ @@ -80,7 +80,7 @@ def init_rebco_variables(): copperaoh_m2_max, \ copperaoh_m2 - dx_hts_tape_rebco = 1.0e-6 + dx_tf_hts_tape_rebco = 1.0e-6 dx_hts_tape_copper = 100.0e-6 dx_hts_tape_hastelloy = 50.0e-6 dr_hts_tape = 4.0e-3 diff --git a/process/data_structure/superconducting_tf_coil_variables.py b/process/data_structure/superconducting_tf_coil_variables.py index 27a444fc9..fb75c09f6 100644 --- a/process/data_structure/superconducting_tf_coil_variables.py +++ b/process/data_structure/superconducting_tf_coil_variables.py @@ -227,11 +227,64 @@ vv_stress_quench: float = None """The Tresca stress experienced by the Vacuum Vessel when the SCTF coil quenches [Pa]""" +# REBCO tape and CroCo strand variables + +dx_tf_hts_tape_rebco: float = None +"""thickness of REBCO layer in tape (m) (`iteration variable 138`)""" + +dx_tf_hts_tape_copper: float = None +"""thickness of copper layer in tape (m) (`iteration variable 139`)""" + +dx_tf_hts_tape_hastelloy: float = None +"""thickness of Hastelloy layer in tape (m)""" + +dr_tf_hts_tape: float = None +"""Mean width of tape (m)""" + +dx_tf_hts_tape_total: float = None +"""thickness of tape, inc. all layers (hts, copper, substrate, etc.) (m)""" + +dia_tf_croco_strand_tape_region: float = None +"""Inner diameter of CroCo strand tape region (m)""" + +dx_tf_croco_strand_copper: float = None +"""Thickness of CroCo strand copper tube (m) (`iteration variable 158`)""" + +copper_rrr: float = None +"""residual resistivity ratio copper in TF superconducting cable""" + +tf_coppera_m2: float = None +"""TF coil current / copper area (A/m2)""" + +tf_coppera_m2_max: float = None +"""Maximum TF coil current / copper area (A/m2)""" + +dx_tf_croco_strand_tape_stack: float = None +"""Width / thickness of tape stack in CroCo strand (m)""" + +n_tf_croco_strand_hts_tapes: float = None +"""Number of HTS tapes in CroCo strand""" + +a_tf_croco_strand_rebco: float = None +"""Area of REBCO in CroCo strand (m2)""" + +a_tf_croco_strand_copper_total: float = None +"""Area of copper in CroCo strand (includes tapes and outer tube) (m2)""" + +a_tf_croco_strand_hastelloy: float = None +"""Area of Hastelloy in CroCo strand (m2)""" + +a_tf_croco_strand_solder: float = None +"""Area of solder in CroCo strand (m2)""" + +a_tf_croco_strand: float = None +"""Total area of a CroCo strand (m2)""" + # croco_strand -croco_strand_area: float = None -croco_strand_critical_current: float = None +tf_croco_strand_area: float = None +tf_croco_strand_critical_current: float = None # conductor @@ -328,7 +381,26 @@ def init_superconducting_tf_coil_variables(): c_tf_turn_cables_critical, \ j_tf_superconductor, \ i_tf_turn_type, \ - vv_stress_quench + vv_stress_quench, \ + dx_tf_hts_tape_rebco, \ + dx_tf_hts_tape_copper, \ + dx_tf_hts_tape_hastelloy, \ + dr_tf_hts_tape, \ + dx_tf_hts_tape_total, \ + dia_tf_croco_strand_tape_region, \ + dx_tf_croco_strand_copper, \ + copper_rrr, \ + tf_coppera_m2, \ + tf_coppera_m2_max, \ + dx_tf_croco_strand_tape_stack, \ + n_tf_croco_strand_hts_tapes, \ + a_tf_croco_strand_rebco, \ + a_tf_croco_strand_copper_total, \ + a_tf_croco_strand_hastelloy, \ + a_tf_croco_strand_solder, \ + a_tf_croco_strand, \ + tf_croco_strand_area, \ + tf_croco_strand_critical_current is_leg_cp_temp_same = 0 tf_fit_t = 0.0 @@ -392,3 +464,23 @@ def init_superconducting_tf_coil_variables(): j_tf_superconductor = 0.0 i_tf_turn_type = 1 vv_stress_quench = 0.0 + + dx_tf_hts_tape_rebco = 1.0e-6 + dx_tf_hts_tape_copper = 100.0e-6 + dx_tf_hts_tape_hastelloy = 50.0e-6 + dr_tf_hts_tape = 4.0e-3 + dx_tf_hts_tape_total = 6.5e-5 + dia_tf_croco_strand_tape_region = 0.0 + dx_tf_croco_strand_copper = 2.5e-3 + copper_rrr = 100.0 + tf_coppera_m2 = 0.0 + tf_coppera_m2_max = 1.0e8 + dx_tf_croco_strand_tape_stack = 0.0 + n_tf_croco_strand_hts_tapes = 0.0 + a_tf_croco_strand_rebco = 0.0 + a_tf_croco_strand_copper_total = 0.0 + a_tf_croco_strand_hastelloy = 0.0 + a_tf_croco_strand_solder = 0.0 + a_tf_croco_strand = 0.0 + tf_croco_strand_area = 0.0 + tf_croco_strand_critical_current = 0.0 diff --git a/process/models/pfcoil.py b/process/models/pfcoil.py index 5e6801758..9cd15bb07 100644 --- a/process/models/pfcoil.py +++ b/process/models/pfcoil.py @@ -4223,9 +4223,9 @@ def superconpf(bmax, fhe, fcu, jwp, isumat, fhts, strain, thelium, bcritsc, tcri bmax, bc20m, tc0m, - rcv.dr_hts_tape, - rcv.dx_hts_tape_rebco, - rcv.dx_hts_tape_total, + rcv.dr_tf_hts_tape, + rcv.dx_tf_hts_tape_rebco, + rcv.dx_tf_hts_tape_total, ) # A0 calculated for tape cross section already # j_crit_cable = j_crit_sc * non-copper fraction of conductor * conductor fraction of cable diff --git a/process/models/stellarator/coils/quench.py b/process/models/stellarator/coils/quench.py index fed5fd484..90c26efce 100644 --- a/process/models/stellarator/coils/quench.py +++ b/process/models/stellarator/coils/quench.py @@ -75,7 +75,7 @@ def calculate_quench_protection(coilcurrent, data: DataStructure): ) # Also give the copper current density (copper A/m2) for REBCO quench calculations: - rebco_variables.coppera_m2 = ( + rebco_variables.tf_coppera_m2 = ( coilcurrent * 1.0e6 / ( diff --git a/process/models/superconductors.py b/process/models/superconductors.py index a5da57821..c03ea301b 100644 --- a/process/models/superconductors.py +++ b/process/models/superconductors.py @@ -9,7 +9,10 @@ from scipy import optimize from process.core.exceptions import ProcessValueError -from process.data_structure import rebco_variables +from process.data_structure import ( + rebco_variables, + superconducting_tf_coil_variables, +) logger = logging.getLogger(__name__) @@ -1148,15 +1151,15 @@ def croco(j_crit_sc, conductor_area, dia_croco_strand, dx_croco_strand_copper): croco_cable_geometry: CroCoCableGeometry = calculate_croco_cable_geometry( dia_croco_strand=dia_croco_strand, dx_croco_strand_copper=dx_croco_strand_copper, - dx_hts_tape_rebco=rebco_variables.dx_hts_tape_rebco, - dx_hts_tape_copper=rebco_variables.dx_hts_tape_copper, - dx_hts_tape_hastelloy=rebco_variables.dx_hts_tape_hastelloy, + dx_hts_tape_rebco=superconducting_tf_coil_variables.dx_tf_hts_tape_rebco, + dx_hts_tape_copper=superconducting_tf_coil_variables.dx_tf_hts_tape_copper, + dx_hts_tape_hastelloy=superconducting_tf_coil_variables.dx_tf_hts_tape_hastelloy, ) - rebco_variables.dia_croco_strand_tape_region = ( + superconducting_tf_coil_variables.dia_tf_croco_strand_tape_region = ( croco_cable_geometry.dia_croco_strand_tape_region ) - rebco_variables.n_croco_strand_hts_tapes = ( + superconducting_tf_coil_variables.n_tf_croco_strand_hts_tapes = ( croco_cable_geometry.n_croco_strand_hts_tapes ) a_croco_strand_copper_total = croco_cable_geometry.a_croco_strand_copper_total @@ -1164,16 +1167,20 @@ def croco(j_crit_sc, conductor_area, dia_croco_strand, dx_croco_strand_copper): a_croco_strand_solder = croco_cable_geometry.a_croco_strand_solder a_croco_strand_rebco = croco_cable_geometry.a_croco_strand_rebco a_croco_strand = croco_cable_geometry.a_croco_strand - rebco_variables.dr_hts_tape = croco_cable_geometry.dr_hts_tape - rebco_variables.dx_croco_strand_tape_stack = ( + superconducting_tf_coil_variables.dr_tf_hts_tape = croco_cable_geometry.dr_hts_tape + superconducting_tf_coil_variables.dx_tf_croco_strand_tape_stack = ( croco_cable_geometry.dx_croco_strand_tape_stack ) - rebco_variables.a_croco_strand_copper_total = a_croco_strand_copper_total - rebco_variables.a_croco_strand_hastelloy = a_croco_strand_hastelloy - rebco_variables.a_croco_strand_solder = a_croco_strand_solder - rebco_variables.a_croco_strand_rebco = a_croco_strand_rebco - rebco_variables.a_croco_strand = a_croco_strand + superconducting_tf_coil_variables.a_croco_strand_copper_total = ( + a_croco_strand_copper_total + ) + superconducting_tf_coil_variables.a_tf_croco_strand_hastelloy = ( + a_croco_strand_hastelloy + ) + superconducting_tf_coil_variables.a_tf_croco_strand_solder = a_croco_strand_solder + superconducting_tf_coil_variables.a_tf_croco_strand_rebco = a_croco_strand_rebco + superconducting_tf_coil_variables.a_tf_croco_strand = a_croco_strand croco_strand_critical_current = j_crit_sc * a_croco_strand_rebco @@ -1294,9 +1301,9 @@ def superconductor_current_density_margin( b_superconductor, bc20m, tc0m, - rebco_variables.dr_hts_tape, - rebco_variables.dx_hts_tape_rebco, - rebco_variables.dx_hts_tape_total, + rebco_variables.dr_tf_hts_tape, + rebco_variables.dx_tf_hts_tape_rebco, + rebco_variables.dx_tf_hts_tape_total, )[0], } diff --git a/process/models/tfcoil/base.py b/process/models/tfcoil/base.py index e34f13975..f82b15aea 100644 --- a/process/models/tfcoil/base.py +++ b/process/models/tfcoil/base.py @@ -1953,14 +1953,14 @@ def outtf(self): self.outfile, "Maximum permitted TF coil current / copper area (A/m2)", "(copperA_m2_max)", - rebco_variables.coppera_m2_max, + rebco_variables.tf_coppera_m2_max, ) po.ovarre( self.outfile, "Actual TF coil current / copper area (A/m2)", "(copperA_m2)", - rebco_variables.coppera_m2, + rebco_variables.tf_coppera_m2, ) # TF coil radial build diff --git a/process/models/tfcoil/superconducting.py b/process/models/tfcoil/superconducting.py index aabb68986..81791c31a 100644 --- a/process/models/tfcoil/superconducting.py +++ b/process/models/tfcoil/superconducting.py @@ -2460,9 +2460,9 @@ def tf_cable_in_conduit_superconductor_properties( b_conductor=b_tf_inboard_peak, b_c20max=bc20m, t_c0=tc0m, - dr_hts_tape=rebco_variables.dr_hts_tape, - dx_hts_tape_rebco=rebco_variables.dx_hts_tape_rebco, - dx_hts_tape_total=rebco_variables.dx_hts_tape_total, + dr_hts_tape=rebco_variables.dr_tf_hts_tape, + dx_hts_tape_rebco=rebco_variables.dx_tf_hts_tape_rebco, + dx_hts_tape_total=rebco_variables.dx_tf_hts_tape_total, ) # Scale for the copper area fraction of the cable j_cables_critical = j_superconductor_critical * ( @@ -3162,33 +3162,43 @@ def run(self, output: bool = False): croco_cable_geometry: CroCoCableGeometry = calculate_croco_cable_geometry( dia_croco_strand=superconducting_tf_coil_variables.dia_tf_turn_croco_cable, - dx_croco_strand_copper=rebco_variables.dx_croco_strand_copper, - dx_hts_tape_rebco=rebco_variables.dx_hts_tape_rebco, - dx_hts_tape_copper=rebco_variables.dx_hts_tape_copper, - dx_hts_tape_hastelloy=rebco_variables.dx_hts_tape_hastelloy, + dx_croco_strand_copper=superconducting_tf_coil_variables.dx_tf_croco_strand_copper, + dx_hts_tape_rebco=superconducting_tf_coil_variables.dx_tf_hts_tape_rebco, + dx_hts_tape_copper=superconducting_tf_coil_variables.dx_tf_hts_tape_copper, + dx_hts_tape_hastelloy=superconducting_tf_coil_variables.dx_tf_hts_tape_hastelloy, ) - rebco_variables.dia_croco_strand_tape_region = ( + superconducting_tf_coil_variables.dia_tf_croco_strand_tape_region = ( croco_cable_geometry.dia_croco_strand_tape_region ) - rebco_variables.n_croco_strand_hts_tapes = ( + superconducting_tf_coil_variables.n_tf_croco_strand_hts_tapes = ( croco_cable_geometry.n_croco_strand_hts_tapes ) - a_croco_strand_copper_total = croco_cable_geometry.a_croco_strand_copper_total - a_croco_strand_hastelloy = croco_cable_geometry.a_croco_strand_hastelloy - a_croco_strand_solder = croco_cable_geometry.a_croco_strand_solder - a_croco_strand_rebco = croco_cable_geometry.a_croco_strand_rebco - a_croco_strand = croco_cable_geometry.a_croco_strand - rebco_variables.dr_hts_tape = croco_cable_geometry.dr_hts_tape - rebco_variables.dx_croco_strand_tape_stack = ( + a_tf_croco_strand_copper_total = croco_cable_geometry.a_croco_strand_copper_total + a_tf_croco_strand_hastelloy = croco_cable_geometry.a_croco_strand_hastelloy + a_tf_croco_strand_solder = croco_cable_geometry.a_croco_strand_solder + a_tf_croco_strand_rebco = croco_cable_geometry.a_croco_strand_rebco + a_tf_croco_strand = croco_cable_geometry.a_croco_strand + superconducting_tf_coil_variables.dr_tf_hts_tape = ( + croco_cable_geometry.dr_hts_tape + ) + superconducting_tf_coil_variables.dx_tf_croco_strand_tape_stack = ( croco_cable_geometry.dx_croco_strand_tape_stack ) - rebco_variables.a_croco_strand_copper_total = a_croco_strand_copper_total - rebco_variables.a_croco_strand_hastelloy = a_croco_strand_hastelloy - rebco_variables.a_croco_strand_solder = a_croco_strand_solder - rebco_variables.a_croco_strand_rebco = a_croco_strand_rebco - rebco_variables.a_croco_strand = a_croco_strand + superconducting_tf_coil_variables.a_tf_croco_strand_copper_total = ( + a_tf_croco_strand_copper_total + ) + superconducting_tf_coil_variables.a_tf_croco_strand_hastelloy = ( + a_tf_croco_strand_hastelloy + ) + superconducting_tf_coil_variables.a_tf_croco_strand_solder = ( + a_tf_croco_strand_solder + ) + superconducting_tf_coil_variables.a_tf_croco_strand_rebco = ( + a_tf_croco_strand_rebco + ) + superconducting_tf_coil_variables.a_tf_croco_strand = a_tf_croco_strand # Negative areas or fractions error reporting if ( @@ -3647,7 +3657,7 @@ def supercon_croco( j_crit_sc, _ = superconductors.jcrit_rebco(thelium, b_tf_inboard_peak_symmetric) ( - superconducting_tf_coil_variables.croco_strand_area, + superconducting_tf_coil_variables.a_tf_croco_strand, superconducting_tf_coil_variables.croco_strand_critical_current, superconducting_tf_coil_variables.conductor_copper_area, superconducting_tf_coil_variables.conductor_copper_fraction, @@ -3665,17 +3675,17 @@ def supercon_croco( j_crit_sc, superconducting_tf_coil_variables.conductor_area, superconducting_tf_coil_variables.dia_tf_turn_croco_cable, - rebco_variables.dx_croco_strand_copper, + superconducting_tf_coil_variables.dx_tf_croco_strand_copper, ) - rebco_variables.coppera_m2 = ( + superconducting_tf_coil_variables.tf_coppera_m2 = ( iop / superconducting_tf_coil_variables.conductor_copper_area ) icrit = superconducting_tf_coil_variables.conductor_critical_current j_crit_cable = ( superconducting_tf_coil_variables.croco_strand_critical_current - / superconducting_tf_coil_variables.croco_strand_area + / superconducting_tf_coil_variables.a_tf_croco_strand ) # Critical current density in winding pack @@ -3842,27 +3852,27 @@ def output_croco_info(self): po.ovarre( self.outfile, "Thickness of REBCO layer in tape (m)", - "(dx_hts_tape_rebco)", - rebco_variables.dx_hts_tape_rebco, + "(dx_tf_hts_tape_rebco)", + superconducting_tf_coil_variables.dx_tf_hts_tape_rebco, ) po.ovarre( self.outfile, "Thickness of copper layer in tape (m)", - "(dx_hts_tape_copper)", - rebco_variables.dx_hts_tape_copper, + "(dx_tf_hts_tape_copper)", + superconducting_tf_coil_variables.dx_tf_hts_tape_copper, ) po.ovarre( self.outfile, "Thickness of Hastelloy layer in tape (m) ", - "(dx_hts_tape_hastelloy)", - rebco_variables.dx_hts_tape_hastelloy, + "(dx_tf_hts_tape_hastelloy)", + superconducting_tf_coil_variables.dx_tf_hts_tape_hastelloy, ) po.ovarre( self.outfile, "Mean width of tape (m)", - "(dr_hts_tape)", - rebco_variables.dr_hts_tape, + "(dr_tf_hts_tape)", + superconducting_tf_coil_variables.dr_tf_hts_tape, "OP ", ) po.ovarre( @@ -3875,89 +3885,89 @@ def output_croco_info(self): po.ovarre( self.outfile, "Inner diameter of CroCo copper tube (m) ", - "(dia_croco_strand_tape_region)", - rebco_variables.dia_croco_strand_tape_region, + "(dia_tf_croco_strand_tape_region)", + superconducting_tf_coil_variables.dia_tf_croco_strand_tape_region, "OP ", ) po.ovarre( self.outfile, "Thickness of of o copper tube (m) ", - "(dx_croco_strand_copper)", - rebco_variables.dx_croco_strand_copper, + "(dx_tf_croco_strand_copper)", + superconducting_tf_coil_variables.dx_tf_croco_strand_copper, ) po.ovarre( self.outfile, "Thickness of each HTS tape ", - "(dx_hts_tape_total)", - rebco_variables.dx_hts_tape_total, + "(dx_tf_hts_tape_total)", + superconducting_tf_coil_variables.dx_tf_hts_tape_total, "OP ", ) po.ovarre( self.outfile, "Thickness of stack of rebco_variables.n_croco_strand_hts_tapes (m) ", - "(dx_croco_strand_tape_stack)", - rebco_variables.dx_croco_strand_tape_stack, + "(dx_tf_croco_strand_tape_stack)", + superconducting_tf_coil_variables.dx_tf_croco_strand_tape_stack, "OP ", ) po.ovarre( self.outfile, - "Number of rebco_variables.n_croco_strand_hts_tapes in strand", - "(n_croco_strand_hts_tapes)", - rebco_variables.n_croco_strand_hts_tapes, + "Number of rebco_variables.n_tf_croco_strand_hts_tapes in strand", + "(n_tf_croco_strand_hts_tapes)", + superconducting_tf_coil_variables.n_tf_croco_strand_hts_tapes, "OP ", ) po.oblnkl(self.outfile) po.ovarre( self.outfile, "Area of total CroCo strand (m2)", - "(a_croco_strand)", - rebco_variables.a_croco_strand, + "(a_tf_croco_strand)", + superconducting_tf_coil_variables.a_tf_croco_strand, "OP ", ) po.ovarre( self.outfile, "Area of REBCO in strand (m2)", - "(a_croco_strand_rebco)", - rebco_variables.a_croco_strand_rebco, + "(a_tf_croco_strand_rebco)", + superconducting_tf_coil_variables.a_tf_croco_strand_rebco, "OP ", ) po.ovarre( self.outfile, "Area of copper in strand (m2)", - "(a_croco_strand_copper_total)", - rebco_variables.a_croco_strand_copper_total, + "(a_tf_croco_strand_copper_total)", + superconducting_tf_coil_variables.a_tf_croco_strand_copper_total, "OP ", ) po.ovarre( self.outfile, "Area of hastelloy substrate in strand (m2) ", - "(a_croco_strand_hastelloy)", - rebco_variables.a_croco_strand_hastelloy, + "(a_tf_croco_strand_hastelloy)", + superconducting_tf_coil_variables.a_tf_croco_strand_hastelloy, "OP ", ) po.ovarre( self.outfile, "Area of solder in strand (m2) ", - "(a_croco_strand_solder)", - rebco_variables.a_croco_strand_solder, + "(a_tf_croco_strand_solder)", + superconducting_tf_coil_variables.a_tf_croco_strand_solder, "OP ", ) po.ovarre( self.outfile, "Total: area of CroCo strand (m2) ", - "(croco_strand_area)", - superconducting_tf_coil_variables.croco_strand_area, + "(a_tf_croco_strand)", + superconducting_tf_coil_variables.a_tf_croco_strand, "OP ", ) if ( abs( - superconducting_tf_coil_variables.croco_strand_area + superconducting_tf_coil_variables.a_tf_croco_strand - ( - rebco_variables.a_croco_strand_rebco - + rebco_variables.a_croco_strand_copper_total - + rebco_variables.a_croco_strand_hastelloy - + rebco_variables.a_croco_strand_solder + superconducting_tf_coil_variables.a_tf_croco_strand_rebco + + superconducting_tf_coil_variables.a_tf_croco_strand_copper_total + + superconducting_tf_coil_variables.a_tf_croco_strand_hastelloy + + superconducting_tf_coil_variables.a_tf_croco_strand_solder ) ) > 1e-6 @@ -4004,7 +4014,7 @@ def output_croco_info(self): po.ovarre( self.outfile, "REBCO area of conductor (mm2)", - "(a_croco_strand_rebco)", + "(a_tf_croco_strand_rebco)", superconducting_tf_coil_variables.conductor_rebco_area, "OP ", ) @@ -4018,21 +4028,21 @@ def output_croco_info(self): po.ovarre( self.outfile, "Total copper area of conductor, total (mm2)", - "(a_croco_strand_copper_total)", + "(a_tf_croco_strand_copper_total)", superconducting_tf_coil_variables.conductor_copper_area, "OP ", ) po.ovarre( self.outfile, "Hastelloy area of conductor (mm2)", - "(a_croco_strand_hastelloy)", + "(a_tf_croco_strand_hastelloy)", superconducting_tf_coil_variables.conductor_hastelloy_area, "OP ", ) po.ovarre( self.outfile, "Solder area of conductor (mm2)", - "(a_croco_strand_solder)", + "(a_tf_croco_strand_solder)", superconducting_tf_coil_variables.conductor_solder_area, "OP ", ) From e182b0c0d21e427e276460463501e45c9a8be53c Mon Sep 17 00:00:00 2001 From: mn3981 Date: Wed, 13 May 2026 11:48:57 +0100 Subject: [PATCH 19/37] Update tests --- process/core/solver/constraints.py | 2 +- process/models/pfcoil.py | 6 +-- process/models/superconductors.py | 7 ++- process/models/tfcoil/superconducting.py | 7 ++- tests/unit/models/test_superconductors.py | 52 ++++++++++++----------- 5 files changed, 38 insertions(+), 36 deletions(-) diff --git a/process/core/solver/constraints.py b/process/core/solver/constraints.py index 71a506a68..e456c2ac6 100644 --- a/process/core/solver/constraints.py +++ b/process/core/solver/constraints.py @@ -1541,7 +1541,7 @@ def constraint_equation_75(constraint_registration, _data): """ return leq( data_structure.rebco_variables.coppera_m2, - data_structure.rebco_variables.tf_coppera_m2_max, + data_structure.superconducting_tf_coil_variables.tf_coppera_m2_max, constraint_registration, ) diff --git a/process/models/pfcoil.py b/process/models/pfcoil.py index 9cd15bb07..c049f0f85 100644 --- a/process/models/pfcoil.py +++ b/process/models/pfcoil.py @@ -4223,9 +4223,9 @@ def superconpf(bmax, fhe, fcu, jwp, isumat, fhts, strain, thelium, bcritsc, tcri bmax, bc20m, tc0m, - rcv.dr_tf_hts_tape, - rcv.dx_tf_hts_tape_rebco, - rcv.dx_tf_hts_tape_total, + superconducting_tf_coil_variables.dr_tf_hts_tape, + superconducting_tf_coil_variables.dx_tf_hts_tape_rebco, + superconducting_tf_coil_variables.dx_tf_hts_tape_total, ) # A0 calculated for tape cross section already # j_crit_cable = j_crit_sc * non-copper fraction of conductor * conductor fraction of cable diff --git a/process/models/superconductors.py b/process/models/superconductors.py index c03ea301b..9aa8baa69 100644 --- a/process/models/superconductors.py +++ b/process/models/superconductors.py @@ -10,7 +10,6 @@ from process.core.exceptions import ProcessValueError from process.data_structure import ( - rebco_variables, superconducting_tf_coil_variables, ) @@ -1301,9 +1300,9 @@ def superconductor_current_density_margin( b_superconductor, bc20m, tc0m, - rebco_variables.dr_tf_hts_tape, - rebco_variables.dx_tf_hts_tape_rebco, - rebco_variables.dx_tf_hts_tape_total, + superconducting_tf_coil_variables.dr_tf_hts_tape, + superconducting_tf_coil_variables.dx_tf_hts_tape_rebco, + superconducting_tf_coil_variables.dx_tf_hts_tape_total, )[0], } diff --git a/process/models/tfcoil/superconducting.py b/process/models/tfcoil/superconducting.py index 81791c31a..48a30c686 100644 --- a/process/models/tfcoil/superconducting.py +++ b/process/models/tfcoil/superconducting.py @@ -17,7 +17,6 @@ global_variables, pfcoil_variables, physics_variables, - rebco_variables, superconducting_tf_coil_variables, tfcoil_variables, ) @@ -2460,9 +2459,9 @@ def tf_cable_in_conduit_superconductor_properties( b_conductor=b_tf_inboard_peak, b_c20max=bc20m, t_c0=tc0m, - dr_hts_tape=rebco_variables.dr_tf_hts_tape, - dx_hts_tape_rebco=rebco_variables.dx_tf_hts_tape_rebco, - dx_hts_tape_total=rebco_variables.dx_tf_hts_tape_total, + dr_hts_tape=superconducting_tf_coil_variables.dr_tf_hts_tape, + dx_hts_tape_rebco=superconducting_tf_coil_variables.dx_tf_hts_tape_rebco, + dx_hts_tape_total=superconducting_tf_coil_variables.dx_tf_hts_tape_total, ) # Scale for the copper area fraction of the cable j_cables_critical = j_superconductor_critical * ( diff --git a/tests/unit/models/test_superconductors.py b/tests/unit/models/test_superconductors.py index 62477530b..fc8e6b12c 100644 --- a/tests/unit/models/test_superconductors.py +++ b/tests/unit/models/test_superconductors.py @@ -3,6 +3,7 @@ import pytest from process.models import superconductors +from process.models.superconductors import CroCoCableGeometry class IterscParam(NamedTuple): @@ -221,19 +222,18 @@ def test_hijc_rebco(): 1e-6, # 1 um 2e-6, # 2 um 3e-6, # 3 um - ( - 0.008, # dia_croco_strand_tape_region - pytest.approx(959.3950997769347, rel=1e-3), # n_croco_strand_hts_tapes - pytest.approx( + CroCoCableGeometry( + dia_croco_strand_tape_region=0.008, + n_croco_strand_hts_tapes=pytest.approx(959.3950997769347, rel=1e-3), + a_croco_strand_copper_total=pytest.approx( 3.8934279435385194e-05, rel=1e-3 - ), # a_croco_strand_copper_total - pytest.approx( - 1.5989918329615573e-05, rel=1e-3 - ), # a_croco_strand_hastelloy - pytest.approx(1.8285645798205533e-05, rel=1e-3), # a_croco_strand_solder - pytest.approx(5.329972776538525e-06, rel=1e-3), # a_croco_strand_rebco - pytest.approx(7.85398e-5, rel=1e-3), # croco_strand_area - pytest.approx(5.5556e-3, rel=1e-3), # dr_hts_tape + ), + a_croco_strand_hastelloy=pytest.approx(1.5989918329615573e-05, rel=1e-3), + a_croco_strand_solder=pytest.approx(1.8285645798205533e-05, rel=1e-3), + a_croco_strand_rebco=pytest.approx(5.329972776538525e-06, rel=1e-3), + a_croco_strand=pytest.approx(7.85398e-5, rel=1e-3), + dr_hts_tape=pytest.approx(5.5556e-3, rel=1e-3), + dx_croco_strand_tape_stack=pytest.approx(0.005756370598661608, rel=1e-3), ), ), ( @@ -242,15 +242,20 @@ def test_hijc_rebco(): 1e-6, 2e-6, 3e-6, - ( - 0.0044, - pytest.approx(527.6673048773141, rel=1e-6), - pytest.approx(1.0921535531100803e-05, rel=1e-6), - pytest.approx(4.836950294708712e-06, rel=1e-6), - pytest.approx(5.531407853957174e-06, rel=1e-6), - pytest.approx(1.612316764902904e-06, rel=1e-6), - pytest.approx(2.2902210444669593e-05, rel=1e-6), - pytest.approx(0.0030555555555555553, rel=1e-6), + CroCoCableGeometry( + dia_croco_strand_tape_region=0.0044, + n_croco_strand_hts_tapes=pytest.approx(527.6673048773141, rel=1e-6), + a_croco_strand_copper_total=pytest.approx( + 1.0921535531100803e-05, rel=1e-6 + ), + a_croco_strand_hastelloy=pytest.approx(4.836950294708712e-06, rel=1e-6), + a_croco_strand_solder=pytest.approx(5.531407853957174e-06, rel=1e-6), + a_croco_strand_rebco=pytest.approx(1.612316764902904e-06, rel=1e-6), + a_croco_strand=pytest.approx(2.2902210444669593e-05, rel=1e-6), + dr_hts_tape=pytest.approx(0.0030555555555555553, rel=1e-6), + dx_croco_strand_tape_stack=pytest.approx( + 0.0031660038292638847, rel=1e-6 + ), ), ), ], @@ -263,12 +268,11 @@ def test_calculate_croco_cable_geometry( dx_hts_tape_hastelloy, expected, ): - result = superconductors.calculate_croco_cable_geometry( + result: CroCoCableGeometry = superconductors.calculate_croco_cable_geometry( dia_croco_strand, dx_croco_strand_copper, dx_hts_tape_rebco, dx_hts_tape_copper, dx_hts_tape_hastelloy, ) - for r, e in zip(result, expected, strict=True): - assert r == e + assert result == expected From 7ded183cd160d0bcd10fcc5cd9517decfa813bd0 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Wed, 13 May 2026 15:38:29 +0100 Subject: [PATCH 20/37] Rename croco superconductor --- documentation/source/eng-models/tf-coil-superconducting.md | 2 +- process/models/tfcoil/superconducting.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/documentation/source/eng-models/tf-coil-superconducting.md b/documentation/source/eng-models/tf-coil-superconducting.md index b375441b6..9ecadc14c 100644 --- a/documentation/source/eng-models/tf-coil-superconducting.md +++ b/documentation/source/eng-models/tf-coil-superconducting.md @@ -652,6 +652,6 @@ WIP WIP -### Superconductor properties | `supercon_croco()` +### Superconductor properties | `tf_croco_superconductor_properties()` ### Quench voltage | `croco_voltage()` \ No newline at end of file diff --git a/process/models/tfcoil/superconducting.py b/process/models/tfcoil/superconducting.py index 48a30c686..6efbb755e 100644 --- a/process/models/tfcoil/superconducting.py +++ b/process/models/tfcoil/superconducting.py @@ -3419,7 +3419,7 @@ def run(self, output: bool = False): ( tfcoil_variables.j_tf_wp_critical, tfcoil_variables.temp_tf_superconductor_margin, - ) = self.supercon_croco( + ) = self.tf_croco_superconductor_properties( a_tf_turn, tfcoil_variables.b_tf_inboard_peak_with_ripple, tfcoil_variables.c_tf_turn, @@ -3633,7 +3633,7 @@ def tf_croco_averaged_turn_geometry( dx_tf_turn_cable_space_average=dx_tf_turn_cable_space_average, ) - def supercon_croco( + def tf_croco_superconductor_properties( self, a_tf_turn, b_tf_inboard_peak_symmetric, iop, thelium, output: bool ): """TF superconducting CroCo conductor using REBCO tape From 6124ee59b5a8a937f2bc93366d93560917976e89 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Wed, 13 May 2026 16:24:48 +0100 Subject: [PATCH 21/37] Pass out function terms --- process/models/tfcoil/superconducting.py | 58 ++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/process/models/tfcoil/superconducting.py b/process/models/tfcoil/superconducting.py index 6efbb755e..10c0fadbc 100644 --- a/process/models/tfcoil/superconducting.py +++ b/process/models/tfcoil/superconducting.py @@ -3199,6 +3199,64 @@ def run(self, output: bool = False): ) superconducting_tf_coil_variables.a_tf_croco_strand = a_tf_croco_strand + j_crit_sc, _ = superconductors.jcrit_rebco( + temp_conductor=tfcoil_variables.tftmp, + b_conductor=tfcoil_variables.b_tf_inboard_peak_with_ripple, + ) + + croco_strand_critical_current = ( + j_crit_sc * superconducting_tf_coil_variables.a_tf_croco_strand + ) + + # Conductor properties + # conductor%number_croco = conductor%acs*(1.0-cable_helium_fraction-copper_bar)/a_croco_strand + superconducting_tf_coil_variables.conductor_critical_current = ( + croco_strand_critical_current * N_CROCO_STRANDS_TURN + ) + # Area of core = area of strand + conductor_copper_bar_area = superconducting_tf_coil_variables.a_tf_croco_strand + conductor_copper_area = ( + superconducting_tf_coil_variables.a_tf_croco_strand_copper_total + * N_CROCO_STRANDS_TURN + + conductor_copper_bar_area + ) + superconducting_tf_coil_variables.conductor_copper_fraction = ( + conductor_copper_area / superconducting_tf_coil_variables.conductor_area + ) + + # Helium area is set by the user. + # conductor_helium_area = cable_helium_fraction * tfcoil_variables.a_tf_turn_cable_space_no_void + conductor_helium_area = ( + np.pi / 2.0 * superconducting_tf_coil_variables.dia_tf_turn_croco_cable**2 + ) + superconducting_tf_coil_variables.conductor_helium_fraction = ( + conductor_helium_area / superconducting_tf_coil_variables.conductor_area + ) + + conductor_hastelloy_area = ( + superconducting_tf_coil_variables.a_tf_croco_strand_hastelloy + * N_CROCO_STRANDS_TURN + ) + superconducting_tf_coil_variables.conductor_hastelloy_fraction = ( + conductor_hastelloy_area / superconducting_tf_coil_variables.conductor_area + ) + + conductor_solder_area = ( + superconducting_tf_coil_variables.a_tf_croco_strand_solder + * N_CROCO_STRANDS_TURN + ) + superconducting_tf_coil_variables.conductor_solder_fraction = ( + conductor_solder_area / superconducting_tf_coil_variables.conductor_area + ) + + conductor_rebco_area = ( + superconducting_tf_coil_variables.a_tf_croco_strand_rebco + * N_CROCO_STRANDS_TURN + ) + superconducting_tf_coil_variables.conductor_rebco_fraction = ( + conductor_rebco_area / superconducting_tf_coil_variables.conductor_area + ) + # Negative areas or fractions error reporting if ( tfcoil_variables.a_tf_wp_conductor <= 0.0e0 From f28473d2894babf45e42860f0747615120b8f154 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Thu, 14 May 2026 13:53:58 +0100 Subject: [PATCH 22/37] Add CroCoCableSpaceGeometry class and refactor cable space calculations in CROCOSuperconductingTFCoil --- process/models/tfcoil/superconducting.py | 164 +++++++++++++++-------- 1 file changed, 106 insertions(+), 58 deletions(-) diff --git a/process/models/tfcoil/superconducting.py b/process/models/tfcoil/superconducting.py index 10c0fadbc..84fab1e95 100644 --- a/process/models/tfcoil/superconducting.py +++ b/process/models/tfcoil/superconducting.py @@ -3008,6 +3008,17 @@ class CROCOAveragedTurnGeometry: dx_tf_turn_cable_space_average: float +@dataclass +class CroCoCableSpaceGeometry: + dia_tf_turn_croco_cable: float + a_tf_turn_cable_space_no_void: float + a_tf_turn_cable_space_effective: float + a_tf_turn_steel: float + conductor_area: float + conductor_jacket_area: float + conductor_jacket_fraction: float + + class CROCOSuperconductingTFCoil(SuperconductingTFCoil): """Cross Conductor Superconducting TF Coil class.""" @@ -3122,43 +3133,70 @@ def run(self, output: bool = False): / tfcoil_variables.a_tf_inboard_total ) - superconducting_tf_coil_variables.dia_tf_turn_croco_cable = ( - tfcoil_variables.t_conductor / 3.0e0 - - tfcoil_variables.dx_tf_turn_steel * (2.0e0 / 3.0e0) + croco_cable_space_geometry: CroCoCableSpaceGeometry = ( + self.tf_turn_croco_cable_space_properties( + t_conductor=tfcoil_variables.t_conductor, + dx_tf_turn_steel=tfcoil_variables.dx_tf_turn_steel, + ) ) - # Area of the full cable circle in the turn + superconducting_tf_coil_variables.dia_tf_turn_croco_cable = ( + croco_cable_space_geometry.dia_tf_turn_croco_cable + ) tfcoil_variables.a_tf_turn_cable_space_no_void = ( - 9.0e0 - / 4.0e0 - * np.pi - * superconducting_tf_coil_variables.dia_tf_turn_croco_cable**2 + croco_cable_space_geometry.a_tf_turn_cable_space_no_void ) - # Area of the full cable spac circle minus the central copper strand superconducting_tf_coil_variables.a_tf_turn_cable_space_effective = ( - tfcoil_variables.a_tf_turn_cable_space_no_void - - 0.25e0 - * np.pi - * superconducting_tf_coil_variables.dia_tf_turn_croco_cable**2 + croco_cable_space_geometry.a_tf_turn_cable_space_effective ) - + tfcoil_variables.a_tf_turn_steel = croco_cable_space_geometry.a_tf_turn_steel superconducting_tf_coil_variables.conductor_area = ( - tfcoil_variables.t_conductor**2 - ) # does this not assume it's a sqaure??? - - superconducting_tf_coil_variables.conductor_jacket_area = ( - superconducting_tf_coil_variables.conductor_area - - tfcoil_variables.a_tf_turn_cable_space_no_void + croco_cable_space_geometry.conductor_area ) - tfcoil_variables.a_tf_turn_steel = ( - superconducting_tf_coil_variables.conductor_jacket_area + superconducting_tf_coil_variables.conductor_jacket_area = ( + croco_cable_space_geometry.conductor_jacket_area ) - superconducting_tf_coil_variables.conductor_jacket_fraction = ( - superconducting_tf_coil_variables.conductor_jacket_area - / superconducting_tf_coil_variables.conductor_area + croco_cable_space_geometry.conductor_jacket_fraction ) + # superconducting_tf_coil_variables.dia_tf_turn_croco_cable = ( + # tfcoil_variables.t_conductor / 3.0e0 + # - tfcoil_variables.dx_tf_turn_steel * (2.0e0 / 3.0e0) + # ) + + # # Area of the full cable circle in the turn + # tfcoil_variables.a_tf_turn_cable_space_no_void = ( + # 9.0e0 + # / 4.0e0 + # * np.pi + # * superconducting_tf_coil_variables.dia_tf_turn_croco_cable**2 + # ) + # # Area of the full cable spac circle minus the central copper strand + # superconducting_tf_coil_variables.a_tf_turn_cable_space_effective = ( + # tfcoil_variables.a_tf_turn_cable_space_no_void + # - 0.25e0 + # * np.pi + # * superconducting_tf_coil_variables.dia_tf_turn_croco_cable**2 + # ) + + # superconducting_tf_coil_variables.conductor_area = ( + # tfcoil_variables.t_conductor**2 + # ) # does this not assume it's a sqaure??? + + # superconducting_tf_coil_variables.conductor_jacket_area = ( + # superconducting_tf_coil_variables.conductor_area + # - tfcoil_variables.a_tf_turn_cable_space_no_void + # ) + # tfcoil_variables.a_tf_turn_steel = ( + # superconducting_tf_coil_variables.conductor_jacket_area + # ) + + # superconducting_tf_coil_variables.conductor_jacket_fraction = ( + # superconducting_tf_coil_variables.conductor_jacket_area + # / superconducting_tf_coil_variables.conductor_area + # ) + croco_cable_geometry: CroCoCableGeometry = calculate_croco_cable_geometry( dia_croco_strand=superconducting_tf_coil_variables.dia_tf_turn_croco_cable, dx_croco_strand_copper=superconducting_tf_coil_variables.dx_tf_croco_strand_copper, @@ -3768,15 +3806,6 @@ def tf_croco_superconductor_properties( ) if output: # Output ---------------------------------- - total = ( - superconducting_tf_coil_variables.conductor_copper_area - + superconducting_tf_coil_variables.conductor_hastelloy_area - + superconducting_tf_coil_variables.conductor_solder_area - + superconducting_tf_coil_variables.conductor_jacket_area - + superconducting_tf_coil_variables.conductor_helium_area - + superconducting_tf_coil_variables.conductor_rebco_area - ) - po.oblnkl(self.outfile) po.ovarre( self.outfile, @@ -3853,14 +3882,41 @@ def tf_croco_superconductor_properties( return j_tf_wp_critical, tmarg @staticmethod - def croco_voltage() -> float: - """Calculate the CROCO voltage. + def tf_turn_croco_cable_space_properties( + t_conductor: float, dx_tf_turn_steel: float + ) -> CroCoCableSpaceGeometry: - Returns - ------- - float - The calculated CROCO voltage based on the quench model. - """ + dia_tf_turn_croco_cable = t_conductor / 3.0e0 - dx_tf_turn_steel * ( + 2.0e0 / 3.0e0 + ) + + # Area of the full cable circle in the turn + a_tf_turn_cable_space_no_void = ( + 9.0e0 / 4.0e0 * np.pi * dia_tf_turn_croco_cable**2 + ) + # Area of the full cable spac circle minus the central copper strand + a_tf_turn_cable_space_effective = ( + a_tf_turn_cable_space_no_void - 0.25e0 * np.pi * dia_tf_turn_croco_cable**2 + ) + + conductor_area = t_conductor**2 # does this not assume it's a sqaure??? + + conductor_jacket_area = conductor_area - a_tf_turn_cable_space_no_void + a_tf_turn_steel = conductor_jacket_area + + conductor_jacket_fraction = conductor_jacket_area / conductor_area + + return CroCoCableSpaceGeometry( + dia_tf_turn_croco_cable=dia_tf_turn_croco_cable, + a_tf_turn_cable_space_no_void=a_tf_turn_cable_space_no_void, + a_tf_turn_cable_space_effective=a_tf_turn_cable_space_effective, + a_tf_turn_steel=a_tf_turn_steel, + conductor_area=conductor_area, + conductor_jacket_area=conductor_jacket_area, + conductor_jacket_fraction=conductor_jacket_fraction, + ) + + def croco_voltage(self) -> float: if tfcoil_variables.quench_model == "linear": superconducting_tf_coil_variables.time2 = ( tfcoil_variables.t_tf_superconductor_quench @@ -3893,14 +3949,6 @@ def croco_voltage() -> float: return croco_voltage def output_croco_info(self): - total = ( - superconducting_tf_coil_variables.conductor_copper_area - + superconducting_tf_coil_variables.conductor_hastelloy_area - + superconducting_tf_coil_variables.conductor_solder_area - + superconducting_tf_coil_variables.conductor_jacket_area - + superconducting_tf_coil_variables.conductor_helium_area - + superconducting_tf_coil_variables.conductor_rebco_area - ) po.oheadr(self.outfile, "Superconducting TF Coils") po.ovarin(self.outfile, "Superconductor switch", "(isumat)", 6) @@ -4117,15 +4165,15 @@ def output_croco_info(self): superconducting_tf_coil_variables.conductor_helium_area, "OP ", ) - if abs(total - superconducting_tf_coil_variables.conductor_area) > 1e-8: - po.ovarre( - self.outfile, - "ERROR: conductor areas do not add up:", - "(total)", - total, - "OP ", - ) - logger.error(f"conductor areas do not add up. total: {total}") + # if abs(total - superconducting_tf_coil_variables.conductor_area) > 1e-8: + # po.ovarre( + # self.outfile, + # "ERROR: conductor areas do not add up:", + # "(total)", + # total, + # "OP ", + # ) + # logger.error(f"conductor areas do not add up. total: {total}") po.ovarre( self.outfile, From 134c0252f88dbe743be5a5717021e37485126ef1 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Thu, 14 May 2026 13:59:46 +0100 Subject: [PATCH 23/37] Add TFSuperconductorLimits dataclass and refactor superconductor properties handling in CICCSuperconductingTFCoil --- process/models/tfcoil/superconducting.py | 94 +++++++++++++----------- 1 file changed, 51 insertions(+), 43 deletions(-) diff --git a/process/models/tfcoil/superconducting.py b/process/models/tfcoil/superconducting.py index 84fab1e95..eab067487 100644 --- a/process/models/tfcoil/superconducting.py +++ b/process/models/tfcoil/superconducting.py @@ -99,6 +99,18 @@ class TFWPGeometry: a_tf_wp_ground_insulation: float +@dataclass +class TFSuperconductorLimits: + j_tf_wp_critical: float + j_superconductor_critical: float + f_c_tf_turn_operating_critical: float + j_superconductor: float + j_tf_coil_turn: float + bc20m: float + tc0m: float + c_turn_cables_critical: float + + class SuperconductingTFCoil(TFCoil): """Class for superconducting TF coil model, inheriting from the base TFCoil class. @@ -1988,16 +2000,7 @@ def run(self, output: bool = False): * tfcoil_variables.n_tf_coil_turns ) - ( - tfcoil_variables.j_tf_wp_critical, - superconducting_tf_coil_variables.j_tf_superconductor_critical, - superconducting_tf_coil_variables.f_c_tf_turn_operating_critical, - superconducting_tf_coil_variables.j_tf_superconductor, - superconducting_tf_coil_variables.j_tf_coil_turn, - superconducting_tf_coil_variables.b_tf_superconductor_critical_zero_temp_strain, - superconducting_tf_coil_variables.temp_tf_superconductor_critical_zero_field_strain, - superconducting_tf_coil_variables.c_tf_turn_cables_critical, - ) = self.tf_cable_in_conduit_superconductor_properties( + critical_superconductor_info: TFSuperconductorLimits = self.tf_cable_in_conduit_superconductor_properties( a_tf_turn_cable_space=tfcoil_variables.a_tf_turn_cable_space_no_void, a_tf_turn=a_tf_turn, a_tf_turn_cable_space_effective=superconducting_tf_coil_variables.a_tf_turn_cable_space_effective, @@ -2013,6 +2016,25 @@ def run(self, output: bool = False): tcritsc=tfcoil_variables.tcritsc, ) + tfcoil_variables.j_tf_wp_critical = critical_superconductor_info.j_tf_wp_critical + superconducting_tf_coil_variables.j_tf_superconductor_critical = ( + critical_superconductor_info.j_superconductor_critical + ) + superconducting_tf_coil_variables.f_c_tf_turn_operating_critical = ( + critical_superconductor_info.f_c_tf_turn_operating_critical + ) + superconducting_tf_coil_variables.j_tf_superconductor = ( + critical_superconductor_info.j_superconductor + ) + superconducting_tf_coil_variables.j_tf_coil_turn = ( + critical_superconductor_info.j_tf_coil_turn + ) + superconducting_tf_coil_variables.b_tf_superconductor_critical_zero_temp_strain = critical_superconductor_info.bc20m + superconducting_tf_coil_variables.temp_tf_superconductor_critical_zero_field_strain = critical_superconductor_info.tc0m + superconducting_tf_coil_variables.c_tf_turn_cables_critical = ( + critical_superconductor_info.c_tf_turn_cables_critical + ) + if tfcoil_variables.i_str_wp == 0: strain = tfcoil_variables.str_tf_con_res else: @@ -2082,7 +2104,7 @@ def tf_cable_in_conduit_superconductor_properties( temp_tf_coolant_peak_field: float, bcritsc: float, tcritsc: float, - ) -> tuple[float, float, float, float, float, float, float, float]: + ) -> TFSuperconductorLimits: """Calculates the properties of the TF superconducting conductor. Parameters @@ -2127,29 +2149,15 @@ def tf_cable_in_conduit_superconductor_properties( Returns ------- - type - tuple (float, float, float, float, float, float, float, float, float) - - j_tf_wp_critical (float): Critical winding pack current density (A/m²). - - j_superconductor_critical (float): Critical current density in - superconductor (A/m²). - - f_c_tf_turn_operating_critical (float): Ratio of - operating / critical current. - - j_superconductor_turn (float): Actual current density in - superconductor (A/m²). - - j_tf_coil_turn (float): Actual current density in superconductor (A/m²). - - b_tf_superconductor_critical_zero_temp_strain (float): Critical field at - zero temperature and strain (T). - - temp_tf_superconductor_critical_zero_field_strain (float): Critical - temperature at zero field and strain (K). - - c_tf_turn_cables_critical (float): Critical current in cable (A). - - Raises - ------ - ProcessValueError - If an invalid superconductor type is selected, including when - ``i_tf_superconductor`` is not a valid ``SuperconductorModel`` - enum value. - + TFSuperconductorLimits + - j_tf_wp_critical (float): Critical winding pack current density (A/m²). + - j_superconductor_critical (float): Critical current density in superconductor (A/m²). + - f_c_tf_turn_operating_critical (float): Ratio of operating / critical current. + - j_superconductor_turn (float): Actual current density in superconductor (A/m²). + - j_tf_coil_turn (float): Actual current density in superconductor (A/m²). + - b_tf_superconductor_critical_zero_temp_strain (float): Critical field at zero temperature and strain (T). + - temp_tf_superconductor_critical_zero_field_strain (float): Critical temperature at zero field and strain (K). + - c_tf_turn_cables_critical (float): Critical current in cable (A). Notes ----- @@ -2518,15 +2526,15 @@ def tf_cable_in_conduit_superconductor_properties( """ ) - return ( - j_tf_wp_critical, - j_superconductor_critical, - f_c_tf_turn_operating_critical, - j_superconductor, - j_tf_coil_turn, - bc20m, - tc0m, - c_turn_cables_critical, + return TFSuperconductorLimits( + j_tf_wp_critical=j_tf_wp_critical, + j_superconductor_critical=j_superconductor_critical, + f_c_tf_turn_operating_critical=f_c_tf_turn_operating_critical, + j_superconductor=j_superconductor, + j_tf_coil_turn=j_tf_coil_turn, + bc20m=bc20m, + tc0m=tc0m, + c_turn_cables_critical=c_turn_cables_critical, ) @staticmethod From b46509eaf812a1e7c920ea11ca54206511b48871 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Thu, 14 May 2026 14:16:52 +0100 Subject: [PATCH 24/37] Refactor CroCo cable geometry calculations and remove deprecated croco function --- process/models/superconductors.py | 95 ------------------ process/models/tfcoil/superconducting.py | 121 ++++++++++++----------- 2 files changed, 61 insertions(+), 155 deletions(-) diff --git a/process/models/superconductors.py b/process/models/superconductors.py index 9aa8baa69..7b6252d57 100644 --- a/process/models/superconductors.py +++ b/process/models/superconductors.py @@ -1131,101 +1131,6 @@ def calculate_croco_cable_geometry( ) -def croco(j_crit_sc, conductor_area, dia_croco_strand, dx_croco_strand_copper): - """'CroCo' (cross-conductor) strand and cable design for - 'REBCO' 2nd generation HTS superconductor - Updated 13/11/18 using data from Lewandowska et al 2018. - - Parameters - ---------- - j_crit_sc : - - conductor_area : - - dia_croco_strand : - - dx_croco_strand_copper : - - """ - croco_cable_geometry: CroCoCableGeometry = calculate_croco_cable_geometry( - dia_croco_strand=dia_croco_strand, - dx_croco_strand_copper=dx_croco_strand_copper, - dx_hts_tape_rebco=superconducting_tf_coil_variables.dx_tf_hts_tape_rebco, - dx_hts_tape_copper=superconducting_tf_coil_variables.dx_tf_hts_tape_copper, - dx_hts_tape_hastelloy=superconducting_tf_coil_variables.dx_tf_hts_tape_hastelloy, - ) - - superconducting_tf_coil_variables.dia_tf_croco_strand_tape_region = ( - croco_cable_geometry.dia_croco_strand_tape_region - ) - superconducting_tf_coil_variables.n_tf_croco_strand_hts_tapes = ( - croco_cable_geometry.n_croco_strand_hts_tapes - ) - a_croco_strand_copper_total = croco_cable_geometry.a_croco_strand_copper_total - a_croco_strand_hastelloy = croco_cable_geometry.a_croco_strand_hastelloy - a_croco_strand_solder = croco_cable_geometry.a_croco_strand_solder - a_croco_strand_rebco = croco_cable_geometry.a_croco_strand_rebco - a_croco_strand = croco_cable_geometry.a_croco_strand - superconducting_tf_coil_variables.dr_tf_hts_tape = croco_cable_geometry.dr_hts_tape - superconducting_tf_coil_variables.dx_tf_croco_strand_tape_stack = ( - croco_cable_geometry.dx_croco_strand_tape_stack - ) - - superconducting_tf_coil_variables.a_croco_strand_copper_total = ( - a_croco_strand_copper_total - ) - superconducting_tf_coil_variables.a_tf_croco_strand_hastelloy = ( - a_croco_strand_hastelloy - ) - superconducting_tf_coil_variables.a_tf_croco_strand_solder = a_croco_strand_solder - superconducting_tf_coil_variables.a_tf_croco_strand_rebco = a_croco_strand_rebco - superconducting_tf_coil_variables.a_tf_croco_strand = a_croco_strand - - croco_strand_critical_current = j_crit_sc * a_croco_strand_rebco - - # Conductor properties - # conductor%number_croco = conductor%acs*(1.0-cable_helium_fraction-copper_bar) - # /a_croco_strand - conductor_critical_current = croco_strand_critical_current * N_CROCO_STRANDS_TURN - # Area of core = area of strand - conductor_copper_bar_area = a_croco_strand - conductor_copper_area = ( - a_croco_strand_copper_total * N_CROCO_STRANDS_TURN + conductor_copper_bar_area - ) - conductor_copper_fraction = conductor_copper_area / conductor_area - - # Helium area is set by the user. - # conductor_helium_area = cable_helium_fraction * tfcoil_variables.a_tf_turn_cable_space_no_void - conductor_helium_area = np.pi / 2.0 * dia_croco_strand**2 - conductor_helium_fraction = conductor_helium_area / conductor_area - - conductor_hastelloy_area = a_croco_strand_hastelloy * N_CROCO_STRANDS_TURN - conductor_hastelloy_fraction = conductor_hastelloy_area / conductor_area - - conductor_solder_area = a_croco_strand_solder * N_CROCO_STRANDS_TURN - conductor_solder_fraction = conductor_solder_area / conductor_area - - conductor_rebco_area = a_croco_strand_rebco * N_CROCO_STRANDS_TURN - conductor_rebco_fraction = conductor_rebco_area / conductor_area - - return ( - a_croco_strand, - croco_strand_critical_current, - conductor_copper_area, - conductor_copper_fraction, - conductor_copper_bar_area, - conductor_hastelloy_area, - conductor_hastelloy_fraction, - conductor_helium_area, - conductor_helium_fraction, - conductor_solder_area, - conductor_solder_fraction, - conductor_rebco_area, - conductor_rebco_fraction, - conductor_critical_current, - ) - - def superconductor_current_density_margin( temp_superconductor: float, i_superconductor_type: int, diff --git a/process/models/tfcoil/superconducting.py b/process/models/tfcoil/superconducting.py index eab067487..2672fed41 100644 --- a/process/models/tfcoil/superconducting.py +++ b/process/models/tfcoil/superconducting.py @@ -3219,11 +3219,21 @@ def run(self, output: bool = False): superconducting_tf_coil_variables.n_tf_croco_strand_hts_tapes = ( croco_cable_geometry.n_croco_strand_hts_tapes ) - a_tf_croco_strand_copper_total = croco_cable_geometry.a_croco_strand_copper_total - a_tf_croco_strand_hastelloy = croco_cable_geometry.a_croco_strand_hastelloy - a_tf_croco_strand_solder = croco_cable_geometry.a_croco_strand_solder - a_tf_croco_strand_rebco = croco_cable_geometry.a_croco_strand_rebco - a_tf_croco_strand = croco_cable_geometry.a_croco_strand + superconducting_tf_coil_variables.a_tf_croco_strand_copper_total = ( + croco_cable_geometry.a_croco_strand_copper_total + ) + superconducting_tf_coil_variables.a_tf_croco_strand_hastelloy = ( + croco_cable_geometry.a_croco_strand_hastelloy + ) + superconducting_tf_coil_variables.a_tf_croco_strand_solder = ( + croco_cable_geometry.a_croco_strand_solder + ) + superconducting_tf_coil_variables.a_tf_croco_strand_rebco = ( + croco_cable_geometry.a_croco_strand_rebco + ) + superconducting_tf_coil_variables.a_tf_croco_strand = ( + croco_cable_geometry.a_croco_strand + ) superconducting_tf_coil_variables.dr_tf_hts_tape = ( croco_cable_geometry.dr_hts_tape ) @@ -3232,75 +3242,85 @@ def run(self, output: bool = False): ) superconducting_tf_coil_variables.a_tf_croco_strand_copper_total = ( - a_tf_croco_strand_copper_total + superconducting_tf_coil_variables.a_tf_croco_strand_copper_total ) superconducting_tf_coil_variables.a_tf_croco_strand_hastelloy = ( - a_tf_croco_strand_hastelloy + superconducting_tf_coil_variables.a_tf_croco_strand_hastelloy ) superconducting_tf_coil_variables.a_tf_croco_strand_solder = ( - a_tf_croco_strand_solder + superconducting_tf_coil_variables.a_tf_croco_strand_solder ) superconducting_tf_coil_variables.a_tf_croco_strand_rebco = ( - a_tf_croco_strand_rebco + superconducting_tf_coil_variables.a_tf_croco_strand_rebco + ) + superconducting_tf_coil_variables.a_tf_croco_strand = ( + superconducting_tf_coil_variables.a_tf_croco_strand ) - superconducting_tf_coil_variables.a_tf_croco_strand = a_tf_croco_strand j_crit_sc, _ = superconductors.jcrit_rebco( temp_conductor=tfcoil_variables.tftmp, b_conductor=tfcoil_variables.b_tf_inboard_peak_with_ripple, ) - croco_strand_critical_current = ( + superconducting_tf_coil_variables.croco_strand_critical_current = ( j_crit_sc * superconducting_tf_coil_variables.a_tf_croco_strand ) # Conductor properties # conductor%number_croco = conductor%acs*(1.0-cable_helium_fraction-copper_bar)/a_croco_strand superconducting_tf_coil_variables.conductor_critical_current = ( - croco_strand_critical_current * N_CROCO_STRANDS_TURN + superconducting_tf_coil_variables.croco_strand_critical_current + * N_CROCO_STRANDS_TURN ) # Area of core = area of strand - conductor_copper_bar_area = superconducting_tf_coil_variables.a_tf_croco_strand - conductor_copper_area = ( + superconducting_tf_coil_variables.conductor_copper_bar_area = ( + superconducting_tf_coil_variables.a_tf_croco_strand + ) + superconducting_tf_coil_variables.conductor_copper_area = ( superconducting_tf_coil_variables.a_tf_croco_strand_copper_total * N_CROCO_STRANDS_TURN - + conductor_copper_bar_area + + superconducting_tf_coil_variables.conductor_copper_bar_area ) superconducting_tf_coil_variables.conductor_copper_fraction = ( - conductor_copper_area / superconducting_tf_coil_variables.conductor_area + superconducting_tf_coil_variables.conductor_copper_area + / superconducting_tf_coil_variables.conductor_area ) # Helium area is set by the user. # conductor_helium_area = cable_helium_fraction * tfcoil_variables.a_tf_turn_cable_space_no_void - conductor_helium_area = ( + superconducting_tf_coil_variables.conductor_helium_area = ( np.pi / 2.0 * superconducting_tf_coil_variables.dia_tf_turn_croco_cable**2 ) superconducting_tf_coil_variables.conductor_helium_fraction = ( - conductor_helium_area / superconducting_tf_coil_variables.conductor_area + superconducting_tf_coil_variables.conductor_helium_area + / superconducting_tf_coil_variables.conductor_area ) - conductor_hastelloy_area = ( + superconducting_tf_coil_variables.conductor_hastelloy_area = ( superconducting_tf_coil_variables.a_tf_croco_strand_hastelloy * N_CROCO_STRANDS_TURN ) superconducting_tf_coil_variables.conductor_hastelloy_fraction = ( - conductor_hastelloy_area / superconducting_tf_coil_variables.conductor_area + superconducting_tf_coil_variables.conductor_hastelloy_area + / superconducting_tf_coil_variables.conductor_area ) - conductor_solder_area = ( + superconducting_tf_coil_variables.conductor_solder_area = ( superconducting_tf_coil_variables.a_tf_croco_strand_solder * N_CROCO_STRANDS_TURN ) superconducting_tf_coil_variables.conductor_solder_fraction = ( - conductor_solder_area / superconducting_tf_coil_variables.conductor_area + superconducting_tf_coil_variables.conductor_solder_area + / superconducting_tf_coil_variables.conductor_area ) - conductor_rebco_area = ( + superconducting_tf_coil_variables.conductor_rebco_area = ( superconducting_tf_coil_variables.a_tf_croco_strand_rebco * N_CROCO_STRANDS_TURN ) superconducting_tf_coil_variables.conductor_rebco_fraction = ( - conductor_rebco_area / superconducting_tf_coil_variables.conductor_area + superconducting_tf_coil_variables.conductor_rebco_area + / superconducting_tf_coil_variables.conductor_area ) # Negative areas or fractions error reporting @@ -3738,7 +3758,12 @@ def tf_croco_averaged_turn_geometry( ) def tf_croco_superconductor_properties( - self, a_tf_turn, b_tf_inboard_peak_symmetric, iop, thelium, output: bool + self, + a_tf_turn: float, + b_tf_inboard_peak: float, + cur_tf_turn: float, + temp_tf_peak: float, + output: bool, ): """TF superconducting CroCo conductor using REBCO tape @@ -3746,43 +3771,21 @@ def tf_croco_superconductor_properties( ---------- a_tf_turn : - b_tf_inboard_peak_symmetric : + b_tf_inboard_peak : Peak field at conductor (T) - iop : + cur_tf_turn : Operating current per turn (A) - thelium : + temp_tf_peak : He temperature at peak field point (K) output: """ j_crit_sc: float = 0.0 # Find critical current density in superconducting cable, j_crit_cable - j_crit_sc, _ = superconductors.jcrit_rebco(thelium, b_tf_inboard_peak_symmetric) - - ( - superconducting_tf_coil_variables.a_tf_croco_strand, - superconducting_tf_coil_variables.croco_strand_critical_current, - superconducting_tf_coil_variables.conductor_copper_area, - superconducting_tf_coil_variables.conductor_copper_fraction, - superconducting_tf_coil_variables.conductor_copper_bar_area, - superconducting_tf_coil_variables.conductor_hastelloy_area, - superconducting_tf_coil_variables.conductor_hastelloy_fraction, - superconducting_tf_coil_variables.conductor_helium_area, - superconducting_tf_coil_variables.conductor_helium_fraction, - superconducting_tf_coil_variables.conductor_solder_area, - superconducting_tf_coil_variables.conductor_solder_fraction, - superconducting_tf_coil_variables.conductor_rebco_area, - superconducting_tf_coil_variables.conductor_rebco_fraction, - superconducting_tf_coil_variables.conductor_critical_current, - ) = superconductors.croco( - j_crit_sc, - superconducting_tf_coil_variables.conductor_area, - superconducting_tf_coil_variables.dia_tf_turn_croco_cable, - superconducting_tf_coil_variables.dx_tf_croco_strand_copper, - ) + j_crit_sc, _ = superconductors.jcrit_rebco(temp_tf_peak, b_tf_inboard_peak) superconducting_tf_coil_variables.tf_coppera_m2 = ( - iop / superconducting_tf_coil_variables.conductor_copper_area + cur_tf_turn / superconducting_tf_coil_variables.conductor_copper_area ) icrit = superconducting_tf_coil_variables.conductor_critical_current @@ -3795,9 +3798,9 @@ def tf_croco_superconductor_properties( # a_tf_turn : Area per turn (i.e. entire jacketed conductor with insulation) (m2) j_tf_wp_critical = icrit / a_tf_turn # Ratio of operating / critical current - iooic = iop / icrit + iooic = cur_tf_turn / icrit # Operating current density - jwdgop = iop / a_tf_turn + jwdgop = cur_tf_turn / a_tf_turn # Actual current density in superconductor, # which should be equal to jcrit(thelium+tmarg) @@ -3805,10 +3808,8 @@ def tf_croco_superconductor_properties( jsc = iooic * j_crit_sc # Temperature margin - current_sharing_t = superconductors.current_sharing_rebco( - b_tf_inboard_peak_symmetric, jsc - ) - tmarg = current_sharing_t - thelium + current_sharing_t = superconductors.current_sharing_rebco(b_tf_inboard_peak, jsc) + tmarg = current_sharing_t - temp_tf_peak tfcoil_variables.temp_margin = ( tmarg # Only used in the availabilty routine - see comment to Issue #526 ) @@ -3818,8 +3819,8 @@ def tf_croco_superconductor_properties( po.ovarre( self.outfile, "Helium temperature at peak field (= superconductor temperature) (K)", - "(thelium)", - thelium, + "(temp_tf_peak)", + temp_tf_peak, ) po.ovarre( self.outfile, From 0b52bb08d911ba5c26a1b3d8eb9937db6fc5b294 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Thu, 14 May 2026 15:52:04 +0100 Subject: [PATCH 25/37] Refactor jcrit_rebco function to return additional critical properties and update related calculations in superconductor models --- .../2nd_gen_rebco_critical_surface.py | 2 + process/models/pfcoil.py | 2 +- process/models/stellarator/coils/coils.py | 2 +- process/models/superconductors.py | 12 +- process/models/tfcoil/superconducting.py | 138 ++++++++++-------- 5 files changed, 93 insertions(+), 63 deletions(-) diff --git a/documentation/scripts/plotting_scripts/2nd_gen_rebco_critical_surface.py b/documentation/scripts/plotting_scripts/2nd_gen_rebco_critical_surface.py index 55526eb29..2dbf0281a 100644 --- a/documentation/scripts/plotting_scripts/2nd_gen_rebco_critical_surface.py +++ b/documentation/scripts/plotting_scripts/2nd_gen_rebco_critical_surface.py @@ -22,6 +22,8 @@ ( j_scaling[i, j], _, + _, + _, ) = superconductors.jcrit_rebco(temp_grid[i, j], b_grid[i, j]) # Convert from A/m² to kA/mm² (1 A/m² = 1e-6 A/mm²) j_scaling[i, j] *= 1e-9 diff --git a/process/models/pfcoil.py b/process/models/pfcoil.py index c049f0f85..2bf3130c0 100644 --- a/process/models/pfcoil.py +++ b/process/models/pfcoil.py @@ -4193,7 +4193,7 @@ def superconpf(bmax, fhe, fcu, jwp, isumat, fhts, strain, thelium, bcritsc, tcri elif isumat == 6: # "REBCO" 2nd generation HTS superconductor in CrCo strand - j_crit_sc, _ = superconductors.jcrit_rebco(thelium, bmax) + j_crit_sc, _, _, _ = superconductors.jcrit_rebco(thelium, bmax) # j_crit_cable = j_crit_sc * non-copper fraction of conductor * conductor fraction of cable j_crit_cable = j_crit_sc * (1.0e0 - fcu) * (1.0e0 - fhe) diff --git a/process/models/stellarator/coils/coils.py b/process/models/stellarator/coils/coils.py index 1fe177c6a..fa18632b5 100644 --- a/process/models/stellarator/coils/coils.py +++ b/process/models/stellarator/coils/coils.py @@ -120,7 +120,7 @@ def jcrit_from_material( # j_crit_cable = j_crit_sc * non-copper fraction of conductor * conductor fraction of cable j_crit_cable = j_crit_sc * (1 - f_tf_conductor_copper) * (1 - f_he) elif i_tf_sc_mat == 6: # ! "REBCO" 2nd generation HTS superconductor in CrCo strand - j_crit_sc, _validity = superconductors.jcrit_rebco(t_helium, b_max, 0) + j_crit_sc, _validity, _, _ = superconductors.jcrit_rebco(t_helium, b_max, 0) j_crit_sc = max(1.0e-9, j_crit_sc) # j_crit_cable = j_crit_sc * non-copper fraction of conductor * conductor fraction of cable j_crit_cable = j_crit_sc * (1 - f_tf_conductor_copper) * (1 - f_he) diff --git a/process/models/superconductors.py b/process/models/superconductors.py index 7b6252d57..a191b2248 100644 --- a/process/models/superconductors.py +++ b/process/models/superconductors.py @@ -118,7 +118,9 @@ def full_name(self): return self._full_name_ -def jcrit_rebco(temp_conductor: float, b_conductor: float) -> tuple[float, bool]: +def jcrit_rebco( + temp_conductor: float, b_conductor: float +) -> tuple[float, bool, float, float]: """Calculate the critical current density for a "REBCO" 2nd generation HTS superconductor. @@ -131,11 +133,13 @@ def jcrit_rebco(temp_conductor: float, b_conductor: float) -> tuple[float, bool] Returns ------- - tuple[float, bool] + tuple[float, bool, float, float] A tuple containing: - j_critical: Critical current density in the superconductor (A/m²). - validity: A boolean indicating whether the input parameters are within the valid range. + - b_c20max: Upper critical field (T) for the superconductor at zero temperature and strain. + - temp_c0max: Critical temperature (K) at zero field and strain. Notes ----- @@ -196,7 +200,7 @@ def jcrit_rebco(temp_conductor: float, b_conductor: float) -> tuple[float, bool] tcb = temp_c0max * (1 - (b_conductor / b_c20max) ** oneoveralpha) j_critical = -(temp_conductor - tcb) - return j_critical, validity + return j_critical, validity, b_c20max, temp_c0max def current_sharing_rebco(bfield, j): @@ -216,7 +220,7 @@ def current_sharing_rebco(bfield, j): """ def deltaj_rebco(temperature): - jcritical, _ = jcrit_rebco(temperature, bfield) + jcritical, _, _, _ = jcrit_rebco(temperature, bfield) return jcritical - j # No additional arguments are required for deltaj_rebco since it only has one diff --git a/process/models/tfcoil/superconducting.py b/process/models/tfcoil/superconducting.py index 2672fed41..d57aa053f 100644 --- a/process/models/tfcoil/superconducting.py +++ b/process/models/tfcoil/superconducting.py @@ -1617,10 +1617,8 @@ def run(self, output: bool = False): # Setting the WP turn geometry / areas if tfcoil_variables.i_tf_turns_integer == 0: - avg_turn_geometry = CICCAveragedTurnGeometry - # Non-ingeger number of turns - avg_turn_geometry = self.tf_cable_in_conduit_averaged_turn_geometry( + avg_turn_geometry: CICCAveragedTurnGeometry = self.tf_cable_in_conduit_averaged_turn_geometry( j_tf_wp=tfcoil_variables.j_tf_wp, dx_tf_turn_steel=tfcoil_variables.dx_tf_turn_steel, dx_tf_turn_insulation=tfcoil_variables.dx_tf_turn_insulation, @@ -3257,21 +3255,6 @@ def run(self, output: bool = False): superconducting_tf_coil_variables.a_tf_croco_strand ) - j_crit_sc, _ = superconductors.jcrit_rebco( - temp_conductor=tfcoil_variables.tftmp, - b_conductor=tfcoil_variables.b_tf_inboard_peak_with_ripple, - ) - - superconducting_tf_coil_variables.croco_strand_critical_current = ( - j_crit_sc * superconducting_tf_coil_variables.a_tf_croco_strand - ) - - # Conductor properties - # conductor%number_croco = conductor%acs*(1.0-cable_helium_fraction-copper_bar)/a_croco_strand - superconducting_tf_coil_variables.conductor_critical_current = ( - superconducting_tf_coil_variables.croco_strand_critical_current - * N_CROCO_STRANDS_TURN - ) # Area of core = area of strand superconducting_tf_coil_variables.conductor_copper_bar_area = ( superconducting_tf_coil_variables.a_tf_croco_strand @@ -3323,6 +3306,57 @@ def run(self, output: bool = False): / superconducting_tf_coil_variables.conductor_area ) + # Cross-sectional area per turn + a_tf_turn = tfcoil_variables.c_tf_total / ( + tfcoil_variables.j_tf_wp + * tfcoil_variables.n_tf_coils + * tfcoil_variables.n_tf_coil_turns + ) + + if ( + SuperconductorModel(tfcoil_variables.i_tf_sc_mat) + == SuperconductorModel.CROCO_REBCO + ): + superconductor_critical_properties: TFSuperconductorLimits = ( + self.tf_croco_superconductor_properties( + a_tf_turn=a_tf_turn, + b_tf_inboard_peak=tfcoil_variables.b_tf_inboard_peak_with_ripple, + cur_tf_turn=tfcoil_variables.c_tf_turn, + temp_tf_peak=tfcoil_variables.tftmp, + i_tf_superconductor=tfcoil_variables.i_tf_sc_mat, + output=output, + ) + ) + + tfcoil_variables.j_tf_wp_critical = ( + superconductor_critical_properties.j_tf_wp_critical + ) + j_superconductor_critical = ( + superconductor_critical_properties.j_superconductor_critical + ) + superconducting_tf_coil_variables.f_c_tf_turn_operating_critical = ( + superconductor_critical_properties.f_c_tf_turn_operating_critical + ) + j_superconductor = superconductor_critical_properties.j_superconductor + superconducting_tf_coil_variables.j_tf_coil_turn = ( + superconductor_critical_properties.j_tf_coil_turn + ) + + superconducting_tf_coil_variables.b_tf_superconductor_critical_zero_temp_strain = superconductor_critical_properties.bc20m + superconducting_tf_coil_variables.temp_tf_superconductor_critical_zero_field_strain = superconductor_critical_properties.tc0m + superconducting_tf_coil_variables.c_tf_turn_cables_critical = ( + superconductor_critical_properties.c_turn_cables_critical + ) + + tfcoil_variables.v_tf_coil_dump_quench_kv = ( + self.croco_voltage() / 1.0e3 + ) # TFC Quench voltage in kV + + if tfcoil_variables.i_str_wp == 0: + strain = tfcoil_variables.str_tf_con_res + else: + strain = tfcoil_variables.str_wp + # Negative areas or fractions error reporting if ( tfcoil_variables.a_tf_wp_conductor <= 0.0e0 @@ -3529,37 +3563,6 @@ def run(self, output: bool = False): self.vv_stress_on_quench() - # Cross-sectional area per turn - a_tf_turn = tfcoil_variables.c_tf_total / ( - tfcoil_variables.j_tf_wp - * tfcoil_variables.n_tf_coils - * tfcoil_variables.n_tf_coil_turns - ) - - if ( - SuperconductorModel(tfcoil_variables.i_tf_sc_mat) - == SuperconductorModel.CROCO_REBCO - ): - ( - tfcoil_variables.j_tf_wp_critical, - tfcoil_variables.temp_tf_superconductor_margin, - ) = self.tf_croco_superconductor_properties( - a_tf_turn, - tfcoil_variables.b_tf_inboard_peak_with_ripple, - tfcoil_variables.c_tf_turn, - tfcoil_variables.tftmp, - output=output, - ) - - tfcoil_variables.v_tf_coil_dump_quench_kv = ( - self.croco_voltage() / 1.0e3 - ) # TFC Quench voltage in kV - - if tfcoil_variables.i_str_wp == 0: - strain = tfcoil_variables.str_tf_con_res - else: - strain = tfcoil_variables.str_wp - # tfcoil_variables.temp_tf_superconductor_margin = self.calculate_superconductor_temperature_margin( # i_tf_superconductor=tfcoil_variables.i_tf_sc_mat, # j_superconductor=superconducting_tf_coil_variables.j_tf_superconductor, @@ -3763,8 +3766,9 @@ def tf_croco_superconductor_properties( b_tf_inboard_peak: float, cur_tf_turn: float, temp_tf_peak: float, + i_tf_superconductor: int, output: bool, - ): + ) -> TFSuperconductorLimits: """TF superconducting CroCo conductor using REBCO tape Parameters @@ -3780,15 +3784,27 @@ def tf_croco_superconductor_properties( output: """ - j_crit_sc: float = 0.0 # Find critical current density in superconducting cable, j_crit_cable - j_crit_sc, _ = superconductors.jcrit_rebco(temp_tf_peak, b_tf_inboard_peak) + j_crit_sc, _, bc20m, tc0m = superconductors.jcrit_rebco( + temp_conductor=temp_tf_peak, b_conductor=b_tf_inboard_peak + ) + + superconducting_tf_coil_variables.croco_strand_critical_current = ( + j_crit_sc * superconducting_tf_coil_variables.a_tf_croco_strand + ) + + # Conductor properties + # conductor%number_croco = conductor%acs*(1.0-cable_helium_fraction-copper_bar)/a_croco_strand + superconducting_tf_coil_variables.conductor_critical_current = ( + superconducting_tf_coil_variables.croco_strand_critical_current + * N_CROCO_STRANDS_TURN + ) superconducting_tf_coil_variables.tf_coppera_m2 = ( cur_tf_turn / superconducting_tf_coil_variables.conductor_copper_area ) - icrit = superconducting_tf_coil_variables.conductor_critical_current + cur_critical = superconducting_tf_coil_variables.conductor_critical_current j_crit_cable = ( superconducting_tf_coil_variables.croco_strand_critical_current / superconducting_tf_coil_variables.a_tf_croco_strand @@ -3796,9 +3812,9 @@ def tf_croco_superconductor_properties( # Critical current density in winding pack # a_tf_turn : Area per turn (i.e. entire jacketed conductor with insulation) (m2) - j_tf_wp_critical = icrit / a_tf_turn + j_tf_wp_critical = cur_critical / a_tf_turn # Ratio of operating / critical current - iooic = cur_tf_turn / icrit + iooic = cur_tf_turn / cur_critical # Operating current density jwdgop = cur_tf_turn / a_tf_turn # Actual current density in superconductor, @@ -3872,7 +3888,6 @@ def tf_croco_superconductor_properties( current_sharing_t, "OP ", ) - po.ovarre(self.outfile, "Critical current (A)", "(icrit)", icrit, "OP ") po.ovarre( self.outfile, "Actual current (A)", @@ -3888,7 +3903,16 @@ def tf_croco_superconductor_properties( "OP ", ) - return j_tf_wp_critical, tmarg + return TFSuperconductorLimits( + j_tf_wp_critical=j_tf_wp_critical, + j_superconductor_critical=j_crit_sc, + f_c_tf_turn_operating_critical=iooic, + j_superconductor=jsc, + j_tf_coil_turn=jwdgop, + bc20m=bc20m, + tc0m=tc0m, + c_turn_cables_critical=0.0, + ) @staticmethod def tf_turn_croco_cable_space_properties( From bd91570934c4ced80786876bd315aaf4fb6c3b3a Mon Sep 17 00:00:00 2001 From: mn3981 Date: Thu, 14 May 2026 16:17:00 +0100 Subject: [PATCH 26/37] Refactor CroCo copper bar area variable and update related calculations in CROCOSuperconductingTFCoil --- .../superconducting_tf_coil_variables.py | 3 +- process/models/tfcoil/superconducting.py | 46 ++----------------- 2 files changed, 6 insertions(+), 43 deletions(-) diff --git a/process/data_structure/superconducting_tf_coil_variables.py b/process/data_structure/superconducting_tf_coil_variables.py index fb75c09f6..7aa0129a1 100644 --- a/process/data_structure/superconducting_tf_coil_variables.py +++ b/process/data_structure/superconducting_tf_coil_variables.py @@ -291,7 +291,8 @@ conductor_copper_area: float = None conductor_copper_fraction: float = None -conductor_copper_bar_area: float = None +a_tf_turn_croco_copper_bar: float = None +"""Area of the central copper strand in the CroCo TF turn [m²]""" conductor_hastelloy_area: float = None conductor_hastelloy_fraction: float = None conductor_helium_area: float = None diff --git a/process/models/tfcoil/superconducting.py b/process/models/tfcoil/superconducting.py index d57aa053f..a1edde08f 100644 --- a/process/models/tfcoil/superconducting.py +++ b/process/models/tfcoil/superconducting.py @@ -1662,8 +1662,7 @@ def run(self, output: bool = False): else: # Integer number of turns - int_turn_geometry = CICCIntegerTurnGeometry - (int_turn_geometry) = self.tf_cable_in_conduit_integer_turn_geometry( + int_turn_geometry: CICCIntegerTurnGeometry = self.tf_cable_in_conduit_integer_turn_geometry( dr_tf_wp_with_insulation=tfcoil_variables.dr_tf_wp_with_insulation, dx_tf_wp_insulation=tfcoil_variables.dx_tf_wp_insulation, dx_tf_wp_insertion_gap=tfcoil_variables.dx_tf_wp_insertion_gap, @@ -3166,43 +3165,6 @@ def run(self, output: bool = False): croco_cable_space_geometry.conductor_jacket_fraction ) - # superconducting_tf_coil_variables.dia_tf_turn_croco_cable = ( - # tfcoil_variables.t_conductor / 3.0e0 - # - tfcoil_variables.dx_tf_turn_steel * (2.0e0 / 3.0e0) - # ) - - # # Area of the full cable circle in the turn - # tfcoil_variables.a_tf_turn_cable_space_no_void = ( - # 9.0e0 - # / 4.0e0 - # * np.pi - # * superconducting_tf_coil_variables.dia_tf_turn_croco_cable**2 - # ) - # # Area of the full cable spac circle minus the central copper strand - # superconducting_tf_coil_variables.a_tf_turn_cable_space_effective = ( - # tfcoil_variables.a_tf_turn_cable_space_no_void - # - 0.25e0 - # * np.pi - # * superconducting_tf_coil_variables.dia_tf_turn_croco_cable**2 - # ) - - # superconducting_tf_coil_variables.conductor_area = ( - # tfcoil_variables.t_conductor**2 - # ) # does this not assume it's a sqaure??? - - # superconducting_tf_coil_variables.conductor_jacket_area = ( - # superconducting_tf_coil_variables.conductor_area - # - tfcoil_variables.a_tf_turn_cable_space_no_void - # ) - # tfcoil_variables.a_tf_turn_steel = ( - # superconducting_tf_coil_variables.conductor_jacket_area - # ) - - # superconducting_tf_coil_variables.conductor_jacket_fraction = ( - # superconducting_tf_coil_variables.conductor_jacket_area - # / superconducting_tf_coil_variables.conductor_area - # ) - croco_cable_geometry: CroCoCableGeometry = calculate_croco_cable_geometry( dia_croco_strand=superconducting_tf_coil_variables.dia_tf_turn_croco_cable, dx_croco_strand_copper=superconducting_tf_coil_variables.dx_tf_croco_strand_copper, @@ -3256,13 +3218,13 @@ def run(self, output: bool = False): ) # Area of core = area of strand - superconducting_tf_coil_variables.conductor_copper_bar_area = ( + superconducting_tf_coil_variables.a_tf_turn_croco_copper_bar = ( superconducting_tf_coil_variables.a_tf_croco_strand ) superconducting_tf_coil_variables.conductor_copper_area = ( superconducting_tf_coil_variables.a_tf_croco_strand_copper_total * N_CROCO_STRANDS_TURN - + superconducting_tf_coil_variables.conductor_copper_bar_area + + superconducting_tf_coil_variables.a_tf_turn_croco_copper_bar ) superconducting_tf_coil_variables.conductor_copper_fraction = ( superconducting_tf_coil_variables.conductor_copper_area @@ -4160,7 +4122,7 @@ def output_croco_info(self): self.outfile, "Area of central copper bar (mm2)", "(copper_bar_area)", - superconducting_tf_coil_variables.conductor_copper_bar_area, + superconducting_tf_coil_variables.a_tf_turn_croco_copper_bar, "OP ", ) po.ovarre( From 2d004acd0d17df3d3f67d5911a8037e9fe37b54d Mon Sep 17 00:00:00 2001 From: mn3981 Date: Thu, 14 May 2026 16:19:41 +0100 Subject: [PATCH 27/37] Refactor CroCo strand critical current variable and update related calculations in CROCOSuperconductingTFCoil --- .../superconducting_tf_coil_variables.py | 7 ++++--- process/models/tfcoil/superconducting.py | 11 +++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/process/data_structure/superconducting_tf_coil_variables.py b/process/data_structure/superconducting_tf_coil_variables.py index 7aa0129a1..bb225e44f 100644 --- a/process/data_structure/superconducting_tf_coil_variables.py +++ b/process/data_structure/superconducting_tf_coil_variables.py @@ -284,7 +284,8 @@ # croco_strand tf_croco_strand_area: float = None -tf_croco_strand_critical_current: float = None +cur_tf_tun_croco_strand_critical: float = None +"""Critical current in the TF turn CroCo strand (A)""" # conductor @@ -401,7 +402,7 @@ def init_superconducting_tf_coil_variables(): a_tf_croco_strand_solder, \ a_tf_croco_strand, \ tf_croco_strand_area, \ - tf_croco_strand_critical_current + cur_tf_tun_croco_strand_critical is_leg_cp_temp_same = 0 tf_fit_t = 0.0 @@ -484,4 +485,4 @@ def init_superconducting_tf_coil_variables(): a_tf_croco_strand_solder = 0.0 a_tf_croco_strand = 0.0 tf_croco_strand_area = 0.0 - tf_croco_strand_critical_current = 0.0 + cur_tf_tun_croco_strand_critical = 0.0 diff --git a/process/models/tfcoil/superconducting.py b/process/models/tfcoil/superconducting.py index a1edde08f..39cd8a69d 100644 --- a/process/models/tfcoil/superconducting.py +++ b/process/models/tfcoil/superconducting.py @@ -3751,14 +3751,13 @@ def tf_croco_superconductor_properties( temp_conductor=temp_tf_peak, b_conductor=b_tf_inboard_peak ) - superconducting_tf_coil_variables.croco_strand_critical_current = ( + superconducting_tf_coil_variables.cur_tf_tun_croco_strand_critical = ( j_crit_sc * superconducting_tf_coil_variables.a_tf_croco_strand ) # Conductor properties - # conductor%number_croco = conductor%acs*(1.0-cable_helium_fraction-copper_bar)/a_croco_strand superconducting_tf_coil_variables.conductor_critical_current = ( - superconducting_tf_coil_variables.croco_strand_critical_current + superconducting_tf_coil_variables.cur_tf_tun_croco_strand_critical * N_CROCO_STRANDS_TURN ) @@ -3768,7 +3767,7 @@ def tf_croco_superconductor_properties( cur_critical = superconducting_tf_coil_variables.conductor_critical_current j_crit_cable = ( - superconducting_tf_coil_variables.croco_strand_critical_current + superconducting_tf_coil_variables.cur_tf_tun_croco_strand_critical / superconducting_tf_coil_variables.a_tf_croco_strand ) @@ -4173,8 +4172,8 @@ def output_croco_info(self): po.ovarre( self.outfile, "Critical current of CroCo strand (A)", - "(croco_strand_critical_current)", - superconducting_tf_coil_variables.croco_strand_critical_current, + "(cur_tf_tun_croco_strand_critical)", + superconducting_tf_coil_variables.cur_tf_tun_croco_strand_critical, "OP ", ) po.ovarre( From 89c4786268b0dd4449cb52fbc769fc8b6ef5f5f2 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Thu, 14 May 2026 16:47:00 +0100 Subject: [PATCH 28/37] Refactor CroCo copper area variables and update related calculations in CROCOSuperconductingTFCoil --- .../superconducting_tf_coil_variables.py | 52 +++++++++---------- process/models/tfcoil/superconducting.py | 19 +++---- 2 files changed, 36 insertions(+), 35 deletions(-) diff --git a/process/data_structure/superconducting_tf_coil_variables.py b/process/data_structure/superconducting_tf_coil_variables.py index bb225e44f..23e0ffb2b 100644 --- a/process/data_structure/superconducting_tf_coil_variables.py +++ b/process/data_structure/superconducting_tf_coil_variables.py @@ -27,22 +27,22 @@ a_tf_wp_with_insulation: float = None """Total cross-sectional area of winding pack including -GW insulation and insertion gap [m2] +GW insulation and insertion gap [m²] """ a_tf_wp_no_insulation: float = None """Total cross-sectional area of winding pack without -ground insulation and insertion gap [m2] +ground insulation and insertion gap [m²] """ a_tf_coil_inboard_steel: float = None -"""Inboard coil steel coil cross-sectional area [m2]""" +"""Inboard coil steel coil cross-sectional area [m²]""" a_tf_coil_inboard_insulation: float = None -"""Inboard coil insulation cross-section per coil [m2]""" +"""Inboard coil insulation cross-section per coil [m²]""" f_a_tf_coil_inboard_steel: float = None @@ -108,27 +108,27 @@ a_tf_plasma_case: float = None -"""Front casing area [m2]""" +"""Front casing area [m²]""" a_tf_coil_nose_case: float = None -"""Nose casing area [m2]""" +"""Nose casing area [m²]""" a_tf_wp_ground_insulation: float = None -"""Inboard mid-plane cross-section area of the WP ground insulation [m2]""" +"""Inboard mid-plane cross-section area of the WP ground insulation [m²]""" a_leg_ins: float = None -"""TF ouboard leg turn insulation area per coil [m2]""" +"""TF ouboard leg turn insulation area per coil [m²]""" a_leg_gr_ins: float = None -"""TF outboard leg ground insulation area per coil [m2]""" +"""TF outboard leg ground insulation area per coil [m²]""" a_leg_cond: float = None -"""Exact TF ouboard leg conductor area [m2]""" +"""Exact TF ouboard leg conductor area [m²]""" rad_tf_coil_inboard_toroidal_half: float = None @@ -172,7 +172,7 @@ a_tf_turn_cable_space_effective: float = None -"""True cable area of WP turn. This includes the removal of the cooling pipe [m^2] """ +"""True cable area of WP turn. This includes the removal of the cooling pipe [m²] """ vforce_inboard_tot: float = None """Total inboard vertical tension (all coils) [N]""" @@ -196,13 +196,13 @@ """Total length of superconducting cable in all TF coils [m]""" j_tf_superconductor_critical: float = None -"""Critical current density of the superconducting cable [A/m^2]""" +"""Critical current density of the superconducting cable [A/m²]""" f_c_tf_turn_operating_critical: float = None """Ratio of the TF operating current to the critical current""" j_tf_coil_turn: float = None -"""Current density in the TF coil turn [A/m^2]""" +"""Current density in the TF coil turn [A/m²]""" b_tf_superconductor_critical_zero_temp_strain: float = None """Critical magnetic field of the superconducting cable at zero temperature and strain [T]""" @@ -214,10 +214,10 @@ """Fraction of usable turn cable space area used for cooling""" c_tf_turn_cables_critical: float = None -"""Critical current density in the turn cables [A/m^2]""" +"""Critical current density in the turn cables [A/m²]""" j_tf_superconductor: float = None -"""Current density in the superconducting cable [A/m^2]""" +"""Current density in the superconducting cable [A/m²]""" i_tf_turn_type: int = None """Switch for TF turn geometry type""" @@ -254,10 +254,10 @@ """residual resistivity ratio copper in TF superconducting cable""" tf_coppera_m2: float = None -"""TF coil current / copper area (A/m2)""" +"""TF coil current / copper area (A/m²)""" tf_coppera_m2_max: float = None -"""Maximum TF coil current / copper area (A/m2)""" +"""Maximum TF coil current / copper area (A/m²)""" dx_tf_croco_strand_tape_stack: float = None """Width / thickness of tape stack in CroCo strand (m)""" @@ -266,31 +266,31 @@ """Number of HTS tapes in CroCo strand""" a_tf_croco_strand_rebco: float = None -"""Area of REBCO in CroCo strand (m2)""" +"""Area of REBCO in CroCo strand (m²)""" a_tf_croco_strand_copper_total: float = None -"""Area of copper in CroCo strand (includes tapes and outer tube) (m2)""" +"""Area of copper in CroCo strand (includes tapes and outer tube) (m²)""" a_tf_croco_strand_hastelloy: float = None -"""Area of Hastelloy in CroCo strand (m2)""" +"""Area of Hastelloy in CroCo strand (m²)""" a_tf_croco_strand_solder: float = None -"""Area of solder in CroCo strand (m2)""" +"""Area of solder in CroCo strand (m²)""" a_tf_croco_strand: float = None -"""Total area of a CroCo strand (m2)""" +"""Total area of a CroCo strand (m²)""" # croco_strand tf_croco_strand_area: float = None -cur_tf_tun_croco_strand_critical: float = None +cur_tf_turn_croco_strand_critical: float = None """Critical current in the TF turn CroCo strand (A)""" # conductor -conductor_copper_area: float = None +a_tf_turn_croco_cable_space_copper: float = None conductor_copper_fraction: float = None a_tf_turn_croco_copper_bar: float = None """Area of the central copper strand in the CroCo TF turn [m²]""" @@ -402,7 +402,7 @@ def init_superconducting_tf_coil_variables(): a_tf_croco_strand_solder, \ a_tf_croco_strand, \ tf_croco_strand_area, \ - cur_tf_tun_croco_strand_critical + cur_tf_turn_croco_strand_critical is_leg_cp_temp_same = 0 tf_fit_t = 0.0 @@ -485,4 +485,4 @@ def init_superconducting_tf_coil_variables(): a_tf_croco_strand_solder = 0.0 a_tf_croco_strand = 0.0 tf_croco_strand_area = 0.0 - cur_tf_tun_croco_strand_critical = 0.0 + cur_tf_turn_croco_strand_critical = 0.0 diff --git a/process/models/tfcoil/superconducting.py b/process/models/tfcoil/superconducting.py index 39cd8a69d..c412fdab9 100644 --- a/process/models/tfcoil/superconducting.py +++ b/process/models/tfcoil/superconducting.py @@ -3221,13 +3221,13 @@ def run(self, output: bool = False): superconducting_tf_coil_variables.a_tf_turn_croco_copper_bar = ( superconducting_tf_coil_variables.a_tf_croco_strand ) - superconducting_tf_coil_variables.conductor_copper_area = ( + superconducting_tf_coil_variables.a_tf_turn_croco_cable_space_copper = ( superconducting_tf_coil_variables.a_tf_croco_strand_copper_total * N_CROCO_STRANDS_TURN + superconducting_tf_coil_variables.a_tf_turn_croco_copper_bar ) superconducting_tf_coil_variables.conductor_copper_fraction = ( - superconducting_tf_coil_variables.conductor_copper_area + superconducting_tf_coil_variables.a_tf_turn_croco_cable_space_copper / superconducting_tf_coil_variables.conductor_area ) @@ -3751,23 +3751,24 @@ def tf_croco_superconductor_properties( temp_conductor=temp_tf_peak, b_conductor=b_tf_inboard_peak ) - superconducting_tf_coil_variables.cur_tf_tun_croco_strand_critical = ( + superconducting_tf_coil_variables.cur_tf_turn_croco_strand_critical = ( j_crit_sc * superconducting_tf_coil_variables.a_tf_croco_strand ) # Conductor properties superconducting_tf_coil_variables.conductor_critical_current = ( - superconducting_tf_coil_variables.cur_tf_tun_croco_strand_critical + superconducting_tf_coil_variables.cur_tf_turn_croco_strand_critical * N_CROCO_STRANDS_TURN ) superconducting_tf_coil_variables.tf_coppera_m2 = ( - cur_tf_turn / superconducting_tf_coil_variables.conductor_copper_area + cur_tf_turn + / superconducting_tf_coil_variables.a_tf_turn_croco_cable_space_copper ) cur_critical = superconducting_tf_coil_variables.conductor_critical_current j_crit_cable = ( - superconducting_tf_coil_variables.cur_tf_tun_croco_strand_critical + superconducting_tf_coil_variables.cur_tf_turn_croco_strand_critical / superconducting_tf_coil_variables.a_tf_croco_strand ) @@ -4128,7 +4129,7 @@ def output_croco_info(self): self.outfile, "Total copper area of conductor, total (mm2)", "(a_tf_croco_strand_copper_total)", - superconducting_tf_coil_variables.conductor_copper_area, + superconducting_tf_coil_variables.a_tf_turn_croco_cable_space_copper, "OP ", ) po.ovarre( @@ -4172,8 +4173,8 @@ def output_croco_info(self): po.ovarre( self.outfile, "Critical current of CroCo strand (A)", - "(cur_tf_tun_croco_strand_critical)", - superconducting_tf_coil_variables.cur_tf_tun_croco_strand_critical, + "(cur_tf_turn_croco_strand_critical)", + superconducting_tf_coil_variables.cur_tf_turn_croco_strand_critical, "OP ", ) po.ovarre( From edaf02e24b83071501641c81507abe917b8287b6 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Thu, 14 May 2026 16:48:19 +0100 Subject: [PATCH 29/37] Rename `conductor_hastelloy_area` to `a_tf_turn_croco_hastelloy` --- process/data_structure/superconducting_tf_coil_variables.py | 2 +- process/models/tfcoil/superconducting.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/process/data_structure/superconducting_tf_coil_variables.py b/process/data_structure/superconducting_tf_coil_variables.py index 23e0ffb2b..1fb615b47 100644 --- a/process/data_structure/superconducting_tf_coil_variables.py +++ b/process/data_structure/superconducting_tf_coil_variables.py @@ -294,7 +294,7 @@ conductor_copper_fraction: float = None a_tf_turn_croco_copper_bar: float = None """Area of the central copper strand in the CroCo TF turn [m²]""" -conductor_hastelloy_area: float = None +a_tf_turn_croco_hastelloy: float = None conductor_hastelloy_fraction: float = None conductor_helium_area: float = None conductor_helium_fraction: float = None diff --git a/process/models/tfcoil/superconducting.py b/process/models/tfcoil/superconducting.py index c412fdab9..ab7afba85 100644 --- a/process/models/tfcoil/superconducting.py +++ b/process/models/tfcoil/superconducting.py @@ -3241,12 +3241,12 @@ def run(self, output: bool = False): / superconducting_tf_coil_variables.conductor_area ) - superconducting_tf_coil_variables.conductor_hastelloy_area = ( + superconducting_tf_coil_variables.a_tf_turn_croco_hastelloy = ( superconducting_tf_coil_variables.a_tf_croco_strand_hastelloy * N_CROCO_STRANDS_TURN ) superconducting_tf_coil_variables.conductor_hastelloy_fraction = ( - superconducting_tf_coil_variables.conductor_hastelloy_area + superconducting_tf_coil_variables.a_tf_turn_croco_hastelloy / superconducting_tf_coil_variables.conductor_area ) @@ -4136,7 +4136,7 @@ def output_croco_info(self): self.outfile, "Hastelloy area of conductor (mm2)", "(a_tf_croco_strand_hastelloy)", - superconducting_tf_coil_variables.conductor_hastelloy_area, + superconducting_tf_coil_variables.a_tf_turn_croco_hastelloy, "OP ", ) po.ovarre( From a71773549a17d51d3eafb8bd45e731c122461ab4 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Thu, 14 May 2026 17:02:01 +0100 Subject: [PATCH 30/37] Refactor superconductor classes to add type hints and clean up unused temperature margin calculation in CICCSuperconductingTFCoil --- process/core/io/plot/summary.py | 5 ++++- process/models/tfcoil/superconducting.py | 11 ----------- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/process/core/io/plot/summary.py b/process/core/io/plot/summary.py index 3754a1f64..0439a9781 100644 --- a/process/core/io/plot/summary.py +++ b/process/core/io/plot/summary.py @@ -12582,6 +12582,7 @@ def plot_hts_tape_geometry( (dx_hts_tape_copper + dx_hts_tape_hastelloy + dx_hts_tape_rebco) * 1.1, ) axis.minorticks_on() + axis.ticklabel_format(style="sci", axis="both", scilimits=(0, 0)) if show_legend: axis.legend(loc="upper right") @@ -14895,8 +14896,10 @@ def main_plot( show_legend=True, ) plot_tf_corc_cable_summary_box(plot_205, figs[25], m_file, scan) + ax_hts_tape = figs[25].add_subplot(339) + ax_hts_tape.set_position([0.75, 0.1, 0.2, 0.2]) plot_hts_tape_geometry( - axis=figs[25].add_subplot(339), + axis=ax_hts_tape, r_left=0.0, z_bottom=0.0, dr_hts_tape=m_file.get("dr_tf_hts_tape", scan=scan), diff --git a/process/models/tfcoil/superconducting.py b/process/models/tfcoil/superconducting.py index ab7afba85..fdab4ac91 100644 --- a/process/models/tfcoil/superconducting.py +++ b/process/models/tfcoil/superconducting.py @@ -2037,17 +2037,6 @@ def run(self, output: bool = False): else: strain = tfcoil_variables.str_wp - tfcoil_variables.temp_tf_superconductor_margin = self.calculate_superconductor_temperature_margin( - i_tf_superconductor=tfcoil_variables.i_tf_sc_mat, - j_superconductor=superconducting_tf_coil_variables.j_tf_superconductor, - b_tf_inboard_peak=tfcoil_variables.b_tf_inboard_peak_with_ripple, - strain=strain, - bc20m=superconducting_tf_coil_variables.b_tf_superconductor_critical_zero_temp_strain, - tc0m=superconducting_tf_coil_variables.temp_tf_superconductor_critical_zero_field_strain, - c0=1.0e10, - temp_tf_coolant_peak_field=tfcoil_variables.tftmp, - ) - # Do current density protection calculation # Only setup for Nb3Sn at present. if ( From 555cc75bd9956a363e6c6408159d9b65ef69087a Mon Sep 17 00:00:00 2001 From: mn3981 Date: Thu, 14 May 2026 17:26:24 +0100 Subject: [PATCH 31/37] Update tests --- process/models/cryostat.py | 4 +-- process/models/tfcoil/base.py | 15 +++++----- process/models/tfcoil/superconducting.py | 13 ++++++++- tests/unit/models/test_superconductors.py | 2 +- tests/unit/models/tfcoil/test_sctfcoil.py | 34 +++++++++++------------ 5 files changed, 39 insertions(+), 29 deletions(-) diff --git a/process/models/cryostat.py b/process/models/cryostat.py index adb83ed21..b461c6b14 100644 --- a/process/models/cryostat.py +++ b/process/models/cryostat.py @@ -111,14 +111,14 @@ def output(self): ) po.ovarrf( self.outfile, - "Cryostat structure volume (m^3)", + "Cryostat structure volume (m³)", "(vol_cryostat)", self.data.fwbs.vol_cryostat, "OP ", ) po.ovarrf( self.outfile, - "Cryostat internal volume (m^3)", + "Cryostat internal volume (m³)", "(vol_cryostat_internal)", self.data.fwbs.vol_cryostat_internal, "OP ", diff --git a/process/models/tfcoil/base.py b/process/models/tfcoil/base.py index f82b15aea..5be158cc8 100644 --- a/process/models/tfcoil/base.py +++ b/process/models/tfcoil/base.py @@ -639,20 +639,21 @@ def tf_stored_magnetic_energy( ) def outtf(self): - """Writes superconducting TF coil output to file - - This routine writes the superconducting TF coil results - to the output file. - PROCESS Superconducting TF Coil Model, J. Morris, CCFE, 1st May 2014 + """Writes generic TF coil parameters used by all types of TF coils to + the output file. """ # General coil parameters - po.osubhd(self.outfile, "TF design") + po.oheadr(self.outfile, "General TF Coil Parameters") po.ovarin( self.outfile, - "Conductor technology", + "TF conductor technology", "(i_tf_sup)", tfcoil_variables.i_tf_sup, ) + po.ocmmnt( + self.outfile, + f"TF conductor model selected: {TFConductorModel(tfcoil_variables.i_tf_sup).name}", + ) po.ovarin( self.outfile, "Superconducting TF coil turn type", diff --git a/process/models/tfcoil/superconducting.py b/process/models/tfcoil/superconducting.py index fdab4ac91..461bd3b9c 100644 --- a/process/models/tfcoil/superconducting.py +++ b/process/models/tfcoil/superconducting.py @@ -2029,7 +2029,7 @@ def run(self, output: bool = False): superconducting_tf_coil_variables.b_tf_superconductor_critical_zero_temp_strain = critical_superconductor_info.bc20m superconducting_tf_coil_variables.temp_tf_superconductor_critical_zero_field_strain = critical_superconductor_info.tc0m superconducting_tf_coil_variables.c_tf_turn_cables_critical = ( - critical_superconductor_info.c_tf_turn_cables_critical + critical_superconductor_info.c_turn_cables_critical ) if tfcoil_variables.i_str_wp == 0: @@ -2037,6 +2037,17 @@ def run(self, output: bool = False): else: strain = tfcoil_variables.str_wp + tfcoil_variables.temp_tf_superconductor_margin = self.calculate_superconductor_temperature_margin( + i_tf_superconductor=tfcoil_variables.i_tf_sc_mat, + j_superconductor=superconducting_tf_coil_variables.j_tf_superconductor, + b_tf_inboard_peak=tfcoil_variables.b_tf_inboard_peak_with_ripple, + strain=strain, + bc20m=superconducting_tf_coil_variables.b_tf_superconductor_critical_zero_temp_strain, + tc0m=superconducting_tf_coil_variables.temp_tf_superconductor_critical_zero_field_strain, + c0=1.0e10, + temp_tf_coolant_peak_field=tfcoil_variables.tftmp, + ) + # Do current density protection calculation # Only setup for Nb3Sn at present. if ( diff --git a/tests/unit/models/test_superconductors.py b/tests/unit/models/test_superconductors.py index fc8e6b12c..a425fa152 100644 --- a/tests/unit/models/test_superconductors.py +++ b/tests/unit/models/test_superconductors.py @@ -145,7 +145,7 @@ def test_jcrit_nbti(jcritnbtiparam): def test_jcrit_rebco(): - jcrit_rebco, validity = superconductors.jcrit_rebco(4.75, 7.0) + jcrit_rebco, validity, _, _ = superconductors.jcrit_rebco(4.75, 7.0) assert jcrit_rebco == pytest.approx(55870234414.171684) assert validity diff --git a/tests/unit/models/tfcoil/test_sctfcoil.py b/tests/unit/models/tfcoil/test_sctfcoil.py index 036c315bd..d031e13c1 100644 --- a/tests/unit/models/tfcoil/test_sctfcoil.py +++ b/tests/unit/models/tfcoil/test_sctfcoil.py @@ -15,6 +15,7 @@ CICCAveragedTurnGeometry, CICCIntegerTurnGeometry, SuperconductingTFCoil, + TFSuperconductorLimits, ) @@ -434,16 +435,7 @@ def test_supercon(superconparam, monkeypatch, cicc_sctfcoil): monkeypatch.setattr(global_variables, "run_tests", superconparam.run_tests) - ( - j_tf_wp_critical, - j_superconductor_critical, - f_c_tf_turn_operating_critical, - j_superconductor, - j_tf_coil_turn, - bc20m, - tc0m, - c_turn_cables_critical, - ) = cicc_sctfcoil.tf_cable_in_conduit_superconductor_properties( + tf_limits: TFSuperconductorLimits = cicc_sctfcoil.tf_cable_in_conduit_superconductor_properties( i_tf_superconductor=superconparam.i_tf_superconductor, a_tf_turn_cable_space=superconparam.a_tf_turn_cable_space, a_tf_turn=superconparam.a_tf_turn, @@ -459,25 +451,31 @@ def test_supercon(superconparam, monkeypatch, cicc_sctfcoil): tcritsc=superconparam.tcritsc, ) - assert j_superconductor == pytest.approx(superconparam.expected_j_superconductor) + assert tf_limits.j_superconductor == pytest.approx( + superconparam.expected_j_superconductor + ) - assert j_tf_wp_critical == pytest.approx(superconparam.expected_j_tf_wp_critical) + assert tf_limits.j_tf_wp_critical == pytest.approx( + superconparam.expected_j_tf_wp_critical + ) - assert j_superconductor_critical == pytest.approx( + assert tf_limits.j_superconductor_critical == pytest.approx( superconparam.expected_j_superconductor_critical ) - assert f_c_tf_turn_operating_critical == pytest.approx( + assert tf_limits.f_c_tf_turn_operating_critical == pytest.approx( superconparam.expected_f_c_tf_turn_operating_critical ) - assert j_tf_coil_turn == pytest.approx(superconparam.expected_j_tf_coil_turn) + assert tf_limits.j_tf_coil_turn == pytest.approx( + superconparam.expected_j_tf_coil_turn + ) - assert bc20m == pytest.approx(superconparam.expected_bc20m) + assert tf_limits.bc20m == pytest.approx(superconparam.expected_bc20m) - assert tc0m == pytest.approx(superconparam.expected_tc0m) + assert tf_limits.tc0m == pytest.approx(superconparam.expected_tc0m) - assert c_turn_cables_critical == pytest.approx( + assert tf_limits.c_turn_cables_critical == pytest.approx( superconparam.expected_c_turn_cables_critical ) From 44a59b7f635bb3f9adf9c15708321b9c5d368e7a Mon Sep 17 00:00:00 2001 From: mn3981 Date: Fri, 15 May 2026 10:40:06 +0100 Subject: [PATCH 32/37] Refactor output methods in TFCoil classes to use output_general_tf_info for consistency --- process/models/tfcoil/base.py | 356 +++++++++++------------ process/models/tfcoil/resistive.py | 2 +- process/models/tfcoil/superconducting.py | 39 ++- 3 files changed, 214 insertions(+), 183 deletions(-) diff --git a/process/models/tfcoil/base.py b/process/models/tfcoil/base.py index 5be158cc8..5cce8c36a 100644 --- a/process/models/tfcoil/base.py +++ b/process/models/tfcoil/base.py @@ -25,7 +25,6 @@ superconducting_tf_coil_variables, tfcoil_variables, ) -from process.models.superconductors import SuperconductorModel if TYPE_CHECKING: from process.models.build import Build @@ -638,9 +637,10 @@ def tf_stored_magnetic_energy( e_tf_coil_magnetic_stored, ) - def outtf(self): + def output_general_tf_info(self): """Writes generic TF coil parameters used by all types of TF coils to the output file. + This should only contain variables calculated in the `TFCoil` class """ # General coil parameters po.oheadr(self.outfile, "General TF Coil Parameters") @@ -654,36 +654,69 @@ def outtf(self): self.outfile, f"TF conductor model selected: {TFConductorModel(tfcoil_variables.i_tf_sup).name}", ) + po.oblnkl(self.outfile) + po.ocmmnt(self.outfile, "----------------------------") + po.oblnkl(self.outfile) + + # Coil shape po.ovarin( self.outfile, - "Superconducting TF coil turn type", - "(i_tf_turn_type)", - superconducting_tf_coil_variables.i_tf_turn_type, + "TF coil shape model used", + "(i_tf_shape)", + tfcoil_variables.i_tf_shape, ) - - if tfcoil_variables.i_tf_sup == TFConductorModel.WATER_COOLED_COPPER: + if tfcoil_variables.i_tf_shape == TFCoilShapeModel.D_SHAPE: + po.oblnkl(self.outfile) + po.ocmmnt(self.outfile, "D-shape coil, inner surface shape approximated by") po.ocmmnt( self.outfile, - " -> resistive coil : Water cooled copper (GLIDCOP AL-15)", + "by a straight segment and elliptical arcs between the following points:", ) - elif tfcoil_variables.i_tf_sup == TFConductorModel.SUPERCONDUCTING: - po.ocmmnt(self.outfile, " -> Superconducting coil (SC)") - elif tfcoil_variables.i_tf_sup == TFConductorModel.HELIUM_COOLED_ALUMINIUM: - po.ocmmnt(self.outfile, " -> Resistive coil : Helium cooled aluminium") - - # SC material scaling - if tfcoil_variables.i_tf_sup == TFConductorModel.SUPERCONDUCTING: - po.ovarin( - self.outfile, - "Superconductor material", - "(i_tf_sc_mat)", - tfcoil_variables.i_tf_sc_mat, + po.oblnkl(self.outfile) + elif tfcoil_variables.i_tf_shape == TFCoilShapeModel.PICTURE_FRAME: + po.oblnkl(self.outfile) + po.ocmmnt(self.outfile, "Picture frame coil, inner surface approximated by") + po.ocmmnt( + self.outfile, "by a straight segment between the following points:" ) + po.oblnkl(self.outfile) - po.ocmmnt( + po.write(self.outfile, " Point r(m) z(m)") + for ii in range(5): + po.write( self.outfile, - f" -> {SuperconductorModel(tfcoil_variables.i_tf_sc_mat).full_name}", + f" {ii} {tfcoil_variables.r_tf_arc[ii]:.6e} {tfcoil_variables.z_tf_arc[ii]:.6e}", + ) + po.ovarre( + constants.MFILE, + f"TF coil arc point {ii} R (m)", + f"(r_tf_arc({ii + 1}))", + tfcoil_variables.r_tf_arc[ii], + ) + po.ovarre( + constants.MFILE, + f"TF coil arc point {ii} Z (m)", + f"(z_tf_arc({ii + 1}))", + tfcoil_variables.z_tf_arc[ii], ) + po.oblnkl(self.outfile) + po.ocmmnt(self.outfile, "----------------------------") + po.oblnkl(self.outfile) + + po.ovarin( + self.outfile, + "TF plasma-facing case geometry type switch", + "(i_tf_case_geom)", + tfcoil_variables.i_tf_case_geom, + ) + po.ocmmnt( + self.outfile, + f"{TFPlasmaCaseType(tfcoil_variables.i_tf_case_geom).description}", + ) + + po.oblnkl(self.outfile) + po.ocmmnt(self.outfile, "----------------------------") + po.oblnkl(self.outfile) # Joints strategy po.ovarin( @@ -700,10 +733,14 @@ def outtf(self): else: po.ocmmnt(self.outfile, " -> Coils without demountable joints") + po.oblnkl(self.outfile) + po.ocmmnt(self.outfile, "----------------------------") + po.oblnkl(self.outfile) + # Centring forces support strategy po.ovarin( self.outfile, - "TF inboard leg support strategy", + "TF inboard leg support strategy model switch", "(i_tf_bucking)", tfcoil_variables.i_tf_bucking, ) @@ -739,6 +776,9 @@ def outtf(self): self.outfile, " -> TF in contact with CS (bucked and weged design)" ) + po.oblnkl(self.outfile) + po.ocmmnt(self.outfile, "----------------------------") + # TF coil geometry po.osubhd(self.outfile, "TF coil Geometry :") po.ovarin( @@ -747,13 +787,15 @@ def outtf(self): "(n_tf_coils)", int(tfcoil_variables.n_tf_coils), ) + po.ovarre( self.outfile, - "Inboard TF half angle [rad]", + "Inboard TF coil toroidal half angle [rad]", "(rad_tf_coil_inboard_toroidal_half)", superconducting_tf_coil_variables.rad_tf_coil_inboard_toroidal_half, "OP ", ) + po.oblnkl(self.outfile) po.ovarre( self.outfile, "Inboard leg centre radius (m)", @@ -775,12 +817,7 @@ def outtf(self): self.data.build.r_tf_inboard_out, "OP ", ) - po.ovarin( - self.outfile, - "WP shape selection switch", - "(i_tf_wp_geom)", - tfcoil_variables.i_tf_wp_geom, - ) + po.ovarre( constants.MFILE, "Radial position of inner edge and centre of winding pack (m)", @@ -824,12 +861,6 @@ def outtf(self): self.data.build.r_tf_outboard_mid, "OP ", ) - po.ovarin( - self.outfile, - "Outboard leg nose case type", - "(i_tf_case_geom)", - tfcoil_variables.i_tf_case_geom, - ) po.ovarre( self.outfile, "Total inboard leg radial thickness (m)", @@ -863,6 +894,7 @@ def outtf(self): tfcoil_variables.dx_tf_inboard_out_toroidal, "OP ", ) + po.oblnkl(self.outfile) po.ovarre( self.outfile, "Maximum inboard edge height (m)", @@ -900,6 +932,7 @@ def outtf(self): "OP ", ) else: + po.oblnkl(self.outfile) po.ovarre( self.outfile, "Mean coil circumference (including inboard leg length) (m)", @@ -908,50 +941,6 @@ def outtf(self): "OP ", ) - # Vertical shape - po.ovarin( - self.outfile, - "Vertical TF shape", - "(i_tf_shape)", - tfcoil_variables.i_tf_shape, - ) - if tfcoil_variables.i_tf_shape == TFCoilShapeModel.D_SHAPE: - po.oblnkl(self.outfile) - po.ocmmnt(self.outfile, "D-shape coil, inner surface shape approximated by") - po.ocmmnt( - self.outfile, - "by a straight segment and elliptical arcs between the following " - "points:", - ) - po.oblnkl(self.outfile) - elif tfcoil_variables.i_tf_shape == TFCoilShapeModel.PICTURE_FRAME: - po.oblnkl(self.outfile) - po.ocmmnt(self.outfile, "Picture frame coil, inner surface approximated by") - po.ocmmnt( - self.outfile, "by a straight segment between the following points:" - ) - po.oblnkl(self.outfile) - - po.write(self.outfile, " point x(m) y(m)") - for ii in range(5): - po.write( - self.outfile, - f" {ii} {tfcoil_variables.r_tf_arc[ii]}" - f" {tfcoil_variables.z_tf_arc[ii]}", - ) - po.ovarre( - constants.MFILE, - f"TF coil arc point {ii} R (m)", - f"(r_tf_arc({ii + 1}))", - tfcoil_variables.r_tf_arc[ii], - ) - po.ovarre( - constants.MFILE, - f"TF coil arc point {ii} Z (m)", - f"(z_tf_arc({ii + 1}))", - tfcoil_variables.z_tf_arc[ii], - ) - # CP tapering geometry if ( physics_variables.itart == 1 @@ -986,22 +975,119 @@ def outtf(self): self.outfile, "Distance from the midplane to the top of the centrepost (m)", "(z_tf_inside_half + dr_tf_outboard)", - self.data.build.z_tf_inside_half + self.data.build.dr_tf_outboard, + build_variables.z_tf_inside_half + build_variables.dr_tf_outboard, + ) + + po.oblnkl(self.outfile) + po.ocmmnt(self.outfile, "----------------------------") + + # TF current and field + po.osubhd(self.outfile, "Maximum B field and currents:") + + po.ovarre( + self.outfile, + "Radius of maximum field position on inboard TF coil (m)", + "(r_b_tf_inboard_peak)", + tfcoil_variables.r_b_tf_inboard_peak, + "OP ", + ) + + po.ovarre( + self.outfile, + "Nominal peak field on inboard TF coil assuming toroidal symmetry (T)", + "(b_tf_inboard_peak_symmetric)", + tfcoil_variables.b_tf_inboard_peak_symmetric, + "OP ", + ) + po.ovarre( + self.outfile, + "Actual peak field at discrete conductor (T)", + "(b_tf_inboard_peak_with_ripple)", + tfcoil_variables.b_tf_inboard_peak_with_ripple, + "OP ", + ) + po.ovarre( + self.outfile, + "Ratio of peak field with ripple to nominal axisymmetric peak field", + "(f_b_tf_inboard_peak_ripple_symmetric)", + superconducting_tf_coil_variables.f_b_tf_inboard_peak_ripple_symmetric, + "OP ", + ) + po.oblnkl(self.outfile) + po.ovarre( + self.outfile, + "Current in a single TF coil (A)", + "(c_tf_coil)", + superconducting_tf_coil_variables.c_tf_coil, + "OP ", + ) + po.ovarre( + self.outfile, + "Total current in all TF coils (A)", + "(c_tf_total)", + tfcoil_variables.c_tf_total, + ) + + po.ovarre( + self.outfile, + "Inboard leg mid-plane conductor current density (A/m2)", + "(oacdcp)", + tfcoil_variables.oacdcp, + ) + if physics_variables.itart == 1: + po.ovarre( + self.outfile, + "Outboard leg conductor current density (A/m2)", + "(cdtfleg)", + tfcoil_variables.cdtfleg, ) + po.oblnkl(self.outfile) + po.ocmmnt(self.outfile, "----------------------------") + + po.osubhd(self.outfile, "Self Inductances and Stored Magnetic Energy:") + po.ovarre( + self.outfile, + "Self inductance of a TF coil (H)", + "(ind_tf_coil)", + tfcoil_variables.ind_tf_coil, + "OP ", + ) + po.ovarre( + self.outfile, + "Total magnetic energy in a TF coil (J)", + "(e_tf_coil_magnetic_stored)", + tfcoil_variables.e_tf_coil_magnetic_stored, + "OP ", + ) + po.ovarre( + self.outfile, + "Total stored energy in TF coils (J)", + "(e_tf_magnetic_stored_total)", + superconducting_tf_coil_variables.e_tf_magnetic_stored_total, + "OP ", + ) + po.ovarre( + self.outfile, + "Total stored energy in TF coils (GJ)", + "(e_tf_magnetic_stored_total_gj)", + tfcoil_variables.e_tf_magnetic_stored_total_gj, + "OP ", + ) + # Turn/WP gemoetry if tfcoil_variables.i_tf_sup == TFConductorModel.SUPERCONDUCTING: # Total material fraction po.osubhd(self.outfile, "Global material area/fractions:") po.ovarre( self.outfile, - "TF cross-section (total) (m2)", + "TF cross-section (total) (m²)", "(a_tf_inboard_total)", tfcoil_variables.a_tf_inboard_total, ) po.ovarre( self.outfile, - "Total steel cross-section (m2)", + "Total steel cross-section (m²)", "(a_tf_coil_inboard_steel*n_tf_coils)", superconducting_tf_coil_variables.a_tf_coil_inboard_steel * tfcoil_variables.n_tf_coils, @@ -1014,7 +1100,7 @@ def outtf(self): ) po.ovarre( self.outfile, - "Total Insulation cross-section (total) (m2)", + "Total Insulation cross-section (total) (m²)", "(a_tf_coil_inboard_insulation*n_tf_coils)", superconducting_tf_coil_variables.a_tf_coil_inboard_insulation * tfcoil_variables.n_tf_coils, @@ -1030,7 +1116,7 @@ def outtf(self): po.osubhd(self.outfile, "External steel Case Information :") po.ovarre( self.outfile, - "Casing cross section area (per leg) (m2)", + "Casing cross section area (per leg) (m²)", "(a_tf_coil_inboard_case)", tfcoil_variables.a_tf_coil_inboard_case, ) @@ -1042,7 +1128,7 @@ def outtf(self): ) po.ovarre( self.outfile, - "Inboard leg plasma case area (m^2)", + "Inboard leg plasma case area (m²)", "(a_tf_plasma_case)", superconducting_tf_coil_variables.a_tf_plasma_case, ) @@ -1088,19 +1174,19 @@ def outtf(self): po.osubhd(self.outfile, "TF winding pack (WP) geometry:") po.ovarre( self.outfile, - "WP cross section area with insulation and insertion (per coil) (m2)", + "WP cross section area with insulation and insertion (per coil) (m²)", "(a_tf_wp_with_insulation)", superconducting_tf_coil_variables.a_tf_wp_with_insulation, ) po.ovarre( self.outfile, - "WP cross section area with no insulation and insertion (per coil) (m2)", + "WP cross section area with no insulation and insertion (per coil) (m²)", "(a_tf_wp_no_insulation)", superconducting_tf_coil_variables.a_tf_wp_no_insulation, ) po.ovarre( self.outfile, - "Total steel area in WP (per coil) (m2)", + "Total steel area in WP (per coil) (m²)", "(a_tf_wp_steel)", tfcoil_variables.a_tf_wp_steel, ) @@ -1143,7 +1229,7 @@ def outtf(self): ) po.ovarre( self.outfile, - "Ground wall insulation area (m^2)", + "Ground wall insulation area (m²)", "(a_tf_wp_ground_insulation)", superconducting_tf_coil_variables.a_tf_wp_ground_insulation, ) @@ -1158,7 +1244,7 @@ def outtf(self): po.osubhd(self.outfile, "TF winding pack (WP) material area/fractions:") po.ovarre( self.outfile, - "Steel WP cross-section (total) (m2)", + "Steel WP cross-section (total) (m²)", "(a_tf_wp_steel*n_tf_coils)", tfcoil_variables.a_tf_wp_steel * tfcoil_variables.n_tf_coils, ) @@ -1671,94 +1757,6 @@ def outtf(self): "OP ", ) - # TF current and field - po.osubhd(self.outfile, "Maximum B field and currents:") - po.ovarre( - self.outfile, - "Nominal peak field assuming toroidal symmetry (T)", - "(b_tf_inboard_peak_symmetric)", - tfcoil_variables.b_tf_inboard_peak_symmetric, - "OP ", - ) - po.ovarre( - self.outfile, - "Radius of maximum field position on inboard TF coil (m)", - "(r_b_tf_inboard_peak)", - tfcoil_variables.r_b_tf_inboard_peak, - "OP ", - ) - po.ovarre( - self.outfile, - "Total current in all TF coils (MA)", - "(c_tf_total/1.D6)", - 1.0e-6 * tfcoil_variables.c_tf_total, - "OP ", - ) - po.ovarre( - self.outfile, - "TF coil current (summed over all coils) (A)", - "(c_tf_total)", - tfcoil_variables.c_tf_total, - ) - if tfcoil_variables.i_tf_sup == TFConductorModel.SUPERCONDUCTING: - po.ovarre( - self.outfile, - "Actual peak field at discrete conductor (T)", - "(b_tf_inboard_peak_with_ripple)", - tfcoil_variables.b_tf_inboard_peak_with_ripple, - "OP ", - ) - po.ovarre( - self.outfile, - "Ratio of peak field with ripple to nominal axisymmetric peak field", - "(f_b_tf_inboard_peak_ripple_symmetric)", - superconducting_tf_coil_variables.f_b_tf_inboard_peak_ripple_symmetric, - "OP ", - ) - po.ovarre( - self.outfile, - "Winding pack current density (A/m2)", - "(j_tf_wp)", - tfcoil_variables.j_tf_wp, - "OP ", - ) - - po.ovarre( - self.outfile, - "Inboard leg mid-plane conductor current density (A/m2)", - "(oacdcp)", - tfcoil_variables.oacdcp, - ) - if physics_variables.itart == 1: - po.ovarre( - self.outfile, - "Outboard leg conductor current density (A/m2)", - "(cdtfleg)", - tfcoil_variables.cdtfleg, - ) - po.ovarre( - self.outfile, - "Self inductance of a TF coil (H)", - "(ind_tf_coil)", - tfcoil_variables.ind_tf_coil, - "OP ", - ) - po.ovarre( - self.outfile, - "Total stored energy in TF coils (GJ)", - "(e_tf_magnetic_stored_total_gj)", - tfcoil_variables.e_tf_magnetic_stored_total_gj, - "OP ", - ) - - po.ovarre( - self.outfile, - "Total magnetic energy in a TF coil (J)", - "(e_tf_coil_magnetic_stored)", - tfcoil_variables.e_tf_coil_magnetic_stored, - "OP ", - ) - # TF forces po.osubhd(self.outfile, "TF Forces:") po.ovarre( diff --git a/process/models/tfcoil/resistive.py b/process/models/tfcoil/resistive.py index f121a44af..a2f9b331b 100644 --- a/process/models/tfcoil/resistive.py +++ b/process/models/tfcoil/resistive.py @@ -270,7 +270,7 @@ def run(self, output: bool = False): tfcoil_variables.sig_tf_case = 0.0e0 tfcoil_variables.sig_tf_wp = 0.0e0 if output: - self.outtf() + self.output_general_tf_info() def res_tf_internal_geom(self): """ diff --git a/process/models/tfcoil/superconducting.py b/process/models/tfcoil/superconducting.py index 461bd3b9c..22db06ca8 100644 --- a/process/models/tfcoil/superconducting.py +++ b/process/models/tfcoil/superconducting.py @@ -121,7 +121,7 @@ def __init__(self): def output(self): """Output routine for superconducting TF coil model.""" - self.outtf() + self.output_general_tf_info() self.run_base_superconducting_tf() self.output_tf_superconductor_info() @@ -456,6 +456,32 @@ def output_tf_superconductor_info(self): f"{SuperconductorModel(tfcoil_variables.i_tf_sc_mat).full_name}", ) + po.ovarin( + self.outfile, + "Superconducting TF coil turn type", + "(i_tf_turn_type)", + superconducting_tf_coil_variables.i_tf_turn_type, + ) + po.ovarin( + self.outfile, + "WP shape selection switch", + "(i_tf_wp_geom)", + tfcoil_variables.i_tf_wp_geom, + ) + + po.ovarin( + self.outfile, + "Superconducting TF coil turn type", + "(i_tf_turn_type)", + superconducting_tf_coil_variables.i_tf_turn_type, + ) + po.ovarin( + self.outfile, + "WP shape selection switch", + "(i_tf_wp_geom)", + tfcoil_variables.i_tf_wp_geom, + ) + po.ovarre( self.outfile, "Critical field at zero temperature and strain (T)", @@ -544,6 +570,13 @@ def output_tf_superconductor_info(self): tfcoil_variables.j_tf_wp_critical, "OP ", ) + po.ovarre( + self.outfile, + "Winding pack current density (A/m2)", + "(j_tf_wp)", + tfcoil_variables.j_tf_wp, + "OP ", + ) po.ovarre( self.outfile, "Actual current density in winding pack (A/m2)", @@ -2084,7 +2117,7 @@ def run(self, output: bool = False): ) # TFC Quench voltage in kV if output: - self.outtf() + self.output_general_tf_info() @staticmethod def tf_cable_in_conduit_superconductor_properties( @@ -3572,7 +3605,7 @@ def run(self, output: bool = False): ) # TFC Quench voltage in kV if output: - self.outtf() + self.output_general_tf_info() self.output_croco_info() def tf_croco_averaged_turn_geometry( From 492001a14321f574ec296ed680d7deaa6cfb6c6f Mon Sep 17 00:00:00 2001 From: mn3981 Date: Fri, 15 May 2026 10:45:32 +0100 Subject: [PATCH 33/37] Move `e_tf_magnetic_stored_total` variable from superconducting to normal tf variables file --- process/data_structure/superconducting_tf_coil_variables.py | 4 ---- process/data_structure/tfcoil_variables.py | 6 +++++- process/models/tfcoil/base.py | 2 +- process/models/tfcoil/resistive.py | 2 +- process/models/tfcoil/superconducting.py | 6 +++--- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/process/data_structure/superconducting_tf_coil_variables.py b/process/data_structure/superconducting_tf_coil_variables.py index 1fb615b47..0a20a4e25 100644 --- a/process/data_structure/superconducting_tf_coil_variables.py +++ b/process/data_structure/superconducting_tf_coil_variables.py @@ -315,8 +315,6 @@ tau2: float = None -e_tf_magnetic_stored_total: float = None - is_leg_cp_temp_same: int = None @@ -365,7 +363,6 @@ def init_superconducting_tf_coil_variables(): t1, \ time2, \ tau2, \ - e_tf_magnetic_stored_total, \ radius_tf_turn_cable_space_corners, \ a_tf_turn_cable_space_effective, \ dr_tf_wp_no_insulation, \ @@ -447,7 +444,6 @@ def init_superconducting_tf_coil_variables(): t1 = 0.0 time2 = 0.0 tau2 = 0.0 - e_tf_magnetic_stored_total = 0.0 radius_tf_turn_cable_space_corners = 0.0 a_tf_turn_cable_space_effective = 0.0 dr_tf_wp_no_insulation = 0.0 diff --git a/process/data_structure/tfcoil_variables.py b/process/data_structure/tfcoil_variables.py index cd58cbee4..1af604b52 100644 --- a/process/data_structure/tfcoil_variables.py +++ b/process/data_structure/tfcoil_variables.py @@ -200,9 +200,11 @@ dia_tf_turn_coolant_channel: float = None """diameter of central helium channel in TF winding (m)""" +e_tf_magnetic_stored_total: float = None +"""Total magnetic stored energy in the toroidal field coils (J)""" e_tf_magnetic_stored_total_gj: float = None -"""total magnetic stored energy in the toroidal field coils (GJ)""" +"""Total magnetic stored energy in the toroidal field coils (GJ)""" e_tf_coil_magnetic_stored: float = None """Stored magnetic energy in a single TF coil (J)""" @@ -1122,6 +1124,7 @@ def init_tfcoil_variables(): dcond, \ den_tf_wp_turn_insulation, \ dia_tf_turn_coolant_channel, \ + e_tf_magnetic_stored_total, \ e_tf_magnetic_stored_total_gj, \ e_tf_coil_magnetic_stored, \ b_crit_upper_nbti, \ @@ -1348,6 +1351,7 @@ def init_tfcoil_variables(): ]) den_tf_wp_turn_insulation = 1800.0 dia_tf_turn_coolant_channel = 0.005 + e_tf_magnetic_stored_total = 0.0 e_tf_magnetic_stored_total_gj = 0.0 e_tf_coil_magnetic_stored = 0.0 b_crit_upper_nbti = 14.86 diff --git a/process/models/tfcoil/base.py b/process/models/tfcoil/base.py index 5cce8c36a..995eefd69 100644 --- a/process/models/tfcoil/base.py +++ b/process/models/tfcoil/base.py @@ -1064,7 +1064,7 @@ def output_general_tf_info(self): self.outfile, "Total stored energy in TF coils (J)", "(e_tf_magnetic_stored_total)", - superconducting_tf_coil_variables.e_tf_magnetic_stored_total, + tfcoil_variables.e_tf_magnetic_stored_total, "OP ", ) po.ovarre( diff --git a/process/models/tfcoil/resistive.py b/process/models/tfcoil/resistive.py index a2f9b331b..d743903dc 100644 --- a/process/models/tfcoil/resistive.py +++ b/process/models/tfcoil/resistive.py @@ -56,7 +56,7 @@ def run(self, output: bool = False): ) ( - superconducting_tf_coil_variables.e_tf_magnetic_stored_total, + tfcoil_variables.e_tf_magnetic_stored_total, tfcoil_variables.e_tf_magnetic_stored_total_gj, tfcoil_variables.e_tf_coil_magnetic_stored, ) = self.tf_stored_magnetic_energy( diff --git a/process/models/tfcoil/superconducting.py b/process/models/tfcoil/superconducting.py index 22db06ca8..3a177f0df 100644 --- a/process/models/tfcoil/superconducting.py +++ b/process/models/tfcoil/superconducting.py @@ -394,7 +394,7 @@ def run_base_superconducting_tf(self): ) ( - superconducting_tf_coil_variables.e_tf_magnetic_stored_total, + tfcoil_variables.e_tf_magnetic_stored_total, tfcoil_variables.e_tf_magnetic_stored_total_gj, tfcoil_variables.e_tf_coil_magnetic_stored, ) = self.tf_stored_magnetic_energy( @@ -3953,7 +3953,7 @@ def croco_voltage(self) -> float: 2.0e0 / superconducting_tf_coil_variables.time2 * ( - superconducting_tf_coil_variables.e_tf_magnetic_stored_total + tfcoil_variables.e_tf_magnetic_stored_total / tfcoil_variables.n_tf_coils ) / tfcoil_variables.c_tf_turn @@ -3966,7 +3966,7 @@ def croco_voltage(self) -> float: 2.0e0 / superconducting_tf_coil_variables.tau2 * ( - superconducting_tf_coil_variables.e_tf_magnetic_stored_total + tfcoil_variables.e_tf_magnetic_stored_total / tfcoil_variables.n_tf_coils ) / tfcoil_variables.c_tf_turn From 5be82fef9d511ff6ade70ad348ef8c7c2fe02e67 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Fri, 15 May 2026 10:55:38 +0100 Subject: [PATCH 34/37] Rename `oacdcp` to `j_tf_coil_full_area` across multiple files for clarity and consistency --- process/core/init.py | 2 +- process/core/input.py | 2 +- process/core/io/plot/scans.py | 2 +- process/core/scan.py | 6 ++++-- process/core/solver/iteration_variables.py | 4 +++- process/data_structure/numerics.py | 2 +- process/data_structure/scan_variables.py | 2 +- process/data_structure/tfcoil_variables.py | 10 ++++------ process/models/stellarator/coils/calculate.py | 2 +- process/models/stellarator/coils/output.py | 4 ++-- process/models/tfcoil/base.py | 17 ++++++++--------- tests/unit/models/tfcoil/test_tfcoil.py | 4 ++-- 12 files changed, 29 insertions(+), 28 deletions(-) diff --git a/process/core/init.py b/process/core/init.py index 91921429c..79c900bef 100644 --- a/process/core/init.py +++ b/process/core/init.py @@ -383,7 +383,7 @@ def check_process(inputs, data): # noqa: ARG001 data_structure.impurity_radiation_module.f_nd_impurity_electrons[imp] ) - # Stop the run if oacdcp is used as an optimisation variable + # Stop the run if j_tf_coil_full_area is used as an optimisation variable # As the current density is now calculated from b_plasma_toroidal_on_axis without constraint 10 if (data_structure.numerics.ixc[: data_structure.numerics.nvar] == 12).any(): diff --git a/process/core/input.py b/process/core/input.py index 8c1dea62d..940ecd828 100644 --- a/process/core/input.py +++ b/process/core/input.py @@ -740,7 +740,7 @@ def __post_init__(self): data_structure.physics_variables, float, range=(0.0, 1e21) ), "nflutfmax": InputVariable("constraints", float, range=(0.0, 1e24)), - "oacdcp": InputVariable( + "j_tf_coil_full_area": InputVariable( data_structure.tfcoil_variables, float, range=(10000.0, 1000000000.0) ), "f_a_cs_turn_steel": InputVariable( diff --git a/process/core/io/plot/scans.py b/process/core/io/plot/scans.py index b993fd568..09d7ea0d6 100644 --- a/process/core/io/plot/scans.py +++ b/process/core/io/plot/scans.py @@ -82,7 +82,7 @@ def plot_scan( 2: "pflux_div_heat_load_max_mw", 3: "p_plant_electric_net_mw", 4: "hfact", - 5: "oacdcp", + 5: "j_tf_coil_full_area", 6: "pflux_fw_neutron_max_mw", 7: "beamfus0", 8: "Obsolete", # OBSOLETE diff --git a/process/core/scan.py b/process/core/scan.py index 7588537e7..e3a74c872 100644 --- a/process/core/scan.py +++ b/process/core/scan.py @@ -60,7 +60,9 @@ def _missing_(cls, var): "p_plant_electric_net_required_mw", "Net_electric_power_(MW)", 3 ) hfact = ScanVariable("hfact", "Confinement_H_factor", 4) - oacdcp = ScanVariable("oacdcp", "TF_inboard_leg_J_(MA/m2)", 5) + j_tf_coil_full_area = ScanVariable( + "j_tf_coil_full_area", "TF_inboard_leg_J_(MA/m2)", 5 + ) pflux_fw_neutron_max_mw = ScanVariable( "pflux_fw_neutron_max_mw", "Allow._wall_load_(MW/m2)", 6 ) @@ -1079,7 +1081,7 @@ def scan_select(self, nwp, swp, iscn): case 4: physics_variables.hfact = swp[iscn - 1] case 5: - tfcoil_variables.oacdcp = swp[iscn - 1] + tfcoil_variables.j_tf_coil_full_area = swp[iscn - 1] case 6: self.data.constraints.pflux_fw_neutron_max_mw = swp[iscn - 1] case 7: diff --git a/process/core/solver/iteration_variables.py b/process/core/solver/iteration_variables.py index b16e2e5cd..8e0cd6e84 100644 --- a/process/core/solver/iteration_variables.py +++ b/process/core/solver/iteration_variables.py @@ -57,7 +57,9 @@ class IterationVariable: 1.0e-3, 1.0e3, ), - 12: IterationVariable("oacdcp", data_structure.tfcoil_variables, 1.0e5, 1.50e8), + 12: IterationVariable( + "j_tf_coil_full_area", data_structure.tfcoil_variables, 1.0e5, 1.50e8 + ), 13: IterationVariable("dr_tf_inboard", "build", 0.1, 5.0), 16: IterationVariable("dr_cs", "build", 0.01, 10.00), 17: IterationVariable("t_plant_pulse_dwell", "times", 0.1, 1.0e8), diff --git a/process/data_structure/numerics.py b/process/data_structure/numerics.py index 8494b3c04..7ea370e1c 100644 --- a/process/data_structure/numerics.py +++ b/process/data_structure/numerics.py @@ -208,7 +208,7 @@ * ( 9) NOT USED * (10) hfact * (11) p_hcd_primary_extra_heat_mw -* (12) oacdcp +* (12) j_tf_coil_full_area * (13) dr_tf_inboard (NOT RECOMMENDED) * (14) NOT USED * (15) NOT USED diff --git a/process/data_structure/scan_variables.py b/process/data_structure/scan_variables.py index e289bedff..f4cdec5d5 100644 --- a/process/data_structure/scan_variables.py +++ b/process/data_structure/scan_variables.py @@ -39,7 +39,7 @@
  • 2 pflux_div_heat_load_max_mw
  • 3 p_plant_electric_net_required_mw
  • 4 hfact -
  • 5 oacdcp +
  • 5 j_tf_coil_full_area
  • 6 pflux_fw_neutron_max_mw
  • 7 beamfus0
  • 8 NOT USED diff --git a/process/data_structure/tfcoil_variables.py b/process/data_structure/tfcoil_variables.py index 1af604b52..1c3201e60 100644 --- a/process/data_structure/tfcoil_variables.py +++ b/process/data_structure/tfcoil_variables.py @@ -419,10 +419,8 @@ """winding pack engineering current density (A/m2)""" -oacdcp: float = None -"""Overall current density in TF coil inboard legs midplane (A/m2) -Rem SK : Not used in tfcoil to set the current any more. Should not be used as -iteration variable 12 any more. It is now calculated. +j_tf_coil_full_area: float = None +"""Inboard leg mid-plane full coil area current density (A/m²) """ @@ -1156,7 +1154,7 @@ def init_tfcoil_variables(): j_tf_wp_critical, \ j_tf_wp_quench_heat_max, \ j_tf_wp, \ - oacdcp, \ + j_tf_coil_full_area, \ eyoung_ins, \ eyoung_steel, \ eyoung_cond_axial, \ @@ -1393,7 +1391,7 @@ def init_tfcoil_variables(): j_tf_wp_critical = 0.0 j_tf_wp_quench_heat_max = 0.0 j_tf_wp = 0.0 - oacdcp = 0.0 + j_tf_coil_full_area = 0.0 eyoung_ins = 1.0e8 eyoung_steel = 2.05e11 eyoung_cond_axial = 6.6e8 diff --git a/process/models/stellarator/coils/calculate.py b/process/models/stellarator/coils/calculate.py index 84481e2d3..764cfb215 100644 --- a/process/models/stellarator/coils/calculate.py +++ b/process/models/stellarator/coils/calculate.py @@ -278,7 +278,7 @@ def calculate_coils_summary_variables(coilcurrent, r_coil_major, r_coil_minor, a # [A] Total current in ALL coils tfcoil_variables.c_tf_total = tfcoil_variables.n_tf_coils * coilcurrent * 1.0e6 # [A / m^2] overall current density - tfcoil_variables.oacdcp = ( + tfcoil_variables.j_tf_coil_full_area = ( tfcoil_variables.c_tf_total / tfcoil_variables.a_tf_inboard_total ) # [m] radius of peak field occurrence, average diff --git a/process/models/stellarator/coils/output.py b/process/models/stellarator/coils/output.py index ba40cada6..72c09d6d8 100644 --- a/process/models/stellarator/coils/output.py +++ b/process/models/stellarator/coils/output.py @@ -197,8 +197,8 @@ def write( po.ovarre( stellarator.outfile, "Overall current density (A/m2)", - "(oacdcp)", - tfcoil_variables.oacdcp, + "(j_tf_coil_full_area)", + tfcoil_variables.j_tf_coil_full_area, ) po.ovarre( stellarator.outfile, diff --git a/process/models/tfcoil/base.py b/process/models/tfcoil/base.py index 995eefd69..4cff15b6e 100644 --- a/process/models/tfcoil/base.py +++ b/process/models/tfcoil/base.py @@ -179,7 +179,7 @@ def run_base_tf(self): tfcoil_variables.b_tf_inboard_peak_symmetric, tfcoil_variables.c_tf_total, superconducting_tf_coil_variables.c_tf_coil, - tfcoil_variables.oacdcp, + tfcoil_variables.j_tf_coil_full_area, ) = self.tf_current( n_tf_coils=tfcoil_variables.n_tf_coils, b_plasma_toroidal_on_axis=physics_variables.b_plasma_toroidal_on_axis, @@ -406,8 +406,7 @@ def tf_current( magnet [T]. - **c_tf_total** (*float*): Total current in TF coils [A]. - **c_tf_coil** (*float*): Current per TF coil [A]. - - **oacdcp** (*float*): Global inboard leg average current density in TF - coils [A/m²]. + - **j_tf_coil_full_area** (*float*): Global inboard leg average current density in TF coils [A/m²]. """ # Calculation of the maximum B field on the magnet [T] b_tf_inboard_peak_symmetric = ( @@ -425,9 +424,9 @@ def tf_current( c_tf_coil = c_tf_total / n_tf_coils # Global inboard leg average current in TF coils [A/m2] - oacdcp = c_tf_total / a_tf_inboard_total + j_tf_coil_full_area = c_tf_total / a_tf_inboard_total - return b_tf_inboard_peak_symmetric, c_tf_total, c_tf_coil, oacdcp + return b_tf_inboard_peak_symmetric, c_tf_total, c_tf_coil, j_tf_coil_full_area def tf_coil_shape_inner( self, @@ -1030,14 +1029,14 @@ def output_general_tf_info(self): po.ovarre( self.outfile, - "Inboard leg mid-plane conductor current density (A/m2)", - "(oacdcp)", - tfcoil_variables.oacdcp, + "Inboard leg mid-plane full coil area current density (A/m²)", + "(j_tf_coil_full_area)", + tfcoil_variables.j_tf_coil_full_area, ) if physics_variables.itart == 1: po.ovarre( self.outfile, - "Outboard leg conductor current density (A/m2)", + "Outboard leg conductor current density (A/m²)", "(cdtfleg)", tfcoil_variables.cdtfleg, ) diff --git a/tests/unit/models/tfcoil/test_tfcoil.py b/tests/unit/models/tfcoil/test_tfcoil.py index 6b4072304..fe8a6ff50 100644 --- a/tests/unit/models/tfcoil/test_tfcoil.py +++ b/tests/unit/models/tfcoil/test_tfcoil.py @@ -304,7 +304,7 @@ def test_tf_global_geometry( pytest.approx(12.4), # b_tf_inboard_peak_symmetric pytest.approx(154999999.93042317), # c_tf_total pytest.approx(9687499.995651448), # c_tf_coil - pytest.approx(193749999.91302896), # oacdcp + pytest.approx(193749999.91302896), # j_tf_coil_full_area ), ), ( @@ -317,7 +317,7 @@ def test_tf_global_geometry( pytest.approx(8.333333333), # b_tf_inboard_peak_symmetric pytest.approx(74999999.9663338), # c_tf_total pytest.approx(6249999.997194484), # c_tf_coil - pytest.approx(149999999.9326676), # oacdcp + pytest.approx(149999999.9326676), # j_tf_coil_full_area ), ), ], From aa39be349ecfc9596c89b915072d237383779863 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Fri, 15 May 2026 14:07:42 +0100 Subject: [PATCH 35/37] Update TF coil variable descriptions for clarity and consistency --- process/data_structure/tfcoil_variables.py | 4 +- process/models/tfcoil/base.py | 169 +++++++++++++-------- 2 files changed, 105 insertions(+), 68 deletions(-) diff --git a/process/data_structure/tfcoil_variables.py b/process/data_structure/tfcoil_variables.py index 1c3201e60..870a4c2b0 100644 --- a/process/data_structure/tfcoil_variables.py +++ b/process/data_structure/tfcoil_variables.py @@ -615,7 +615,7 @@ a_tf_inboard_total: float = None -"""Area of inboard midplane TF legs (m2)""" +"""Total inboard area of all TF coils (m²)""" len_tf_bus: float = None @@ -751,7 +751,7 @@ dx_tf_inboard_out_toroidal: float = None -"""TF coil toroidal thickness (m)""" +"""Inboard leg toroidal thickness at outer edge (m)""" dx_tf_turn_insulation: float = None diff --git a/process/models/tfcoil/base.py b/process/models/tfcoil/base.py index 4cff15b6e..69b3545b2 100644 --- a/process/models/tfcoil/base.py +++ b/process/models/tfcoil/base.py @@ -636,7 +636,7 @@ def tf_stored_magnetic_energy( e_tf_coil_magnetic_stored, ) - def output_general_tf_info(self): + def output_general_tf_info(self) -> None: """Writes generic TF coil parameters used by all types of TF coils to the output file. This should only contain variables calculated in the `TFCoil` class @@ -795,6 +795,14 @@ def output_general_tf_info(self): "OP ", ) po.oblnkl(self.outfile) + + po.ovarre( + constants.MFILE, + "Inboard leg inner radius (m)", + "(r_tf_inboard_in)", + build_variables.r_tf_inboard_in, + "OP ", + ) po.ovarre( self.outfile, "Inboard leg centre radius (m)", @@ -802,6 +810,20 @@ def output_general_tf_info(self): self.data.build.r_tf_inboard_mid, "OP ", ) + po.ovarre( + constants.MFILE, + "Inboard leg outer radius (m)", + "(r_tf_inboard_out)", + build_variables.r_tf_inboard_out, + "OP ", + ) + po.ovarre( + constants.MFILE, + "Inboard leg outer radius (m)", + "(r_tf_inboard_out)", + build_variables.r_tf_inboard_out, + "OP ", + ) po.ovarre( constants.MFILE, "Inboard leg inner radius (m)", @@ -860,6 +882,7 @@ def output_general_tf_info(self): self.data.build.r_tf_outboard_mid, "OP ", ) + po.oblnkl(self.outfile) po.ovarre( self.outfile, "Total inboard leg radial thickness (m)", @@ -874,21 +897,40 @@ def output_general_tf_info(self): ) po.ovarre( self.outfile, - "Full external coil width at mid-plane (m)", + "Inboard leg nose case radial thickness (m)", + "(dr_tf_nose_case)", + tfcoil_variables.dr_tf_nose_case, + ) + po.ovarre( + self.outfile, + "Inboard leg plasma side case thickness (m)", + "(dr_tf_plasma_case)", + tfcoil_variables.dr_tf_plasma_case, + ) + po.ovarre( + self.outfile, + "Full external coil radial width at mid-plane (m)", "(dr_tf_full_midplane)", tfcoil_variables.dr_tf_full_midplane, "OP ", ) po.ovarre( self.outfile, - "Full internal coil width at mid-plane (m)", + "Full internal coil radial width at mid-plane (m)", "(dr_tf_internal_midplane)", tfcoil_variables.dr_tf_internal_midplane, "OP ", ) + po.oblnkl(self.outfile) + po.ovarre( + self.outfile, + "Inboard leg case sidewall thickness at its narrowest point (m)", + "(dx_tf_side_case_min)", + tfcoil_variables.dx_tf_side_case_min, + ) po.ovarre( self.outfile, - "Outboard leg toroidal thickness (m)", + "Inboard leg toroidal thickness at outer edge (m)", "(dx_tf_inboard_out_toroidal)", tfcoil_variables.dx_tf_inboard_out_toroidal, "OP ", @@ -908,6 +950,7 @@ def output_general_tf_info(self): self.data.build.z_tf_top, "OP ", ) + po.oblnkl(self.outfile) po.ovarre( self.outfile, "Height difference in upper and lower TF from midplane (m)", @@ -939,6 +982,19 @@ def output_general_tf_info(self): tfcoil_variables.len_tf_coil, "OP ", ) + po.oblnkl(self.outfile) + po.ovarre( + self.outfile, + "Total inboard area of all TF coils (m²)", + "(a_tf_inboard_total)", + tfcoil_variables.a_tf_inboard_total, + ) + po.ovarre( + self.outfile, + "Outboard leg area of single TF coil (m²)", + "(a_tf_leg_outboard)", + tfcoil_variables.a_tf_leg_outboard, + ) # CP tapering geometry if ( @@ -1054,36 +1110,67 @@ def output_general_tf_info(self): ) po.ovarre( self.outfile, - "Total magnetic energy in a TF coil (J)", + "Total stored magnetic energy in a TF coil (J)", "(e_tf_coil_magnetic_stored)", tfcoil_variables.e_tf_coil_magnetic_stored, "OP ", ) po.ovarre( self.outfile, - "Total stored energy in TF coils (J)", + "Total stored magnetic energy in all TF coils (J)", "(e_tf_magnetic_stored_total)", tfcoil_variables.e_tf_magnetic_stored_total, "OP ", ) po.ovarre( self.outfile, - "Total stored energy in TF coils (GJ)", + "Total stored magnetic energy in all TF coils (GJ)", "(e_tf_magnetic_stored_total_gj)", tfcoil_variables.e_tf_magnetic_stored_total_gj, "OP ", ) + po.oblnkl(self.outfile) + po.ocmmnt(self.outfile, "----------------------------") + # Ripple calculations + po.osubhd( + self.outfile, "Plasma outboard midplane toroidal ripple information (δₜ):" + ) + if tfcoil_variables.i_tf_shape == TFCoilShapeModel.D_SHAPE: + po.ovarre( + self.outfile, + "Max allowed toroidal field ripple at plasma outboard midplane (%)", + "(ripple_b_tf_plasma_edge_max)", + tfcoil_variables.ripple_b_tf_plasma_edge_max, + ) + po.ovarre( + self.outfile, + "Toroidal field ripple at plasma outboard midplane (%)", + "(ripple_b_tf_plasma_edge)", + tfcoil_variables.ripple_b_tf_plasma_edge, + "OP ", + ) + else: + po.ovarre( + self.outfile, + "Max allowed toroidal field ripple at plasma outboard midplane (%)", + "(ripple_b_tf_plasma_edge_max)", + tfcoil_variables.ripple_b_tf_plasma_edge_max, + ) + po.ovarre( + self.outfile, + "Toroidal field ripple at plasma outboard midplane (%)", + "(ripple_b_tf_plasma_edge)", + tfcoil_variables.ripple_b_tf_plasma_edge, + ) + po.oblnkl(self.outfile) + po.ocmmnt(self.outfile, "----------------------------") + # Turn/WP gemoetry if tfcoil_variables.i_tf_sup == TFConductorModel.SUPERCONDUCTING: # Total material fraction po.osubhd(self.outfile, "Global material area/fractions:") - po.ovarre( - self.outfile, - "TF cross-section (total) (m²)", - "(a_tf_inboard_total)", - tfcoil_variables.a_tf_inboard_total, - ) + po.ovarre( self.outfile, "Total steel cross-section (m²)", @@ -1119,36 +1206,21 @@ def output_general_tf_info(self): "(a_tf_coil_inboard_case)", tfcoil_variables.a_tf_coil_inboard_case, ) - po.ovarre( - self.outfile, - "Inboard leg case plasma side wall thickness (m)", - "(dr_tf_plasma_case)", - tfcoil_variables.dr_tf_plasma_case, - ) + po.ovarre( self.outfile, "Inboard leg plasma case area (m²)", "(a_tf_plasma_case)", superconducting_tf_coil_variables.a_tf_plasma_case, ) - po.ovarre( - self.outfile, - 'Inboard leg case inboard "nose" thickness (m)', - "(dr_tf_nose_case)", - tfcoil_variables.dr_tf_nose_case, - ) + po.ovarre( self.outfile, 'Inboard leg case inboard "nose" area (m^2)', "(a_tf_coil_nose_case)", superconducting_tf_coil_variables.a_tf_coil_nose_case, ) - po.ovarre( - self.outfile, - "Inboard leg case sidewall thickness at its narrowest point (m)", - "(dx_tf_side_case_min)", - tfcoil_variables.dx_tf_side_case_min, - ) + po.ovarre( self.outfile, "Inboard leg case sidewall average thickness (m)", @@ -1871,41 +1943,6 @@ def output_general_tf_info(self): tfcoil_variables.temp_cp_average, ) - # Ripple calculations - po.osubhd(self.outfile, "Ripple information:") - if tfcoil_variables.i_tf_shape == TFCoilShapeModel.D_SHAPE: - po.ovarre( - self.outfile, - "Max allowed tfcoil_variables.ripple amplitude at plasma outboard " - "midplane (%)", - "(ripple_b_tf_plasma_edge_max)", - tfcoil_variables.ripple_b_tf_plasma_edge_max, - ) - po.ovarre( - self.outfile, - "Ripple amplitude at plasma outboard midplane (%)", - "(ripple_b_tf_plasma_edge)", - tfcoil_variables.ripple_b_tf_plasma_edge, - "OP ", - ) - else: - po.ovarre( - self.outfile, - "Max allowed tfcoil_variables.ripple amplitude at plasma (%)", - "(ripple_b_tf_plasma_edge_max)", - tfcoil_variables.ripple_b_tf_plasma_edge_max, - ) - po.ovarre( - self.outfile, - "Ripple at plasma edge (%)", - "(ripple_b_tf_plasma_edge)", - tfcoil_variables.ripple_b_tf_plasma_edge, - ) - po.ocmmnt( - self.outfile, - " Ripple calculation to be re-defined for picure frame coils", - ) - # Quench information if tfcoil_variables.i_tf_sup == TFConductorModel.SUPERCONDUCTING: po.osubhd(self.outfile, "Quench information :") From acb93f6e079789ce5682b75ef8e9fc42095b479d Mon Sep 17 00:00:00 2001 From: mn3981 Date: Fri, 15 May 2026 14:47:54 +0100 Subject: [PATCH 36/37] Refactor TFCoil output methods to use instance outfile and add general output method for superconducting TF coils --- process/models/tfcoil/base.py | 1149 +--------------------- process/models/tfcoil/superconducting.py | 1103 ++++++++++++++++++++- 2 files changed, 1123 insertions(+), 1129 deletions(-) diff --git a/process/models/tfcoil/base.py b/process/models/tfcoil/base.py index 69b3545b2..eab66ebb1 100644 --- a/process/models/tfcoil/base.py +++ b/process/models/tfcoil/base.py @@ -19,9 +19,7 @@ from process.core.model import Model from process.data_structure import ( global_variables, - numerics, physics_variables, - rebco_variables, superconducting_tf_coil_variables, tfcoil_variables, ) @@ -797,7 +795,7 @@ def output_general_tf_info(self) -> None: po.oblnkl(self.outfile) po.ovarre( - constants.MFILE, + self.outfile, "Inboard leg inner radius (m)", "(r_tf_inboard_in)", build_variables.r_tf_inboard_in, @@ -807,66 +805,42 @@ def output_general_tf_info(self) -> None: self.outfile, "Inboard leg centre radius (m)", "(r_tf_inboard_mid)", - self.data.build.r_tf_inboard_mid, - "OP ", - ) - po.ovarre( - constants.MFILE, - "Inboard leg outer radius (m)", - "(r_tf_inboard_out)", - build_variables.r_tf_inboard_out, + build_variables.r_tf_inboard_mid, "OP ", ) po.ovarre( - constants.MFILE, + self.outfile, "Inboard leg outer radius (m)", "(r_tf_inboard_out)", build_variables.r_tf_inboard_out, "OP ", ) - po.ovarre( - constants.MFILE, - "Inboard leg inner radius (m)", - "(r_tf_inboard_in)", - self.data.build.r_tf_inboard_in, - "OP ", - ) - po.ovarre( - constants.MFILE, - "Inboard leg outer radius (m)", - "(r_tf_inboard_out)", - self.data.build.r_tf_inboard_out, - "OP ", - ) + po.oblnkl(self.outfile) po.ovarre( - constants.MFILE, + self.outfile, "Radial position of inner edge and centre of winding pack (m)", "(r_tf_wp_inboard_inner)", superconducting_tf_coil_variables.r_tf_wp_inboard_inner, "OP ", ) + po.ovarre( - constants.MFILE, - "Radial position of outer edge and of winding pack (m)", - "(r_tf_wp_inboard_outer)", - superconducting_tf_coil_variables.r_tf_wp_inboard_outer, - "OP ", - ) - po.ovarre( - constants.MFILE, + self.outfile, "Radial position of centre of winding pack (m)", "(r_tf_wp_inboard_centre)", superconducting_tf_coil_variables.r_tf_wp_inboard_centre, "OP ", ) po.ovarre( - constants.MFILE, - "Minimum toroidal thickness of winding pack (m)", - "(dx_tf_wp_toroidal_min)", - superconducting_tf_coil_variables.dx_tf_wp_toroidal_min, + self.outfile, + "Radial position of outer edge and of winding pack (m)", + "(r_tf_wp_inboard_outer)", + superconducting_tf_coil_variables.r_tf_wp_inboard_outer, "OP ", ) + po.oblnkl(self.outfile) + po.ovarre( self.outfile, "Outboard leg inner radius (m)", @@ -1166,668 +1140,6 @@ def output_general_tf_info(self) -> None: po.oblnkl(self.outfile) po.ocmmnt(self.outfile, "----------------------------") - # Turn/WP gemoetry - if tfcoil_variables.i_tf_sup == TFConductorModel.SUPERCONDUCTING: - # Total material fraction - po.osubhd(self.outfile, "Global material area/fractions:") - - po.ovarre( - self.outfile, - "Total steel cross-section (m²)", - "(a_tf_coil_inboard_steel*n_tf_coils)", - superconducting_tf_coil_variables.a_tf_coil_inboard_steel - * tfcoil_variables.n_tf_coils, - ) - po.ovarre( - self.outfile, - "Total steel TF fraction", - "(f_a_tf_coil_inboard_steel)", - superconducting_tf_coil_variables.f_a_tf_coil_inboard_steel, - ) - po.ovarre( - self.outfile, - "Total Insulation cross-section (total) (m²)", - "(a_tf_coil_inboard_insulation*n_tf_coils)", - superconducting_tf_coil_variables.a_tf_coil_inboard_insulation - * tfcoil_variables.n_tf_coils, - ) - po.ovarre( - self.outfile, - "Total Insulation fraction", - "(f_a_tf_coil_inboard_insulation)", - superconducting_tf_coil_variables.f_a_tf_coil_inboard_insulation, - ) - - # External casing - po.osubhd(self.outfile, "External steel Case Information :") - po.ovarre( - self.outfile, - "Casing cross section area (per leg) (m²)", - "(a_tf_coil_inboard_case)", - tfcoil_variables.a_tf_coil_inboard_case, - ) - - po.ovarre( - self.outfile, - "Inboard leg plasma case area (m²)", - "(a_tf_plasma_case)", - superconducting_tf_coil_variables.a_tf_plasma_case, - ) - - po.ovarre( - self.outfile, - 'Inboard leg case inboard "nose" area (m^2)', - "(a_tf_coil_nose_case)", - superconducting_tf_coil_variables.a_tf_coil_nose_case, - ) - - po.ovarre( - self.outfile, - "Inboard leg case sidewall average thickness (m)", - "(dx_tf_side_case_average)", - superconducting_tf_coil_variables.dx_tf_side_case_average, - ) - po.ovarre( - self.outfile, - "Inboard leg case sidewall peak thickness (m)", - "(dx_tf_side_case_peak)", - superconducting_tf_coil_variables.dx_tf_side_case_peak, - ) - po.ovarre( - self.outfile, - "External case mass per coil (kg)", - "(m_tf_coil_case)", - tfcoil_variables.m_tf_coil_case, - "OP ", - ) - - # Winding pack structure - po.osubhd(self.outfile, "TF winding pack (WP) geometry:") - po.ovarre( - self.outfile, - "WP cross section area with insulation and insertion (per coil) (m²)", - "(a_tf_wp_with_insulation)", - superconducting_tf_coil_variables.a_tf_wp_with_insulation, - ) - po.ovarre( - self.outfile, - "WP cross section area with no insulation and insertion (per coil) (m²)", - "(a_tf_wp_no_insulation)", - superconducting_tf_coil_variables.a_tf_wp_no_insulation, - ) - po.ovarre( - self.outfile, - "Total steel area in WP (per coil) (m²)", - "(a_tf_wp_steel)", - tfcoil_variables.a_tf_wp_steel, - ) - po.ovarre( - self.outfile, - "Winding pack radial thickness (m)", - "(dr_tf_wp_with_insulation)", - tfcoil_variables.dr_tf_wp_with_insulation, - "OP ", - ) - if tfcoil_variables.i_tf_turns_integer == 1: - po.ovarre( - self.outfile, - "Winding pack toroidal width (m)", - "(dx_tf_wp_primary_toroidal)", - tfcoil_variables.dx_tf_wp_primary_toroidal, - "OP ", - ) - else: - po.ovarre( - self.outfile, - "Winding pack toroidal width 1 (m)", - "(dx_tf_wp_primary_toroidal)", - tfcoil_variables.dx_tf_wp_primary_toroidal, - "OP ", - ) - po.ovarre( - self.outfile, - "Winding pack toroidal width 2 (m)", - "(dx_tf_wp_secondary_toroidal)", - tfcoil_variables.dx_tf_wp_secondary_toroidal, - "OP ", - ) - - po.ovarre( - self.outfile, - "Ground wall insulation thickness (m)", - "(dx_tf_wp_insulation)", - tfcoil_variables.dx_tf_wp_insulation, - ) - po.ovarre( - self.outfile, - "Ground wall insulation area (m²)", - "(a_tf_wp_ground_insulation)", - superconducting_tf_coil_variables.a_tf_wp_ground_insulation, - ) - po.ovarre( - self.outfile, - "Winding pack insertion gap (m)", - "(dx_tf_wp_insertion_gap)", - tfcoil_variables.dx_tf_wp_insertion_gap, - ) - - # WP material fraction - po.osubhd(self.outfile, "TF winding pack (WP) material area/fractions:") - po.ovarre( - self.outfile, - "Steel WP cross-section (total) (m²)", - "(a_tf_wp_steel*n_tf_coils)", - tfcoil_variables.a_tf_wp_steel * tfcoil_variables.n_tf_coils, - ) - po.ovarre( - self.outfile, - "Steel WP fraction", - "(a_tf_wp_steel/a_tf_wp_with_insulation)", - tfcoil_variables.a_tf_wp_steel - / superconducting_tf_coil_variables.a_tf_wp_with_insulation, - ) - po.ovarre( - self.outfile, - "Insulation WP fraction", - "(a_tf_coil_wp_turn_insulation/a_tf_wp_with_insulation)", - tfcoil_variables.a_tf_coil_wp_turn_insulation - / superconducting_tf_coil_variables.a_tf_wp_with_insulation, - ) - po.ovarre( - self.outfile, - "Cable WP fraction", - "((a_tf_wp_with_insulation-a_tf_wp_steel-a_tf_coil_wp_turn_insulation)" - "/a_tf_wp_with_insulation)", - ( - superconducting_tf_coil_variables.a_tf_wp_with_insulation - - tfcoil_variables.a_tf_wp_steel - - tfcoil_variables.a_tf_coil_wp_turn_insulation - ) - / superconducting_tf_coil_variables.a_tf_wp_with_insulation, - ) - - # Number of turns - po.osubhd(self.outfile, "WP turn information:") - po.ovarin( - self.outfile, - "Turn parameterisation", - "(i_tf_turns_integer)", - tfcoil_variables.i_tf_turns_integer, - ) - if tfcoil_variables.i_tf_turns_integer == 0: - po.ocmmnt(self.outfile, " Non-integer number of turns") - else: - po.ocmmnt(self.outfile, " Integer number of turns") - - po.ovarre( - self.outfile, - "Number of turns per TF coil", - "(n_tf_coil_turns)", - tfcoil_variables.n_tf_coil_turns, - "OP ", - ) - if tfcoil_variables.i_tf_turns_integer == 1: - po.ovarin( - self.outfile, - "Number of TF pancakes", - "(n_tf_wp_pancakes)", - tfcoil_variables.n_tf_wp_pancakes, - ) - po.ovarin( - self.outfile, - "Number of TF layers", - "(n_tf_wp_layers)", - tfcoil_variables.n_tf_wp_layers, - ) - - po.oblnkl(self.outfile) - - if tfcoil_variables.i_tf_turns_integer == 1: - po.ovarre( - self.outfile, - "Radial width of turn (m)", - "(dr_tf_turn)", - superconducting_tf_coil_variables.dr_tf_turn, - ) - po.ovarre( - self.outfile, - "Toroidal width of turn (m)", - "(dx_tf_turn)", - superconducting_tf_coil_variables.dx_tf_turn, - ) - po.ovarre( - self.outfile, - "Radial width of conductor (m)", - "(t_conductor_radial)", - superconducting_tf_coil_variables.t_conductor_radial, - "OP ", - ) - po.ovarre( - self.outfile, - "Toroidal width of conductor (m)", - "(t_conductor_toroidal)", - superconducting_tf_coil_variables.t_conductor_toroidal, - "OP ", - ) - po.ovarre( - self.outfile, - "Radial width of cable space", - "(dr_tf_turn_cable_space)", - superconducting_tf_coil_variables.dr_tf_turn_cable_space, - ) - po.ovarre( - self.outfile, - "Toroidal width of cable space", - "(dx_tf_turn_cable_space)", - superconducting_tf_coil_variables.dx_tf_turn_cable_space, - ) - po.ovarre( - self.outfile, - "Radius of turn cable space rounded corners (m)", - "(radius_tf_turn_cable_space_corners)", - superconducting_tf_coil_variables.radius_tf_turn_cable_space_corners, - ) - else: - po.ovarre( - self.outfile, - "Width of turn including inter-turn insulation (m)", - "(dx_tf_turn_general)", - tfcoil_variables.dx_tf_turn_general, - "OP ", - ) - po.ovarre( - self.outfile, - "Width of conductor (square) (m)", - "(t_conductor)", - tfcoil_variables.t_conductor, - "OP ", - ) - po.ovarre( - self.outfile, - "Width of space inside conductor (m)", - "(dx_tf_turn_cable_space_average)", - superconducting_tf_coil_variables.dx_tf_turn_cable_space_average, - "OP ", - ) - po.ovarre( - self.outfile, - "Radius of turn cable space rounded corners (m)", - "(radius_tf_turn_cable_space_corners)", - superconducting_tf_coil_variables.radius_tf_turn_cable_space_corners, - ) - - po.ovarre( - self.outfile, - "Steel conduit thickness (m)", - "(dx_tf_turn_steel)", - tfcoil_variables.dx_tf_turn_steel, - ) - po.ovarre( - self.outfile, - "Inter-turn insulation thickness (m)", - "(dx_tf_turn_insulation)", - tfcoil_variables.dx_tf_turn_insulation, - ) - - if tfcoil_variables.i_tf_sc_mat in {1, 2, 3, 4, 5, 7, 8, 9}: - po.osubhd(self.outfile, "Conductor information:") - po.ovarre( - self.outfile, - "Diameter of central helium channel in cable", - "(dia_tf_turn_coolant_channel)", - tfcoil_variables.dia_tf_turn_coolant_channel, - ) - po.ovarre( - self.outfile, - "Diameter of superconducting cable", - "(dia_tf_turn_superconducting_cable)", - superconducting_tf_coil_variables.dia_tf_turn_superconducting_cable, - ) - po.ovarre( - self.outfile, - "Number of superconducting cables per turn", - "(n_tf_turn_superconducting_cables)", - superconducting_tf_coil_variables.n_tf_turn_superconducting_cables, - ) - po.ovarre( - self.outfile, - "Length of superconductor in TF coil (m)", - "(len_tf_coil_superconductor)", - superconducting_tf_coil_variables.len_tf_coil_superconductor, - ) - po.ovarre( - self.outfile, - "Total length of superconductor in all TF coils (m)", - "(len_tf_superconductor_total)", - superconducting_tf_coil_variables.len_tf_superconductor_total, - ) - po.ocmmnt(self.outfile, "Fractions by area") - po.ovarre( - self.outfile, - "internal area of the cable space", - "(a_tf_turn_cable_space_no_void)", - tfcoil_variables.a_tf_turn_cable_space_no_void, - ) - po.ovarre( - self.outfile, - "True area of turn cable space with gaps and channels removed", - "(a_tf_turn_cable_space_effective)", - superconducting_tf_coil_variables.a_tf_turn_cable_space_effective, - ) - - po.ovarre( - self.outfile, - "Coolant fraction in conductor excluding central channel", - "(f_a_tf_turn_cable_space_extra_void)", - tfcoil_variables.f_a_tf_turn_cable_space_extra_void, - ) - po.ovarre( - self.outfile, - "Area of steel in turn", - "(a_tf_turn_steel)", - tfcoil_variables.a_tf_turn_steel, - ) - po.ovarre( - self.outfile, - "Area of all turn insulation in WP", - "(a_tf_coil_wp_turn_insulation)", - tfcoil_variables.a_tf_coil_wp_turn_insulation, - ) - po.ovarre( - self.outfile, - "Total insulation area in TF coil (turn and WP)", - "(a_tf_coil_inboard_insulation)", - superconducting_tf_coil_variables.a_tf_coil_inboard_insulation, - ) - po.ovarre( - self.outfile, - "Total steel area in inboard TF coil (turn and case)", - "(a_tf_coil_inboard_steel)", - superconducting_tf_coil_variables.a_tf_coil_inboard_steel, - ) - po.ovarre( - self.outfile, - "Total conductor area in WP", - "(a_tf_wp_conductor)", - tfcoil_variables.a_tf_wp_conductor, - ) - po.ovarre( - self.outfile, - "Total additional void area in WP", - "(a_tf_wp_extra_void)", - tfcoil_variables.a_tf_wp_extra_void, - ) - - po.ovarre( - self.outfile, - "Area of all coolant channels in WP", - "(a_tf_wp_coolant_channels)", - tfcoil_variables.a_tf_wp_coolant_channels, - ) - - po.ovarre( - self.outfile, - "Copper fraction of conductor", - "(f_a_tf_turn_cable_copper)", - tfcoil_variables.f_a_tf_turn_cable_copper, - ) - po.ovarre( - self.outfile, - "Superconductor fraction of conductor", - "(1-f_a_tf_turn_cable_copper)", - 1 - tfcoil_variables.f_a_tf_turn_cable_copper, - ) - ap = ( - tfcoil_variables.a_tf_wp_conductor - + tfcoil_variables.n_tf_coil_turns * tfcoil_variables.a_tf_turn_steel - + tfcoil_variables.a_tf_coil_wp_turn_insulation - + tfcoil_variables.a_tf_wp_extra_void - + tfcoil_variables.a_tf_wp_coolant_channels - ) - po.ovarrf( - self.outfile, - "Check total area fractions in winding pack = 1", - "", - ( - tfcoil_variables.a_tf_wp_conductor - + tfcoil_variables.n_tf_coil_turns - * tfcoil_variables.a_tf_turn_steel - + tfcoil_variables.a_tf_coil_wp_turn_insulation - + tfcoil_variables.a_tf_wp_extra_void - + tfcoil_variables.a_tf_wp_coolant_channels - ) - / ap, - ) - po.ovarrf( - self.outfile, - "minimum TF conductor temperature margin (K)", - "(temp_tf_superconductor_margin_min)", - tfcoil_variables.temp_tf_superconductor_margin_min, - ) - po.ovarrf( - self.outfile, - "TF conductor temperature margin (K)", - "(temp_tf_superconductor_margin)", - tfcoil_variables.temp_tf_superconductor_margin, - ) - - po.ovarin( - self.outfile, - "Elastic properties behavior", - "(i_tf_cond_eyoung_axial)", - tfcoil_variables.i_tf_cond_eyoung_axial, - ) - if tfcoil_variables.i_tf_cond_eyoung_axial == 0: - po.ocmmnt(self.outfile, " Conductor stiffness neglected") - elif tfcoil_variables.i_tf_cond_eyoung_axial == 1: - po.ocmmnt(self.outfile, " Conductor stiffness is user-input") - elif tfcoil_variables.i_tf_cond_eyoung_axial == 2: - po.ocmmnt( - self.outfile, - " Conductor stiffness is set by material-specific default", - ) - - po.ovarre( - self.outfile, - "Conductor axial Youngs modulus", - "(eyoung_cond_axial)", - tfcoil_variables.eyoung_cond_axial, - ) - po.ovarre( - self.outfile, - "Conductor transverse Youngs modulus", - "(eyoung_cond_trans)", - tfcoil_variables.eyoung_cond_trans, - ) - else: - # External casing - po.osubhd(self.outfile, "Bucking cylinder information:") - po.ovarre( - self.outfile, - "Casing cross section area (per leg) (m2)", - "(a_tf_coil_inboard_case)", - tfcoil_variables.a_tf_coil_inboard_case, - ) - po.ovarre( - self.outfile, - "Inboard leg case plasma side wall thickness (m)", - "(dr_tf_plasma_case)", - tfcoil_variables.dr_tf_plasma_case, - ) - po.ovarre( - self.outfile, - "Inboard leg plasma case area (m^2)", - "(a_tf_plasma_case)", - superconducting_tf_coil_variables.a_tf_plasma_case, - ) - po.ovarre( - self.outfile, - "Inboard leg bucking cylinder thickness (m)", - "(dr_tf_nose_case)", - tfcoil_variables.dr_tf_nose_case, - ) - po.ovarre( - self.outfile, - 'Inboard leg case inboard "nose" area (m^2)', - "(a_tf_coil_nose_case)", - superconducting_tf_coil_variables.a_tf_coil_nose_case, - ) - - # Conductor layer geometry - po.osubhd(self.outfile, "Inboard TFC conductor sector geometry:") - po.ovarre( - self.outfile, - "Inboard TFC conductor sector area with gr insulation (per leg) (m2)", - "(a_tf_wp_with_insulation)", - superconducting_tf_coil_variables.a_tf_wp_with_insulation, - ) - po.ovarre( - self.outfile, - "Inboard TFC conductor sector area, NO ground & gap (per leg) (m2)", - "(a_tf_wp_no_insulation)", - superconducting_tf_coil_variables.a_tf_wp_no_insulation, - ) - po.ovarre( - self.outfile, - "Ground wall insulation area (m^2)", - "(a_tf_wp_ground_insulation)", - superconducting_tf_coil_variables.a_tf_wp_ground_insulation, - ) - po.ovarre( - self.outfile, - "Inboard conductor sector radial thickness (m)", - "(dr_tf_wp_with_insulation)", - tfcoil_variables.dr_tf_wp_with_insulation, - ) - if physics_variables.itart == 1: - po.ovarre( - self.outfile, - "Central collumn top conductor sector radial thickness (m)", - "(dr_tf_wp_top)", - superconducting_tf_coil_variables.dr_tf_wp_top, - ) - - po.ovarre( - self.outfile, - "Ground wall insulation thickness (m)", - "(dx_tf_wp_insulation)", - tfcoil_variables.dx_tf_wp_insulation, - ) - # Turn info - po.osubhd(self.outfile, "Coil turn information:") - po.ovarre( - self.outfile, - "Number of turns per TF leg", - "(n_tf_coil_turns)", - tfcoil_variables.n_tf_coil_turns, - ) - po.ovarre( - self.outfile, - "Turn insulation thickness", - "(dx_tf_turn_insulation)", - tfcoil_variables.dx_tf_turn_insulation, - ) - po.ovarre( - self.outfile, - "Mid-plane CP cooling fraction", - "(fcoolcp)", - tfcoil_variables.fcoolcp, - ) - po.ovarre( - self.outfile, - "Area of resistive conductor per coil", - "(a_res_tf_coil_conductor)", - tfcoil_variables.a_res_tf_coil_conductor, - ) - po.ovarre( - self.outfile, - "Outboard leg current per turn (A)", - "(c_tf_turn)", - tfcoil_variables.c_tf_turn, - ) - po.ovarre( - self.outfile, - "Inboard leg conductor volume (m3)", - "(vol_cond_cp)", - tfcoil_variables.vol_cond_cp, - ) - po.ovarre( - self.outfile, - "Outboard leg volume per coil (m3)", - "(voltfleg)", - tfcoil_variables.voltfleg, - ) - - # Coil masses - po.osubhd(self.outfile, "TF coil mass:") - po.ovarre( - self.outfile, - "Superconductor mass per coil (kg)", - "(m_tf_coil_superconductor)", - tfcoil_variables.m_tf_coil_superconductor, - "OP ", - ) - po.ovarre( - self.outfile, - "Copper mass per coil (kg)", - "(m_tf_coil_copper)", - tfcoil_variables.m_tf_coil_copper, - "OP ", - ) - po.ovarre( - self.outfile, - "Steel conduit mass per coil (kg)", - "(m_tf_wp_steel_conduit)", - tfcoil_variables.m_tf_wp_steel_conduit, - "OP ", - ) - po.ovarre( - self.outfile, - "Conduit insulation mass per coil (kg)", - "(m_tf_coil_wp_turn_insulation)", - tfcoil_variables.m_tf_coil_wp_turn_insulation, - "OP ", - ) - if tfcoil_variables.i_tf_sup == TFConductorModel.SUPERCONDUCTING: - po.ovarre( - self.outfile, - "Total conduit mass per coil (kg)", - "(m_tf_coil_conductor)", - tfcoil_variables.m_tf_coil_conductor, - "OP ", - ) - - if physics_variables.itart == 1: - po.ovarre( - self.outfile, - "Mass of inboard legs (kg)", - "(whtcp)", - tfcoil_variables.whtcp, - "OP ", - ) - po.ovarre( - self.outfile, - "Mass of outboard legs (kg)", - "(whttflgs)", - tfcoil_variables.whttflgs, - "OP ", - ) - - po.ovarre( - self.outfile, - "Mass of each TF coil (kg)", - "(m_tf_coils_total/n_tf_coils)", - tfcoil_variables.m_tf_coils_total / tfcoil_variables.n_tf_coils, - "OP ", - ) - po.ovarre( - self.outfile, - "Total TF coil mass (kg)", - "(m_tf_coils_total)", - tfcoil_variables.m_tf_coils_total, - "OP ", - ) - # TF forces po.osubhd(self.outfile, "TF Forces:") po.ovarre( @@ -1846,7 +1158,14 @@ def output_general_tf_info(self) -> None: ) po.ovarre( self.outfile, - "inboard vertical tension fraction (-)", + "Total inboard vertical tension (N)", + "(vforce_inboard_total)", + superconducting_tf_coil_variables.vforce_inboard_tot, + "OP ", + ) + po.ovarre( + self.outfile, + "Inboard vertical tension fraction (-)", "(f_vforce_inboard)", tfcoil_variables.f_vforce_inboard, "OP ", @@ -1858,433 +1177,7 @@ def output_general_tf_info(self) -> None: tfcoil_variables.cforce, "OP ", ) - - # Resistive coil parameters - if tfcoil_variables.i_tf_sup != TFConductorModel.SUPERCONDUCTING: - po.osubhd(self.outfile, "Resitive loss parameters:") - if tfcoil_variables.i_tf_sup == TFConductorModel.WATER_COOLED_COPPER: - po.ocmmnt( - self.outfile, - "Resistive Material : GLIDCOP AL-15 - Dispersion " - "Strengthened Copper", - ) - elif tfcoil_variables.i_tf_sup == TFConductorModel.HELIUM_COOLED_ALUMINIUM: - po.ocmmnt( - self.outfile, "Resistive Material : Pure Aluminium (99.999+ %)" - ) - - if physics_variables.itart == 1: - po.ovarre( - self.outfile, - "CP resistivity (ohm.m)", - "(rho_cp)", - tfcoil_variables.rho_cp, - ) - po.ovarre( - self.outfile, - "Leg resistivity (ohm.m)", - "(rho_tf_leg)", - tfcoil_variables.rho_tf_leg, - ) - po.ovarre( - self.outfile, - "CP resistive power loss (W)", - "(p_cp_resistive)", - tfcoil_variables.p_cp_resistive, - ) - po.ovarre( - self.outfile, - "Total legs resitive power loss, (W)", - "(p_tf_leg_resistive)", - tfcoil_variables.p_tf_leg_resistive, - ) - po.ovarre( - self.outfile, - "joints resistive power loss (W)", - "(p_tf_joints_resistive)", - tfcoil_variables.p_tf_joints_resistive, - ) - po.ovarre( - self.outfile, - "Outboard leg resistance per coil (ohm)", - "(res_tf_leg)", - tfcoil_variables.res_tf_leg, - ) - po.ovarre( - self.outfile, - "Average CP temperature (K)", - "(temp_cp_average)", - tfcoil_variables.temp_cp_average, - ) - po.ovarre( - self.outfile, - "Average leg temperature (K)", - "(temp_tf_legs_outboard)", - tfcoil_variables.temp_tf_legs_outboard, - ) - - else: - po.ovarre( - self.outfile, - "TF resistivity (ohm.m)", - "(p_cp_resistive)", - tfcoil_variables.rho_cp, - ) - po.ovarre( - self.outfile, - "TF coil resistive power less (total) (ohm.m)", - "(p_cp_resistive)", - tfcoil_variables.p_cp_resistive, - ) - po.ovarre( - self.outfile, - "Average coil temperature (K)", - "(temp_cp_average)", - tfcoil_variables.temp_cp_average, - ) - - # Quench information - if tfcoil_variables.i_tf_sup == TFConductorModel.SUPERCONDUCTING: - po.osubhd(self.outfile, "Quench information :") - po.ovarre( - self.outfile, - "Actual quench time (or time constant) (s)", - "(t_tf_superconductor_quench)", - tfcoil_variables.t_tf_superconductor_quench, - ) - po.ovarre( - self.outfile, - "Vacuum Vessel stress on quench (Pa)", - "(vv_stress_quench)", - superconducting_tf_coil_variables.vv_stress_quench, - "OP ", - ) - po.ovarre( - self.outfile, - "Maximum allowed voltage during quench due to insulation (kV)", - "(v_tf_coil_dump_quench_max_kv)", - tfcoil_variables.v_tf_coil_dump_quench_max_kv, - ) - po.ovarre( - self.outfile, - "Actual quench voltage (kV)", - "(v_tf_coil_dump_quench_kv)", - tfcoil_variables.v_tf_coil_dump_quench_kv, - "OP ", - ) - - if tfcoil_variables.i_tf_sc_mat in {1, 2, 3, 4, 5}: - po.ovarre( - self.outfile, - "Maximum allowed temp during a quench (K)", - "(temp_tf_conductor_quench_max)", - tfcoil_variables.temp_tf_conductor_quench_max, - ) - elif tfcoil_variables == 6: - po.ocmmnt(self.outfile, "CroCo cable with jacket: ") - - if 75 in numerics.icc: - po.ovarre( - self.outfile, - "Maximum permitted TF coil current / copper area (A/m2)", - "(copperA_m2_max)", - rebco_variables.tf_coppera_m2_max, - ) - - po.ovarre( - self.outfile, - "Actual TF coil current / copper area (A/m2)", - "(copperA_m2)", - rebco_variables.tf_coppera_m2, - ) - - # TF coil radial build - po.osubhd(self.outfile, "Radial build of TF coil centre-line :") - - radius = self.data.build.r_tf_inboard_in - po.obuild(self.outfile, "Innermost edge of TF coil", radius, radius) - - # Radial build for SC TF coils - if tfcoil_variables.i_tf_sup == TFConductorModel.SUPERCONDUCTING: - radius += tfcoil_variables.dr_tf_nose_case - po.obuild( - self.outfile, - 'Coil case ("nose")', - tfcoil_variables.dr_tf_nose_case, - radius, - "(dr_tf_nose_case)", - ) - - radius += tfcoil_variables.dx_tf_wp_insertion_gap - po.obuild( - self.outfile, - "Insertion gap for winding pack", - tfcoil_variables.dx_tf_wp_insertion_gap, - radius, - "(dx_tf_wp_insertion_gap)", - ) - - radius += tfcoil_variables.dx_tf_wp_insulation - po.obuild( - self.outfile, - "Winding pack ground insulation", - tfcoil_variables.dx_tf_wp_insulation, - radius, - "(dx_tf_wp_insulation)", - ) - - radius = ( - radius - + 0.5e0 * tfcoil_variables.dr_tf_wp_with_insulation - - tfcoil_variables.dx_tf_wp_insulation - - tfcoil_variables.dx_tf_wp_insertion_gap - ) - po.obuild( - self.outfile, - "Winding - first half", - tfcoil_variables.dr_tf_wp_with_insulation / 2e0 - - tfcoil_variables.dx_tf_wp_insulation - - tfcoil_variables.dx_tf_wp_insertion_gap, - radius, - "(dr_tf_wp_with_insulation/2-dx_tf_wp_insulation" - "-dx_tf_wp_insertion_gap)", - ) - - radius = ( - radius - + 0.5e0 * tfcoil_variables.dr_tf_wp_with_insulation - - tfcoil_variables.dx_tf_wp_insulation - - tfcoil_variables.dx_tf_wp_insertion_gap - ) - po.obuild( - self.outfile, - "Winding - second half", - tfcoil_variables.dr_tf_wp_with_insulation / 2e0 - - tfcoil_variables.dx_tf_wp_insulation - - tfcoil_variables.dx_tf_wp_insertion_gap, - radius, - "(dr_tf_wp_with_insulation/2-dx_tf_wp_insulation" - "-dx_tf_wp_insertion_gap)", - ) - - radius += tfcoil_variables.dx_tf_wp_insulation - po.obuild( - self.outfile, - "Winding pack insulation", - tfcoil_variables.dx_tf_wp_insulation, - radius, - "(dx_tf_wp_insulation)", - ) - - radius += tfcoil_variables.dx_tf_wp_insertion_gap - po.obuild( - self.outfile, - "Insertion gap for winding pack", - tfcoil_variables.dx_tf_wp_insertion_gap, - radius, - "(dx_tf_wp_insertion_gap)", - ) - - radius += tfcoil_variables.dr_tf_plasma_case - po.obuild( - self.outfile, - "Plasma side case min radius", - tfcoil_variables.dr_tf_plasma_case, - radius, - "(dr_tf_plasma_case)", - ) - - po.obuild( - self.outfile, - "Plasma side case max radius", - self.data.build.r_tf_inboard_out, - radius, - "(r_tf_inboard_out)", - ) - - # Radial build for restive coil - else: - radius += tfcoil_variables.dr_tf_nose_case - po.obuild( - self.outfile, - "Coil bucking cylindre", - tfcoil_variables.dr_tf_nose_case, - radius, - "(dr_tf_nose_case)", - ) - - radius += tfcoil_variables.dx_tf_wp_insulation - po.obuild( - self.outfile, - "Conductor ground insulation", - tfcoil_variables.dx_tf_wp_insulation, - radius, - "(dx_tf_wp_insulation)", - ) - - radius = ( - radius - + 0.5e0 * tfcoil_variables.dr_tf_wp_with_insulation - - tfcoil_variables.dx_tf_wp_insulation - ) - po.obuild( - self.outfile, - "Conductor - first half", - tfcoil_variables.dr_tf_wp_with_insulation / 2e0 - - tfcoil_variables.dx_tf_wp_insulation, - radius, - "(tfcoil_variables.dr_tf_wp_with_insulation/2" - "-tfcoil_variables.dx_tf_wp_insulation)", - ) - - radius = ( - radius - + 0.5e0 * tfcoil_variables.dr_tf_wp_with_insulation - - tfcoil_variables.dx_tf_wp_insulation - ) - po.obuild( - self.outfile, - "Conductor - second half", - tfcoil_variables.dr_tf_wp_with_insulation / 2e0 - - tfcoil_variables.dx_tf_wp_insulation, - radius, - "(tfcoil_variables.dr_tf_wp_with_insulation/2" - "-tfcoil_variables.dx_tf_wp_insulation)", - ) - - radius += tfcoil_variables.dx_tf_wp_insulation - po.obuild( - self.outfile, - "Conductor ground insulation", - tfcoil_variables.dx_tf_wp_insulation, - radius, - "(dx_tf_wp_insulation)", - ) - - radius += tfcoil_variables.dr_tf_plasma_case - po.obuild( - self.outfile, - "Plasma side TF coil support", - tfcoil_variables.dr_tf_plasma_case, - radius, - "(dr_tf_plasma_case)", - ) - - # Radial build consistency check - if not ( - abs(radius - self.data.build.r_tf_inboard_in - self.data.build.dr_tf_inboard) - < 10.0e0 * np.finfo(float(radius)).eps - ): - logger.error( - "TF coil dimensions are not consistent. Radius of plasma-facing side " - "of inner leg should be " - f"{self.data.build.r_tf_inboard_in + self.data.build.dr_tf_inboard}m" - ) - - tf_total_height = ( - self.data.build.dh_tf_inner_bore + 2 * self.data.build.dr_tf_inboard - ) - tf_total_width = ( - self.data.build.dr_tf_inner_bore - + self.data.build.dr_tf_inboard - + self.data.build.dr_tf_outboard - ) po.oblnkl(self.outfile) - po.obuild( - self.outfile, - "Total height and width of TFC [m]", - tf_total_height, - tf_total_width, - ) - - # Top section TF coil radial build (physics_variables.itart = 1 only) - if ( - physics_variables.itart == 1 - and tfcoil_variables.i_tf_sup != TFConductorModel.SUPERCONDUCTING - ): - po.osubhd(self.outfile, "Radial build of TF coil at central collumn top :") - # write(self.outfile,5) - - # Restart the radial build at bucking cylindre inner radius - radius = self.data.build.r_tf_inboard_in - po.obuild(self.outfile, "Innermost edge of TF coil", radius, radius) - - radius += tfcoil_variables.dr_tf_nose_case - po.obuild( - self.outfile, - "Coil bucking cylindre", - tfcoil_variables.dr_tf_nose_case, - radius, - "(dr_tf_nose_case)", - ) - - radius += tfcoil_variables.dx_tf_wp_insulation - po.obuild( - self.outfile, - "Conductor ground insulation", - tfcoil_variables.dx_tf_wp_insulation, - radius, - "(dx_tf_wp_insulation)", - ) - - radius = ( - radius - + 0.5e0 * superconducting_tf_coil_variables.dr_tf_wp_top - - tfcoil_variables.dx_tf_wp_insulation - ) - po.obuild( - self.outfile, - "Conductor - first half", - 0.5e0 * superconducting_tf_coil_variables.dr_tf_wp_top - - tfcoil_variables.dx_tf_wp_insulation, - radius, - "(dr_tf_wp_top/2-dx_tf_wp_insulation)", - ) - - radius = ( - radius - + 0.5e0 * superconducting_tf_coil_variables.dr_tf_wp_top - - tfcoil_variables.dx_tf_wp_insulation - ) - po.obuild( - self.outfile, - "Conductor - second half", - 0.5e0 * superconducting_tf_coil_variables.dr_tf_wp_top - - tfcoil_variables.dx_tf_wp_insulation, - radius, - "(dr_tf_wp_top/2-dx_tf_wp_insulation)", - ) - - radius += tfcoil_variables.dx_tf_wp_insulation - po.obuild( - self.outfile, - "Conductor ground insulation", - tfcoil_variables.dx_tf_wp_insulation, - radius, - "(dx_tf_wp_insulation)", - ) - - radius += tfcoil_variables.dr_tf_plasma_case - po.obuild( - self.outfile, - "Plasma side TF coil support", - tfcoil_variables.dr_tf_plasma_case, - radius, - "(dr_tf_plasma_case)", - ) - - # Consistency check - if abs(radius - self.data.build.r_cp_top) < np.finfo(float(radius)).eps: - po.ocmmnt(self.outfile, "Top TF coil dimensions are consistent") - else: - po.ocmmnt(self.outfile, "ERROR: TF coil dimensions are NOT consistent:") - po.ovarre( - self.outfile, - "Radius of plasma-facing side of inner leg SHOULD BE [m]", - "", - self.data.build.r_cp_top, - ) - po.oblnkl(self.outfile) @staticmethod def circumference(aaa, bbb): diff --git a/process/models/tfcoil/superconducting.py b/process/models/tfcoil/superconducting.py index 3a177f0df..6d8286bbd 100644 --- a/process/models/tfcoil/superconducting.py +++ b/process/models/tfcoil/superconducting.py @@ -15,8 +15,10 @@ from process.data_structure import ( divertor_variables, global_variables, + numerics, pfcoil_variables, physics_variables, + rebco_variables, superconducting_tf_coil_variables, tfcoil_variables, ) @@ -29,7 +31,7 @@ calculate_croco_cable_geometry, ) from process.models.tfcoil import quench -from process.models.tfcoil.base import TFCoil, TFPlasmaCaseType +from process.models.tfcoil.base import TFCoil, TFConductorModel, TFPlasmaCaseType logger = logging.getLogger(__name__) @@ -123,6 +125,7 @@ def output(self): """Output routine for superconducting TF coil model.""" self.output_general_tf_info() self.run_base_superconducting_tf() + self.output_general_superconducting_tf_info() self.output_tf_superconductor_info() tfcoil_variables.n_rad_per_layer = 500 @@ -440,6 +443,1104 @@ def run_base_superconducting_tf(self): ) # ====================================================== + def output_general_superconducting_tf_info(self) -> None: + """Output general TF coil information that is relevant for superconducting + TF coils. + Should only be info calculated in the `SuperconductingTFCoil` class, not the + base `TFCoil` class, which is relevant for all TF coil types. + + """ + + po.oheadr(self.outfile, "General Superconducting TF Coil Parameters ") + # Turn/WP gemoetry + if tfcoil_variables.i_tf_sup == TFConductorModel.SUPERCONDUCTING: + # Total material fraction + po.osubhd(self.outfile, "Global material area/fractions:") + + po.ovarre( + self.outfile, + "Total steel cross-section (m²)", + "(a_tf_coil_inboard_steel*n_tf_coils)", + superconducting_tf_coil_variables.a_tf_coil_inboard_steel + * tfcoil_variables.n_tf_coils, + ) + po.ovarre( + self.outfile, + "Total steel TF fraction", + "(f_a_tf_coil_inboard_steel)", + superconducting_tf_coil_variables.f_a_tf_coil_inboard_steel, + ) + po.ovarre( + self.outfile, + "Total Insulation cross-section (total) (m²)", + "(a_tf_coil_inboard_insulation*n_tf_coils)", + superconducting_tf_coil_variables.a_tf_coil_inboard_insulation + * tfcoil_variables.n_tf_coils, + ) + po.ovarre( + self.outfile, + "Total Insulation fraction", + "(f_a_tf_coil_inboard_insulation)", + superconducting_tf_coil_variables.f_a_tf_coil_inboard_insulation, + ) + + # External casing + po.osubhd(self.outfile, "External steel Case Information :") + po.ovarre( + self.outfile, + "Casing cross section area (per leg) (m²)", + "(a_tf_coil_inboard_case)", + tfcoil_variables.a_tf_coil_inboard_case, + ) + + po.ovarre( + self.outfile, + "Inboard leg plasma case area (m²)", + "(a_tf_plasma_case)", + superconducting_tf_coil_variables.a_tf_plasma_case, + ) + + po.ovarre( + self.outfile, + 'Inboard leg case inboard "nose" area (m^2)', + "(a_tf_coil_nose_case)", + superconducting_tf_coil_variables.a_tf_coil_nose_case, + ) + + po.ovarre( + self.outfile, + "Inboard leg case sidewall average thickness (m)", + "(dx_tf_side_case_average)", + superconducting_tf_coil_variables.dx_tf_side_case_average, + ) + po.ovarre( + self.outfile, + "Inboard leg case sidewall peak thickness (m)", + "(dx_tf_side_case_peak)", + superconducting_tf_coil_variables.dx_tf_side_case_peak, + ) + po.ovarre( + self.outfile, + "External case mass per coil (kg)", + "(m_tf_coil_case)", + tfcoil_variables.m_tf_coil_case, + "OP ", + ) + + # Winding pack structure + po.osubhd(self.outfile, "TF winding pack (WP) geometry:") + po.ovarre( + self.outfile, + "WP cross section area with insulation and insertion (per coil) (m²)", + "(a_tf_wp_with_insulation)", + superconducting_tf_coil_variables.a_tf_wp_with_insulation, + ) + po.ovarre( + self.outfile, + "Minimum toroidal thickness of winding pack (m)", + "(dx_tf_wp_toroidal_min)", + superconducting_tf_coil_variables.dx_tf_wp_toroidal_min, + "OP ", + ) + po.ovarre( + self.outfile, + "WP cross section area with no insulation and insertion (per coil) (m²)", + "(a_tf_wp_no_insulation)", + superconducting_tf_coil_variables.a_tf_wp_no_insulation, + ) + po.ovarre( + self.outfile, + "Total steel area in WP (per coil) (m²)", + "(a_tf_wp_steel)", + tfcoil_variables.a_tf_wp_steel, + ) + po.ovarre( + self.outfile, + "Winding pack radial thickness (m)", + "(dr_tf_wp_with_insulation)", + tfcoil_variables.dr_tf_wp_with_insulation, + "OP ", + ) + if tfcoil_variables.i_tf_turns_integer == 1: + po.ovarre( + self.outfile, + "Winding pack toroidal width (m)", + "(dx_tf_wp_primary_toroidal)", + tfcoil_variables.dx_tf_wp_primary_toroidal, + "OP ", + ) + else: + po.ovarre( + self.outfile, + "Winding pack toroidal width 1 (m)", + "(dx_tf_wp_primary_toroidal)", + tfcoil_variables.dx_tf_wp_primary_toroidal, + "OP ", + ) + po.ovarre( + self.outfile, + "Winding pack toroidal width 2 (m)", + "(dx_tf_wp_secondary_toroidal)", + tfcoil_variables.dx_tf_wp_secondary_toroidal, + "OP ", + ) + + po.ovarre( + self.outfile, + "Ground wall insulation thickness (m)", + "(dx_tf_wp_insulation)", + tfcoil_variables.dx_tf_wp_insulation, + ) + po.ovarre( + self.outfile, + "Ground wall insulation area (m²)", + "(a_tf_wp_ground_insulation)", + superconducting_tf_coil_variables.a_tf_wp_ground_insulation, + ) + po.ovarre( + self.outfile, + "Winding pack insertion gap (m)", + "(dx_tf_wp_insertion_gap)", + tfcoil_variables.dx_tf_wp_insertion_gap, + ) + + # WP material fraction + po.osubhd(self.outfile, "TF winding pack (WP) material area/fractions:") + po.ovarre( + self.outfile, + "Steel WP cross-section (total) (m²)", + "(a_tf_wp_steel*n_tf_coils)", + tfcoil_variables.a_tf_wp_steel * tfcoil_variables.n_tf_coils, + ) + po.ovarre( + self.outfile, + "Steel WP fraction", + "(a_tf_wp_steel/a_tf_wp_with_insulation)", + tfcoil_variables.a_tf_wp_steel + / superconducting_tf_coil_variables.a_tf_wp_with_insulation, + ) + po.ovarre( + self.outfile, + "Insulation WP fraction", + "(a_tf_coil_wp_turn_insulation/a_tf_wp_with_insulation)", + tfcoil_variables.a_tf_coil_wp_turn_insulation + / superconducting_tf_coil_variables.a_tf_wp_with_insulation, + ) + po.ovarre( + self.outfile, + "Cable WP fraction", + "((a_tf_wp_with_insulation-a_tf_wp_steel-a_tf_coil_wp_turn_insulation)/a_tf_wp_with_insulation)", + ( + superconducting_tf_coil_variables.a_tf_wp_with_insulation + - tfcoil_variables.a_tf_wp_steel + - tfcoil_variables.a_tf_coil_wp_turn_insulation + ) + / superconducting_tf_coil_variables.a_tf_wp_with_insulation, + ) + + # Number of turns + po.osubhd(self.outfile, "WP turn information:") + po.ovarin( + self.outfile, + "Turn parameterisation", + "(i_tf_turns_integer)", + tfcoil_variables.i_tf_turns_integer, + ) + if tfcoil_variables.i_tf_turns_integer == 0: + po.ocmmnt(self.outfile, " Non-integer number of turns") + else: + po.ocmmnt(self.outfile, " Integer number of turns") + + po.ovarre( + self.outfile, + "Number of turns per TF coil", + "(n_tf_coil_turns)", + tfcoil_variables.n_tf_coil_turns, + "OP ", + ) + if tfcoil_variables.i_tf_turns_integer == 1: + po.ovarin( + self.outfile, + "Number of TF pancakes", + "(n_tf_wp_pancakes)", + tfcoil_variables.n_tf_wp_pancakes, + ) + po.ovarin( + self.outfile, + "Number of TF layers", + "(n_tf_wp_layers)", + tfcoil_variables.n_tf_wp_layers, + ) + + po.oblnkl(self.outfile) + + if tfcoil_variables.i_tf_turns_integer == 1: + po.ovarre( + self.outfile, + "Radial width of turn (m)", + "(dr_tf_turn)", + superconducting_tf_coil_variables.dr_tf_turn, + ) + po.ovarre( + self.outfile, + "Toroidal width of turn (m)", + "(dx_tf_turn)", + superconducting_tf_coil_variables.dx_tf_turn, + ) + po.ovarre( + self.outfile, + "Radial width of conductor (m)", + "(t_conductor_radial)", + superconducting_tf_coil_variables.t_conductor_radial, + "OP ", + ) + po.ovarre( + self.outfile, + "Toroidal width of conductor (m)", + "(t_conductor_toroidal)", + superconducting_tf_coil_variables.t_conductor_toroidal, + "OP ", + ) + po.ovarre( + self.outfile, + "Radial width of cable space", + "(dr_tf_turn_cable_space)", + superconducting_tf_coil_variables.dr_tf_turn_cable_space, + ) + po.ovarre( + self.outfile, + "Toroidal width of cable space", + "(dx_tf_turn_cable_space)", + superconducting_tf_coil_variables.dx_tf_turn_cable_space, + ) + po.ovarre( + self.outfile, + "Radius of turn cable space rounded corners (m)", + "(radius_tf_turn_cable_space_corners)", + superconducting_tf_coil_variables.radius_tf_turn_cable_space_corners, + ) + else: + po.ovarre( + self.outfile, + "Width of turn including inter-turn insulation (m)", + "(dx_tf_turn_general)", + tfcoil_variables.dx_tf_turn_general, + "OP ", + ) + po.ovarre( + self.outfile, + "Width of conductor (square) (m)", + "(t_conductor)", + tfcoil_variables.t_conductor, + "OP ", + ) + po.ovarre( + self.outfile, + "Width of space inside conductor (m)", + "(dx_tf_turn_cable_space_average)", + superconducting_tf_coil_variables.dx_tf_turn_cable_space_average, + "OP ", + ) + po.ovarre( + self.outfile, + "Radius of turn cable space rounded corners (m)", + "(radius_tf_turn_cable_space_corners)", + superconducting_tf_coil_variables.radius_tf_turn_cable_space_corners, + ) + + po.ovarre( + self.outfile, + "Steel conduit thickness (m)", + "(dx_tf_turn_steel)", + tfcoil_variables.dx_tf_turn_steel, + ) + po.ovarre( + self.outfile, + "Inter-turn insulation thickness (m)", + "(dx_tf_turn_insulation)", + tfcoil_variables.dx_tf_turn_insulation, + ) + + if tfcoil_variables.i_tf_sc_mat in {1, 2, 3, 4, 5, 7, 8, 9}: + po.osubhd(self.outfile, "Conductor information:") + po.ovarre( + self.outfile, + "Diameter of central helium channel in cable", + "(dia_tf_turn_coolant_channel)", + tfcoil_variables.dia_tf_turn_coolant_channel, + ) + po.ovarre( + self.outfile, + "Diameter of superconducting cable", + "(dia_tf_turn_superconducting_cable)", + superconducting_tf_coil_variables.dia_tf_turn_superconducting_cable, + ) + po.ovarre( + self.outfile, + "Number of superconducting cables per turn", + "(n_tf_turn_superconducting_cables)", + superconducting_tf_coil_variables.n_tf_turn_superconducting_cables, + ) + po.ovarre( + self.outfile, + "Length of superconductor in TF coil (m)", + "(len_tf_coil_superconductor)", + superconducting_tf_coil_variables.len_tf_coil_superconductor, + ) + po.ovarre( + self.outfile, + "Total length of superconductor in all TF coils (m)", + "(len_tf_superconductor_total)", + superconducting_tf_coil_variables.len_tf_superconductor_total, + ) + po.ocmmnt(self.outfile, "Fractions by area") + po.ovarre( + self.outfile, + "internal area of the cable space", + "(a_tf_turn_cable_space_no_void)", + tfcoil_variables.a_tf_turn_cable_space_no_void, + ) + po.ovarre( + self.outfile, + "True area of turn cable space with gaps and channels removed", + "(a_tf_turn_cable_space_effective)", + superconducting_tf_coil_variables.a_tf_turn_cable_space_effective, + ) + + po.ovarre( + self.outfile, + "Coolant fraction in conductor excluding central channel", + "(f_a_tf_turn_cable_space_extra_void)", + tfcoil_variables.f_a_tf_turn_cable_space_extra_void, + ) + po.ovarre( + self.outfile, + "Area of steel in turn", + "(a_tf_turn_steel)", + tfcoil_variables.a_tf_turn_steel, + ) + po.ovarre( + self.outfile, + "Area of all turn insulation in WP", + "(a_tf_coil_wp_turn_insulation)", + tfcoil_variables.a_tf_coil_wp_turn_insulation, + ) + po.ovarre( + self.outfile, + "Total insulation area in TF coil (turn and WP)", + "(a_tf_coil_inboard_insulation)", + superconducting_tf_coil_variables.a_tf_coil_inboard_insulation, + ) + po.ovarre( + self.outfile, + "Total steel area in inboard TF coil (turn and case)", + "(a_tf_coil_inboard_steel)", + superconducting_tf_coil_variables.a_tf_coil_inboard_steel, + ) + po.ovarre( + self.outfile, + "Total conductor area in WP", + "(a_tf_wp_conductor)", + tfcoil_variables.a_tf_wp_conductor, + ) + po.ovarre( + self.outfile, + "Total additional void area in WP", + "(a_tf_wp_extra_void)", + tfcoil_variables.a_tf_wp_extra_void, + ) + + po.ovarre( + self.outfile, + "Area of all coolant channels in WP", + "(a_tf_wp_coolant_channels)", + tfcoil_variables.a_tf_wp_coolant_channels, + ) + + po.ovarre( + self.outfile, + "Copper fraction of conductor", + "(f_a_tf_turn_cable_copper)", + tfcoil_variables.f_a_tf_turn_cable_copper, + ) + po.ovarre( + self.outfile, + "Superconductor fraction of conductor", + "(1-f_a_tf_turn_cable_copper)", + 1 - tfcoil_variables.f_a_tf_turn_cable_copper, + ) + ap = ( + tfcoil_variables.a_tf_wp_conductor + + tfcoil_variables.n_tf_coil_turns * tfcoil_variables.a_tf_turn_steel + + tfcoil_variables.a_tf_coil_wp_turn_insulation + + tfcoil_variables.a_tf_wp_extra_void + + tfcoil_variables.a_tf_wp_coolant_channels + ) + po.ovarrf( + self.outfile, + "Check total area fractions in winding pack = 1", + "", + ( + tfcoil_variables.a_tf_wp_conductor + + tfcoil_variables.n_tf_coil_turns + * tfcoil_variables.a_tf_turn_steel + + tfcoil_variables.a_tf_coil_wp_turn_insulation + + tfcoil_variables.a_tf_wp_extra_void + + tfcoil_variables.a_tf_wp_coolant_channels + ) + / ap, + ) + po.ovarrf( + self.outfile, + "minimum TF conductor temperature margin (K)", + "(temp_tf_superconductor_margin_min)", + tfcoil_variables.temp_tf_superconductor_margin_min, + ) + po.ovarrf( + self.outfile, + "TF conductor temperature margin (K)", + "(temp_tf_superconductor_margin)", + tfcoil_variables.temp_tf_superconductor_margin, + ) + + po.ovarin( + self.outfile, + "Elastic properties behavior", + "(i_tf_cond_eyoung_axial)", + tfcoil_variables.i_tf_cond_eyoung_axial, + ) + if tfcoil_variables.i_tf_cond_eyoung_axial == 0: + po.ocmmnt(self.outfile, " Conductor stiffness neglected") + elif tfcoil_variables.i_tf_cond_eyoung_axial == 1: + po.ocmmnt(self.outfile, " Conductor stiffness is user-input") + elif tfcoil_variables.i_tf_cond_eyoung_axial == 2: + po.ocmmnt( + self.outfile, + " Conductor stiffness is set by material-specific default", + ) + + po.ovarre( + self.outfile, + "Conductor axial Youngs modulus", + "(eyoung_cond_axial)", + tfcoil_variables.eyoung_cond_axial, + ) + po.ovarre( + self.outfile, + "Conductor transverse Youngs modulus", + "(eyoung_cond_trans)", + tfcoil_variables.eyoung_cond_trans, + ) + else: + # External casing + po.osubhd(self.outfile, "Bucking cylinder information:") + po.ovarre( + self.outfile, + "Casing cross section area (per leg) (m2)", + "(a_tf_coil_inboard_case)", + tfcoil_variables.a_tf_coil_inboard_case, + ) + po.ovarre( + self.outfile, + "Inboard leg case plasma side wall thickness (m)", + "(dr_tf_plasma_case)", + tfcoil_variables.dr_tf_plasma_case, + ) + po.ovarre( + self.outfile, + "Inboard leg plasma case area (m^2)", + "(a_tf_plasma_case)", + superconducting_tf_coil_variables.a_tf_plasma_case, + ) + po.ovarre( + self.outfile, + "Inboard leg bucking cylinder thickness (m)", + "(dr_tf_nose_case)", + tfcoil_variables.dr_tf_nose_case, + ) + po.ovarre( + self.outfile, + 'Inboard leg case inboard "nose" area (m^2)', + "(a_tf_coil_nose_case)", + superconducting_tf_coil_variables.a_tf_coil_nose_case, + ) + + # Conductor layer geometry + po.osubhd(self.outfile, "Inboard TFC conductor sector geometry:") + po.ovarre( + self.outfile, + "Inboard TFC conductor sector area with gr insulation (per leg) (m2)", + "(a_tf_wp_with_insulation)", + superconducting_tf_coil_variables.a_tf_wp_with_insulation, + ) + po.ovarre( + self.outfile, + "Inboard TFC conductor sector area, NO ground & gap (per leg) (m2)", + "(a_tf_wp_no_insulation)", + superconducting_tf_coil_variables.a_tf_wp_no_insulation, + ) + po.ovarre( + self.outfile, + "Ground wall insulation area (m^2)", + "(a_tf_wp_ground_insulation)", + superconducting_tf_coil_variables.a_tf_wp_ground_insulation, + ) + po.ovarre( + self.outfile, + "Inboard conductor sector radial thickness (m)", + "(dr_tf_wp_with_insulation)", + tfcoil_variables.dr_tf_wp_with_insulation, + ) + if physics_variables.itart == 1: + po.ovarre( + self.outfile, + "Central collumn top conductor sector radial thickness (m)", + "(dr_tf_wp_top)", + superconducting_tf_coil_variables.dr_tf_wp_top, + ) + + po.ovarre( + self.outfile, + "Ground wall insulation thickness (m)", + "(dx_tf_wp_insulation)", + tfcoil_variables.dx_tf_wp_insulation, + ) + # Turn info + po.osubhd(self.outfile, "Coil turn information:") + po.ovarre( + self.outfile, + "Number of turns per TF leg", + "(n_tf_coil_turns)", + tfcoil_variables.n_tf_coil_turns, + ) + po.ovarre( + self.outfile, + "Turn insulation thickness", + "(dx_tf_turn_insulation)", + tfcoil_variables.dx_tf_turn_insulation, + ) + po.ovarre( + self.outfile, + "Mid-plane CP cooling fraction", + "(fcoolcp)", + tfcoil_variables.fcoolcp, + ) + po.ovarre( + self.outfile, + "Area of resistive conductor per coil", + "(a_res_tf_coil_conductor)", + tfcoil_variables.a_res_tf_coil_conductor, + ) + po.ovarre( + self.outfile, + "Outboard leg current per turn (A)", + "(c_tf_turn)", + tfcoil_variables.c_tf_turn, + ) + po.ovarre( + self.outfile, + "Inboard leg conductor volume (m3)", + "(vol_cond_cp)", + tfcoil_variables.vol_cond_cp, + ) + po.ovarre( + self.outfile, + "Outboard leg volume per coil (m3)", + "(voltfleg)", + tfcoil_variables.voltfleg, + ) + + # Coil masses + po.osubhd(self.outfile, "TF coil mass:") + po.ovarre( + self.outfile, + "Superconductor mass per coil (kg)", + "(m_tf_coil_superconductor)", + tfcoil_variables.m_tf_coil_superconductor, + "OP ", + ) + po.ovarre( + self.outfile, + "Copper mass per coil (kg)", + "(m_tf_coil_copper)", + tfcoil_variables.m_tf_coil_copper, + "OP ", + ) + po.ovarre( + self.outfile, + "Steel conduit mass per coil (kg)", + "(m_tf_wp_steel_conduit)", + tfcoil_variables.m_tf_wp_steel_conduit, + "OP ", + ) + po.ovarre( + self.outfile, + "Conduit insulation mass per coil (kg)", + "(m_tf_coil_wp_turn_insulation)", + tfcoil_variables.m_tf_coil_wp_turn_insulation, + "OP ", + ) + if tfcoil_variables.i_tf_sup == TFConductorModel.SUPERCONDUCTING: + po.ovarre( + self.outfile, + "Total conduit mass per coil (kg)", + "(m_tf_coil_conductor)", + tfcoil_variables.m_tf_coil_conductor, + "OP ", + ) + + if physics_variables.itart == 1: + po.ovarre( + self.outfile, + "Mass of inboard legs (kg)", + "(whtcp)", + tfcoil_variables.whtcp, + "OP ", + ) + po.ovarre( + self.outfile, + "Mass of outboard legs (kg)", + "(whttflgs)", + tfcoil_variables.whttflgs, + "OP ", + ) + + po.ovarre( + self.outfile, + "Mass of each TF coil (kg)", + "(m_tf_coils_total/n_tf_coils)", + tfcoil_variables.m_tf_coils_total / tfcoil_variables.n_tf_coils, + "OP ", + ) + po.ovarre( + self.outfile, + "Total TF coil mass (kg)", + "(m_tf_coils_total)", + tfcoil_variables.m_tf_coils_total, + "OP ", + ) + + # Resistive coil parameters + if tfcoil_variables.i_tf_sup != TFConductorModel.SUPERCONDUCTING: + po.osubhd(self.outfile, "Resitive loss parameters:") + if tfcoil_variables.i_tf_sup == TFConductorModel.WATER_COOLED_COPPER: + po.ocmmnt( + self.outfile, + "Resistive Material : GLIDCOP AL-15 - Dispersion Strengthened Copper", + ) + elif tfcoil_variables.i_tf_sup == TFConductorModel.HELIUM_COOLED_ALUMINIUM: + po.ocmmnt( + self.outfile, "Resistive Material : Pure Aluminium (99.999+ %)" + ) + + if physics_variables.itart == 1: + po.ovarre( + self.outfile, + "CP resistivity (ohm.m)", + "(rho_cp)", + tfcoil_variables.rho_cp, + ) + po.ovarre( + self.outfile, + "Leg resistivity (ohm.m)", + "(rho_tf_leg)", + tfcoil_variables.rho_tf_leg, + ) + po.ovarre( + self.outfile, + "CP resistive power loss (W)", + "(p_cp_resistive)", + tfcoil_variables.p_cp_resistive, + ) + po.ovarre( + self.outfile, + "Total legs resitive power loss, (W)", + "(p_tf_leg_resistive)", + tfcoil_variables.p_tf_leg_resistive, + ) + po.ovarre( + self.outfile, + "joints resistive power loss (W)", + "(p_tf_joints_resistive)", + tfcoil_variables.p_tf_joints_resistive, + ) + po.ovarre( + self.outfile, + "Outboard leg resistance per coil (ohm)", + "(res_tf_leg)", + tfcoil_variables.res_tf_leg, + ) + po.ovarre( + self.outfile, + "Average CP temperature (K)", + "(temp_cp_average)", + tfcoil_variables.temp_cp_average, + ) + po.ovarre( + self.outfile, + "Average leg temperature (K)", + "(temp_tf_legs_outboard)", + tfcoil_variables.temp_tf_legs_outboard, + ) + + else: + po.ovarre( + self.outfile, + "TF resistivity (ohm.m)", + "(p_cp_resistive)", + tfcoil_variables.rho_cp, + ) + po.ovarre( + self.outfile, + "TF coil resistive power less (total) (ohm.m)", + "(p_cp_resistive)", + tfcoil_variables.p_cp_resistive, + ) + po.ovarre( + self.outfile, + "Average coil temperature (K)", + "(temp_cp_average)", + tfcoil_variables.temp_cp_average, + ) + + # Quench information + if tfcoil_variables.i_tf_sup == TFConductorModel.SUPERCONDUCTING: + po.osubhd(self.outfile, "Quench information :") + po.ovarre( + self.outfile, + "Actual quench time (or time constant) (s)", + "(t_tf_superconductor_quench)", + tfcoil_variables.t_tf_superconductor_quench, + ) + po.ovarre( + self.outfile, + "Vacuum Vessel stress on quench (Pa)", + "(vv_stress_quench)", + superconducting_tf_coil_variables.vv_stress_quench, + "OP ", + ) + po.ovarre( + self.outfile, + "Maximum allowed voltage during quench due to insulation (kV)", + "(v_tf_coil_dump_quench_max_kv)", + tfcoil_variables.v_tf_coil_dump_quench_max_kv, + ) + po.ovarre( + self.outfile, + "Actual quench voltage (kV)", + "(v_tf_coil_dump_quench_kv)", + tfcoil_variables.v_tf_coil_dump_quench_kv, + "OP ", + ) + + if tfcoil_variables.i_tf_sc_mat in {1, 2, 3, 4, 5}: + po.ovarre( + self.outfile, + "Maximum allowed temp during a quench (K)", + "(temp_tf_conductor_quench_max)", + tfcoil_variables.temp_tf_conductor_quench_max, + ) + elif tfcoil_variables == 6: + po.ocmmnt(self.outfile, "CroCo cable with jacket: ") + + if 75 in numerics.icc: + po.ovarre( + self.outfile, + "Maximum permitted TF coil current / copper area (A/m2)", + "(copperA_m2_max)", + rebco_variables.tf_coppera_m2_max, + ) + + po.ovarre( + self.outfile, + "Actual TF coil current / copper area (A/m2)", + "(copperA_m2)", + rebco_variables.tf_coppera_m2, + ) + + # TF coil radial build + po.osubhd(self.outfile, "Radial build of TF coil centre-line :") + + radius = build_variables.r_tf_inboard_in + po.obuild(self.outfile, "Innermost edge of TF coil", radius, radius) + + # Radial build for SC TF coils + if tfcoil_variables.i_tf_sup == TFConductorModel.SUPERCONDUCTING: + radius += tfcoil_variables.dr_tf_nose_case + po.obuild( + self.outfile, + 'Coil case ("nose")', + tfcoil_variables.dr_tf_nose_case, + radius, + "(dr_tf_nose_case)", + ) + + radius += tfcoil_variables.dx_tf_wp_insertion_gap + po.obuild( + self.outfile, + "Insertion gap for winding pack", + tfcoil_variables.dx_tf_wp_insertion_gap, + radius, + "(dx_tf_wp_insertion_gap)", + ) + + radius += tfcoil_variables.dx_tf_wp_insulation + po.obuild( + self.outfile, + "Winding pack ground insulation", + tfcoil_variables.dx_tf_wp_insulation, + radius, + "(dx_tf_wp_insulation)", + ) + + radius = ( + radius + + 0.5e0 * tfcoil_variables.dr_tf_wp_with_insulation + - tfcoil_variables.dx_tf_wp_insulation + - tfcoil_variables.dx_tf_wp_insertion_gap + ) + po.obuild( + self.outfile, + "Winding - first half", + tfcoil_variables.dr_tf_wp_with_insulation / 2e0 + - tfcoil_variables.dx_tf_wp_insulation + - tfcoil_variables.dx_tf_wp_insertion_gap, + radius, + "(dr_tf_wp_with_insulation/2-dx_tf_wp_insulation-dx_tf_wp_insertion_gap)", + ) + + radius = ( + radius + + 0.5e0 * tfcoil_variables.dr_tf_wp_with_insulation + - tfcoil_variables.dx_tf_wp_insulation + - tfcoil_variables.dx_tf_wp_insertion_gap + ) + po.obuild( + self.outfile, + "Winding - second half", + tfcoil_variables.dr_tf_wp_with_insulation / 2e0 + - tfcoil_variables.dx_tf_wp_insulation + - tfcoil_variables.dx_tf_wp_insertion_gap, + radius, + "(dr_tf_wp_with_insulation/2-dx_tf_wp_insulation-dx_tf_wp_insertion_gap)", + ) + + radius += tfcoil_variables.dx_tf_wp_insulation + po.obuild( + self.outfile, + "Winding pack insulation", + tfcoil_variables.dx_tf_wp_insulation, + radius, + "(dx_tf_wp_insulation)", + ) + + radius += tfcoil_variables.dx_tf_wp_insertion_gap + po.obuild( + self.outfile, + "Insertion gap for winding pack", + tfcoil_variables.dx_tf_wp_insertion_gap, + radius, + "(dx_tf_wp_insertion_gap)", + ) + + radius += tfcoil_variables.dr_tf_plasma_case + po.obuild( + self.outfile, + "Plasma side case min radius", + tfcoil_variables.dr_tf_plasma_case, + radius, + "(dr_tf_plasma_case)", + ) + + po.obuild( + self.outfile, + "Plasma side case max radius", + build_variables.r_tf_inboard_out, + radius, + "(r_tf_inboard_out)", + ) + + # Radial build for restive coil + else: + radius += tfcoil_variables.dr_tf_nose_case + po.obuild( + self.outfile, + "Coil bucking cylindre", + tfcoil_variables.dr_tf_nose_case, + radius, + "(dr_tf_nose_case)", + ) + + radius += tfcoil_variables.dx_tf_wp_insulation + po.obuild( + self.outfile, + "Conductor ground insulation", + tfcoil_variables.dx_tf_wp_insulation, + radius, + "(dx_tf_wp_insulation)", + ) + + radius = ( + radius + + 0.5e0 * tfcoil_variables.dr_tf_wp_with_insulation + - tfcoil_variables.dx_tf_wp_insulation + ) + po.obuild( + self.outfile, + "Conductor - first half", + tfcoil_variables.dr_tf_wp_with_insulation / 2e0 + - tfcoil_variables.dx_tf_wp_insulation, + radius, + "(tfcoil_variables.dr_tf_wp_with_insulation/2-tfcoil_variables.dx_tf_wp_insulation)", + ) + + radius = ( + radius + + 0.5e0 * tfcoil_variables.dr_tf_wp_with_insulation + - tfcoil_variables.dx_tf_wp_insulation + ) + po.obuild( + self.outfile, + "Conductor - second half", + tfcoil_variables.dr_tf_wp_with_insulation / 2e0 + - tfcoil_variables.dx_tf_wp_insulation, + radius, + "(tfcoil_variables.dr_tf_wp_with_insulation/2-tfcoil_variables.dx_tf_wp_insulation)", + ) + + radius += tfcoil_variables.dx_tf_wp_insulation + po.obuild( + self.outfile, + "Conductor ground insulation", + tfcoil_variables.dx_tf_wp_insulation, + radius, + "(dx_tf_wp_insulation)", + ) + + radius += tfcoil_variables.dr_tf_plasma_case + po.obuild( + self.outfile, + "Plasma side TF coil support", + tfcoil_variables.dr_tf_plasma_case, + radius, + "(dr_tf_plasma_case)", + ) + + # Radial build consistency check + if not ( + abs(radius - build_variables.r_tf_inboard_in - build_variables.dr_tf_inboard) + < 10.0e0 * np.finfo(float(radius)).eps + ): + logger.error( + "TF coil dimensions are not consistent. Radius of plasma-facing side of inner leg should be " + f"{build_variables.r_tf_inboard_in + build_variables.dr_tf_inboard}m" + ) + + tf_total_height = ( + build_variables.dh_tf_inner_bore + 2 * build_variables.dr_tf_inboard + ) + tf_total_width = ( + build_variables.dr_tf_inner_bore + + build_variables.dr_tf_inboard + + build_variables.dr_tf_outboard + ) + po.oblnkl(self.outfile) + po.obuild( + self.outfile, + "Total height and width of TFC [m]", + tf_total_height, + tf_total_width, + ) + + # Top section TF coil radial build (physics_variables.itart = 1 only) + if ( + physics_variables.itart == 1 + and tfcoil_variables.i_tf_sup != TFConductorModel.SUPERCONDUCTING + ): + po.osubhd(self.outfile, "Radial build of TF coil at central collumn top :") + # write(self.outfile,5) + + # Restart the radial build at bucking cylindre inner radius + radius = build_variables.r_tf_inboard_in + po.obuild(self.outfile, "Innermost edge of TF coil", radius, radius) + + radius += tfcoil_variables.dr_tf_nose_case + po.obuild( + self.outfile, + "Coil bucking cylindre", + tfcoil_variables.dr_tf_nose_case, + radius, + "(dr_tf_nose_case)", + ) + + radius += tfcoil_variables.dx_tf_wp_insulation + po.obuild( + self.outfile, + "Conductor ground insulation", + tfcoil_variables.dx_tf_wp_insulation, + radius, + "(dx_tf_wp_insulation)", + ) + + radius = ( + radius + + 0.5e0 * superconducting_tf_coil_variables.dr_tf_wp_top + - tfcoil_variables.dx_tf_wp_insulation + ) + po.obuild( + self.outfile, + "Conductor - first half", + 0.5e0 * superconducting_tf_coil_variables.dr_tf_wp_top + - tfcoil_variables.dx_tf_wp_insulation, + radius, + "(dr_tf_wp_top/2-dx_tf_wp_insulation)", + ) + + radius = ( + radius + + 0.5e0 * superconducting_tf_coil_variables.dr_tf_wp_top + - tfcoil_variables.dx_tf_wp_insulation + ) + po.obuild( + self.outfile, + "Conductor - second half", + 0.5e0 * superconducting_tf_coil_variables.dr_tf_wp_top + - tfcoil_variables.dx_tf_wp_insulation, + radius, + "(dr_tf_wp_top/2-dx_tf_wp_insulation)", + ) + + radius += tfcoil_variables.dx_tf_wp_insulation + po.obuild( + self.outfile, + "Conductor ground insulation", + tfcoil_variables.dx_tf_wp_insulation, + radius, + "(dx_tf_wp_insulation)", + ) + + radius += tfcoil_variables.dr_tf_plasma_case + po.obuild( + self.outfile, + "Plasma side TF coil support", + tfcoil_variables.dr_tf_plasma_case, + radius, + "(dr_tf_plasma_case)", + ) + + # Consistency check + if abs(radius - build_variables.r_cp_top) < np.finfo(float(radius)).eps: + po.ocmmnt(self.outfile, "Top TF coil dimensions are consistent") + else: + po.ocmmnt(self.outfile, "ERROR: TF coil dimensions are NOT consistent:") + po.ovarre( + self.outfile, + "Radius of plasma-facing side of inner leg SHOULD BE [m]", + "", + build_variables.r_cp_top, + ) + po.oblnkl(self.outfile) + def output_tf_superconductor_info(self): """Output TF superconductor information""" po.oheadr(self.outfile, "TF Coils Superconductor Information") From ab5eaec86f03cb6026d285c9c412f2bf64896d38 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Fri, 15 May 2026 15:15:20 +0100 Subject: [PATCH 37/37] Post rebase changes --- process/models/tfcoil/base.py | 8 ++++---- process/models/tfcoil/superconducting.py | 25 ++++++++++++------------ 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/process/models/tfcoil/base.py b/process/models/tfcoil/base.py index eab66ebb1..55c6ba969 100644 --- a/process/models/tfcoil/base.py +++ b/process/models/tfcoil/base.py @@ -798,21 +798,21 @@ def output_general_tf_info(self) -> None: self.outfile, "Inboard leg inner radius (m)", "(r_tf_inboard_in)", - build_variables.r_tf_inboard_in, + self.data.build.r_tf_inboard_in, "OP ", ) po.ovarre( self.outfile, "Inboard leg centre radius (m)", "(r_tf_inboard_mid)", - build_variables.r_tf_inboard_mid, + self.data.build.r_tf_inboard_mid, "OP ", ) po.ovarre( self.outfile, "Inboard leg outer radius (m)", "(r_tf_inboard_out)", - build_variables.r_tf_inboard_out, + self.data.build.r_tf_inboard_out, "OP ", ) po.oblnkl(self.outfile) @@ -1004,7 +1004,7 @@ def output_general_tf_info(self) -> None: self.outfile, "Distance from the midplane to the top of the centrepost (m)", "(z_tf_inside_half + dr_tf_outboard)", - build_variables.z_tf_inside_half + build_variables.dr_tf_outboard, + self.data.build.z_tf_inside_half + self.data.build.dr_tf_outboard, ) po.oblnkl(self.outfile) diff --git a/process/models/tfcoil/superconducting.py b/process/models/tfcoil/superconducting.py index 6d8286bbd..d654faafa 100644 --- a/process/models/tfcoil/superconducting.py +++ b/process/models/tfcoil/superconducting.py @@ -450,7 +450,6 @@ def output_general_superconducting_tf_info(self) -> None: base `TFCoil` class, which is relevant for all TF coil types. """ - po.oheadr(self.outfile, "General Superconducting TF Coil Parameters ") # Turn/WP gemoetry if tfcoil_variables.i_tf_sup == TFConductorModel.SUPERCONDUCTING: @@ -1261,7 +1260,7 @@ def output_general_superconducting_tf_info(self) -> None: # TF coil radial build po.osubhd(self.outfile, "Radial build of TF coil centre-line :") - radius = build_variables.r_tf_inboard_in + radius = self.data.build.r_tf_inboard_in po.obuild(self.outfile, "Innermost edge of TF coil", radius, radius) # Radial build for SC TF coils @@ -1355,7 +1354,7 @@ def output_general_superconducting_tf_info(self) -> None: po.obuild( self.outfile, "Plasma side case max radius", - build_variables.r_tf_inboard_out, + self.data.build.r_tf_inboard_out, radius, "(r_tf_inboard_out)", ) @@ -1428,21 +1427,21 @@ def output_general_superconducting_tf_info(self) -> None: # Radial build consistency check if not ( - abs(radius - build_variables.r_tf_inboard_in - build_variables.dr_tf_inboard) + abs(radius - self.data.build.r_tf_inboard_in - self.data.build.dr_tf_inboard) < 10.0e0 * np.finfo(float(radius)).eps ): logger.error( "TF coil dimensions are not consistent. Radius of plasma-facing side of inner leg should be " - f"{build_variables.r_tf_inboard_in + build_variables.dr_tf_inboard}m" + f"{self.data.build.r_tf_inboard_in + self.data.build.dr_tf_inboard}m" ) tf_total_height = ( - build_variables.dh_tf_inner_bore + 2 * build_variables.dr_tf_inboard + self.data.build.dh_tf_inner_bore + 2 * self.data.build.dr_tf_inboard ) tf_total_width = ( - build_variables.dr_tf_inner_bore - + build_variables.dr_tf_inboard - + build_variables.dr_tf_outboard + self.data.build.dr_tf_inner_bore + + self.data.build.dr_tf_inboard + + self.data.build.dr_tf_outboard ) po.oblnkl(self.outfile) po.obuild( @@ -1461,7 +1460,7 @@ def output_general_superconducting_tf_info(self) -> None: # write(self.outfile,5) # Restart the radial build at bucking cylindre inner radius - radius = build_variables.r_tf_inboard_in + radius = self.data.build.r_tf_inboard_in po.obuild(self.outfile, "Innermost edge of TF coil", radius, radius) radius += tfcoil_variables.dr_tf_nose_case @@ -1529,7 +1528,7 @@ def output_general_superconducting_tf_info(self) -> None: ) # Consistency check - if abs(radius - build_variables.r_cp_top) < np.finfo(float(radius)).eps: + if abs(radius - self.data.build.r_cp_top) < np.finfo(float(radius)).eps: po.ocmmnt(self.outfile, "Top TF coil dimensions are consistent") else: po.ocmmnt(self.outfile, "ERROR: TF coil dimensions are NOT consistent:") @@ -1537,7 +1536,7 @@ def output_general_superconducting_tf_info(self) -> None: self.outfile, "Radius of plasma-facing side of inner leg SHOULD BE [m]", "", - build_variables.r_cp_top, + self.data.build.r_cp_top, ) po.oblnkl(self.outfile) @@ -3917,7 +3916,7 @@ def tf_cable_in_conduit_averaged_turn_geometry( else: logger.error( "Cable space area problem; artificially set rounded corner " - "radius to 0. %s %s", + "radius to 0. %s %s", a_tf_turn_cable_space_no_void, dx_tf_turn_cable_space_average, )