diff --git a/documentation/source/eng-models/central-solenoid.md b/documentation/source/eng-models/central-solenoid.md index fae589980a..a89de20998 100644 --- a/documentation/source/eng-models/central-solenoid.md +++ b/documentation/source/eng-models/central-solenoid.md @@ -433,7 +433,7 @@ solenoid usually consists of several coils, which can have opposite currents. T forces that tend to separate the coils. To prevent this, ITER has "tie-plates" which hold the coil segments together. PROCESS has a corresponding structure, known as the pre-compression structure, made up of two cylinders, one on the inside and one on the outside, of the same thickness. The -radii of the two cylinders are `dr_bore` and `dr_bore` + `dr_cs`. The thickness is derived using the +radii of the two cylinders are `dr_cs_bore` and `dr_cs_bore` + `dr_cs`. The thickness is derived using the separation force and the combined cross-sectional area: $$ diff --git a/process/core/io/plot/summary.py b/process/core/io/plot/summary.py index 536c671b65..7f71600954 100644 --- a/process/core/io/plot/summary.py +++ b/process/core/io/plot/summary.py @@ -2664,12 +2664,12 @@ def plot_main_plasma_information( f"Extra heat power: {mfile.get('p_hcd_secondary_extra_heat_mw', scan=scan):.4f} MW\n" f"$\\eta_{{\\text{{CD,sec}}}}$: {mfile.get('eta_cd_hcd_secondary', scan=scan):.4f} A/W | $\\langle\\zeta_{{\\text{{CD,sec}}}}\\rangle$: {mfile.get('eta_cd_dimensionless_hcd_secondary', scan=scan):.4f} \n" f"$\\gamma_{{\\text{{CD,sec}}}}$: {mfile.get('eta_cd_norm_hcd_secondary', scan=scan):.4f} $\\times 10^{{20}} \\mathrm{{A}} / \\mathrm{{Wm}}^2$\n" - f"Current driven by secondary: {mfile.get('c_hcd_secondary_driven', scan=scan) / 1e6:.3f} MA\n" + f"Current driven by secondary: {mfile.get('c_hcd_secondary_driven', scan=scan) / 1e6:.3f} MA" ) axis.text( - 0.66, - 0.6, + 0.73, + 0.675, textstr_hcd, fontsize=9, verticalalignment="top", @@ -7948,7 +7948,7 @@ def plot_pf_coils( coils_dz = [] coil_text = [] - dr_bore = mfile.get("dr_bore", scan=scan) + dr_cs_bore = mfile.get("dr_cs_bore", scan=scan) dr_cs = mfile.get("dr_cs", scan=scan) dz_cs_full = mfile.get("dz_cs_full", scan=scan) @@ -7977,7 +7977,7 @@ def plot_pf_coils( coils_z=coils_z, coils_dr=coils_dr, coils_dz=coils_dz, - dr_bore=dr_bore, + dr_cs_bore=dr_cs_bore, dr_cs=dr_cs, ohdz=dz_cs_full, ) @@ -9946,7 +9946,7 @@ def plot_cs_coil_structure( dr_cs_full = mfile.get("dr_cs_full", scan=scan) dz_cs_full = mfile.get("dz_cs_full", scan=scan) dz_cs = mfile.get("dz_cs_full", scan=scan) - dr_bore = mfile.get("dr_bore", scan=scan) + dr_cs_bore = mfile.get("dr_cs_bore", scan=scan) r_cs_current_filaments_array = [ mfile.get(f"r_pf_cs_current_filaments{i}", scan=scan) for i in range(NFIXMX) ] @@ -9956,7 +9956,7 @@ def plot_cs_coil_structure( # Plot the right side of the CS right_cs = patches.Rectangle( - (dr_bore, -dz_cs / 2), + (dr_cs_bore, -dz_cs / 2), dr_cs, dz_cs, edgecolor="black", @@ -9967,8 +9967,8 @@ def plot_cs_coil_structure( # Plot the bore of the machine bore_rect = patches.Rectangle( - (-dr_bore, -dz_cs / 2), - dr_bore * 2, + (-dr_cs_bore, -dz_cs / 2), + dr_cs_bore * 2, dz_cs, edgecolor="black", facecolor="lightgrey", @@ -9977,7 +9977,7 @@ def plot_cs_coil_structure( axis.add_patch(bore_rect) left_cs = patches.Rectangle( - (-dr_bore - dr_cs, -dz_cs / 2), + (-dr_cs_bore - dr_cs, -dz_cs / 2), dr_cs, dz_cs, edgecolor="black", @@ -9995,9 +9995,9 @@ def plot_cs_coil_structure( if dr_cs_turn > 0: n_lines = int(dr_cs / dr_cs_turn) for i in range(1, n_lines): - x = dr_bore + i * dr_cs_turn + x = dr_cs_bore + i * dr_cs_turn axis.plot([x, x], [-dz_cs / 2, dz_cs / 2], **t_kwargs) - x_left = -dr_bore - dr_cs + i * dr_cs_turn + x_left = -dr_cs_bore - dr_cs + i * dr_cs_turn axis.plot([x_left, x_left], [-dz_cs / 2, dz_cs / 2], **t_kwargs) # Plot horizontal lines (along Z) for each turn if dz_cs_turn > 0: @@ -10005,9 +10005,9 @@ def plot_cs_coil_structure( for j in range(1, n_hlines): y = -dz_cs / 2 + j * dz_cs_turn # Right CS - axis.plot([dr_bore, dr_bore + dr_cs], [y, y], **t_kwargs) + axis.plot([dr_cs_bore, dr_cs_bore + dr_cs], [y, y], **t_kwargs) # Left CS - axis.plot([-dr_bore - dr_cs, -dr_bore], [y, y], **t_kwargs) + axis.plot([-dr_cs_bore - dr_cs, -dr_cs_bore], [y, y], **t_kwargs) l_kwargs = {"color": "black", "linestyle": "--", "linewidth": 0.6, "alpha": 0.5} @@ -10015,14 +10015,14 @@ def plot_cs_coil_structure( axis.axhline(y=0.0, **l_kwargs) # Plot a vertical line at x = 0.0 axis.axvline(x=0.0, **l_kwargs) - # Plot a vertical line at x = dr_bore - axis.axvline(x=dr_bore, **l_kwargs) - # Plot a vertical line at x = -dr_bore - axis.axvline(x=-dr_bore, **l_kwargs) - # Plot a vertical line at x = dr_bore + dr_cs - axis.axvline(x=(dr_bore + dr_cs), **l_kwargs) - # Plot a vertical line at x = -dr_bore - dr_cs - axis.axvline(x=-(dr_bore + dr_cs), **l_kwargs) + # Plot a vertical line at x = dr_cs_bore + axis.axvline(x=dr_cs_bore, **l_kwargs) + # Plot a vertical line at x = -dr_cs_bore + axis.axvline(x=-dr_cs_bore, **l_kwargs) + # Plot a vertical line at x = dr_cs_bore + dr_cs + axis.axvline(x=(dr_cs_bore + dr_cs), **l_kwargs) + # Plot a vertical line at x = -dr_cs_bore - dr_cs + axis.axvline(x=-(dr_cs_bore + dr_cs), **l_kwargs) # Plot a vertical line at y= dz_cs / 2 axis.axhline(y=(dz_cs / 2), **l_kwargs) # Plot a vertical line at y= -dz_cs / 2 diff --git a/process/data_structure/build_variables.py b/process/data_structure/build_variables.py index 1ac5ef404d..c5fd2f0b98 100644 --- a/process/data_structure/build_variables.py +++ b/process/data_structure/build_variables.py @@ -106,7 +106,10 @@ class BuildData: """upper first wall thickness (m)""" dr_bore: float = 1.42 - """central solenoid inboard radius (m) (`iteration variable 29`)""" + """Machine centre bore gap inboard radius (m) (`iteration variable 29`)""" + + dr_cs_bore: float = 1.42 + """Central solenoid bore radius [m]""" f_z_cryostat: float = 4.268 """cryostat lid height scaling factor (tokamaks)""" diff --git a/process/models/build.py b/process/models/build.py index f7846ec457..3d7f49109c 100644 --- a/process/models/build.py +++ b/process/models/build.py @@ -1672,43 +1672,6 @@ def calculate_radial_build(self, output: bool): self.data.build.dz_fw_plasma_gap, ) - # Calculate pre-compression structure thickness - if ( - CSPrecompressionConfiguration(self.data.build.i_cs_precomp) - == CSPrecompressionConfiguration.CS_PRECOMPRESSION_STRUCTURE_PRESENT - and self.data.build.i_tf_inside_cs == TFCSRadialConfiguration.TF_OUTSIDE_CS - ): - self.data.build.dr_cs_precomp = self.data.build.fseppc / ( - 2.0e0 - * np.pi - * self.data.build.fcspc - * self.data.build.sigallpc - * ( - self.data.build.dr_bore - + self.data.build.dr_bore - + self.data.build.dr_cs - ) - ) - elif ( - CSPrecompressionConfiguration(self.data.build.i_cs_precomp) - == CSPrecompressionConfiguration.CS_PRECOMPRESSION_STRUCTURE_PRESENT - and self.data.build.i_tf_inside_cs == TFCSRadialConfiguration.TF_INSIDE_CS - ): - self.data.build.dr_cs_precomp = self.data.build.fseppc / ( - 2.0e0 - * np.pi - * self.data.build.fcspc - * self.data.build.sigallpc - * ( - 2.0 * self.data.build.dr_bore - + 2.0 * self.data.build.dr_tf_inboard - + 2.0 * self.data.build.dr_cs_tf_gap - + self.data.build.dr_cs - ) - ) - else: - self.data.build.dr_cs_precomp = 0.0e0 - # Issue #514 Radial dimensions of inboard leg # Calculate self.data.build.dr_tf_inboard if # self.data.tfcoil.dr_tf_wp_with_insulation is an iteration variable (140) @@ -1720,14 +1683,34 @@ def calculate_radial_build(self, output: bool): ) if self.data.build.i_tf_inside_cs == TFCSRadialConfiguration.TF_INSIDE_CS: - self.data.build.r_tf_inboard_in = ( + self.data.build.r_tf_inboard_in = self.data.build.dr_bore + # CS bore radius [m] + self.data.build.dr_cs_bore = ( self.data.build.dr_bore - # NOTE: dr_bore is just the hollow space, the - # true dr_bore size used for flux calculations - # is dr_bore + dr_tf_inboard + dr_cs_tf_gap + + self.data.build.dr_tf_inboard + + self.data.build.dr_cs_tf_gap ) else: + self.data.build.dr_cs_bore = self.data.build.dr_bore + + # Calculate pre-compression structure thickness + if ( + CSPrecompressionConfiguration(self.data.build.i_cs_precomp) + == CSPrecompressionConfiguration.CS_PRECOMPRESSION_STRUCTURE_PRESENT + ): + self.data.build.dr_cs_precomp = self.data.build.fseppc / ( + 2.0e0 + * np.pi + * self.data.build.fcspc + * self.data.build.sigallpc + * (2.0 * self.data.build.dr_cs_bore + self.data.build.dr_cs) + ) + else: + self.data.build.dr_cs_precomp = 0.0e0 + + if self.data.build.i_tf_inside_cs != TFCSRadialConfiguration.TF_INSIDE_CS: # Inboard side inner radius [m] + # This is not calculated above because it requires the dr_cs_precomp self.data.build.r_tf_inboard_in = ( self.data.build.dr_bore + self.data.build.dr_cs @@ -1916,7 +1899,7 @@ def calculate_radial_build(self, output: bool): + 0.5e0 * self.data.build.dr_tf_outboard ) - # TF coil horizontal self.data.build.dr_bore [m] + # TF coil horizontal bore at mid-plane [m] self.data.build.dr_tf_inner_bore = ( self.data.build.r_tf_outboard_mid - 0.5e0 * self.data.build.dr_tf_outboard ) - (self.data.build.r_tf_inboard_mid - 0.5e0 * self.data.build.dr_tf_inboard) @@ -2050,21 +2033,6 @@ def calculate_radial_build(self, output: bool): "OP ", ) - if self.data.build.i_tf_inside_cs == TFCSRadialConfiguration.TF_INSIDE_CS: - po.ocmmnt( - self.outfile, - ( - "\n " - "(The stated machine dr_bore size is just for the hollow space, " - ), - ) - po.ocmmnt( - self.outfile, - ( - "the true dr_bore size used for calculations is " - "dr_bore + dr_tf_inboard + dr_cs_tf_gap)\n" - ), - ) if ( self.data.build.i_tf_inside_cs == TFCSRadialConfiguration.TF_INSIDE_CS and self.data.tfcoil.i_tf_bucking >= 2 diff --git a/process/models/geometry/pfcoil.py b/process/models/geometry/pfcoil.py index 1d6bf76a42..0af2e57506 100644 --- a/process/models/geometry/pfcoil.py +++ b/process/models/geometry/pfcoil.py @@ -13,7 +13,7 @@ def pfcoil_geometry( coils_z: list[float], coils_dr: list[float], coils_dz: list[float], - dr_bore: float, + dr_cs_bore: float, dr_cs: float, ohdz: float, ) -> tuple[np.ndarray, np.ndarray, RectangleGeometry]: @@ -30,7 +30,7 @@ def pfcoil_geometry( list of pf coil radial thicknesses coils_dz: list of pf coil vertical thicknesses - dr_bore: + dr_cs_bore: central solenoid inboard radius dr_cs: central solenoid thickness @@ -55,7 +55,7 @@ def pfcoil_geometry( z_points.append([z_1, z_2, z_2, z_1, z_1]) central_coil = RectangleGeometry( - anchor_x=dr_bore, anchor_z=(-ohdz / 2), width=dr_cs, height=ohdz + anchor_x=dr_cs_bore, anchor_z=(-ohdz / 2), width=dr_cs, height=ohdz ) return r_points, z_points, central_coil diff --git a/process/models/pfcoil.py b/process/models/pfcoil.py index fc0cd99df6..437951fcf8 100644 --- a/process/models/pfcoil.py +++ b/process/models/pfcoil.py @@ -182,7 +182,7 @@ def pfcoil(self): z_tf_inside_half=self.data.build.z_tf_inside_half, f_z_cs_tf_internal=self.data.pf_coil.f_z_cs_tf_internal, dr_cs=self.data.build.dr_cs, - dr_bore=self.data.build.dr_bore, + dr_cs_bore=self.data.build.dr_cs_bore, ) self.data.pf_coil.z_cs_upper = self.data.pf_coil.z_pf_coil_upper[ @@ -649,9 +649,9 @@ def pfcoil(self): * np.pi * np.pi * ( - (self.data.build.dr_bore * self.data.build.dr_bore) + (self.data.build.dr_cs_bore * self.data.build.dr_cs_bore) + (self.data.build.dr_cs * self.data.build.dr_cs) / 6.0e0 - + (self.data.build.dr_cs * self.data.build.dr_bore) / 2.0e0 + + (self.data.build.dr_cs * self.data.build.dr_cs_bore) / 2.0e0 ) / (self.data.pf_coil.dz_cs_full) ) @@ -1050,7 +1050,7 @@ def pfcoil(self): c += 1 self.data.pf_coil.itr_sum += ( - (self.data.build.dr_bore + 0.5 * self.data.build.dr_cs) + (self.data.build.dr_cs_bore + 0.5 * self.data.build.dr_cs) * self.data.pf_coil.n_pf_coil_turns[self.data.pf_coil.n_cs_pf_coils - 1] * self.data.pf_coil.c_pf_coil_turn_peak_input[ self.data.pf_coil.n_cs_pf_coils - 1 @@ -1543,14 +1543,14 @@ def tf_pf_collision_detector(self): if self.data.pf_coil.r_pf_coil_middle_group_array[ ii, ij ] <= ( # Inboard TF coil collision - self.data.build.dr_bore + self.data.build.dr_cs_bore + self.data.build.dr_cs + self.data.build.dr_cs_precomp + self.data.build.dr_cs_tf_gap + self.data.build.dr_tf_inboard + self.data.pf_coil.r_pf_coil_middle[i] ) and self.data.pf_coil.r_pf_coil_middle_group_array[ii, ij] >= ( - self.data.build.dr_bore + self.data.build.dr_cs_bore + self.data.build.dr_cs + self.data.build.dr_cs_precomp + self.data.build.dr_cs_tf_gap @@ -3009,7 +3009,7 @@ def calculate_cs_geometry( z_tf_inside_half: float, f_z_cs_tf_internal: float, dr_cs: float, - dr_bore: float, + dr_cs_bore: float, ) -> CSGeometry: """Calculate the geometry of the Central Solenoid (CS) coil. @@ -3021,8 +3021,8 @@ def calculate_cs_geometry( Fractional height of CS relative to TF bore dr_cs : float Thickness of the CS coil (m) - dr_bore : float - Radius of the TF bore (m) + dr_cs_bore : float + Radius of the CS bore (m) Returns ------- @@ -3030,7 +3030,7 @@ def calculate_cs_geometry( Data class containing the geometry parameters of the CS coil """ # Central Solenoid mean radius - r_cs_middle = dr_bore + (0.5e0 * dr_cs) + r_cs_middle = dr_cs_bore + (0.5e0 * dr_cs) # Scale the CS height relative to TF bore height z_cs_half = z_tf_inside_half * f_z_cs_tf_internal @@ -3234,7 +3234,7 @@ def ohcalc(self): z_tf_inside_half=self.data.build.z_tf_inside_half, f_z_cs_tf_internal=self.data.pf_coil.f_z_cs_tf_internal, dr_cs=self.data.build.dr_cs, - dr_bore=self.data.build.dr_bore, + dr_cs_bore=self.data.build.dr_cs_bore, ) self.data.pf_coil.z_cs_upper = self.data.pf_coil.z_pf_coil_upper[ @@ -3870,8 +3870,8 @@ def output_cs_structure(self) -> None: op.ovarre( self.outfile, "Radial thickness of the CS bore [m]", - "(dr_bore)", - self.data.build.dr_bore, + "(dr_cs_bore)", + self.data.build.dr_cs_bore, "OP ", ) op.oblnkl(self.outfile) diff --git a/tests/unit/models/test_pfcoil.py b/tests/unit/models/test_pfcoil.py index 14e60ac74c..859f7b5608 100644 --- a/tests/unit/models/test_pfcoil.py +++ b/tests/unit/models/test_pfcoil.py @@ -2048,7 +2048,7 @@ def test_brookscoil(pfcoil): @pytest.mark.parametrize( - ("z_tf_inside_half", "f_z_cs_tf_internal", "dr_cs", "dr_bore", "expected"), + ("z_tf_inside_half", "f_z_cs_tf_internal", "dr_cs", "dr_cs_bore", "expected"), [ # Typical values ( @@ -2101,13 +2101,13 @@ def test_brookscoil(pfcoil): ], ) def test_calculate_cs_geometry( - cs_coil, z_tf_inside_half, f_z_cs_tf_internal, dr_cs, dr_bore, expected + cs_coil, z_tf_inside_half, f_z_cs_tf_internal, dr_cs, dr_cs_bore, expected ): result = cs_coil.calculate_cs_geometry( z_tf_inside_half=z_tf_inside_half, f_z_cs_tf_internal=f_z_cs_tf_internal, dr_cs=dr_cs, - dr_bore=dr_bore, + dr_cs_bore=dr_cs_bore, ) for field in fields(result): assert pytest.approx(getattr(result, field.name)) == getattr( @@ -2436,7 +2436,7 @@ def test_pfcoil(monkeypatch, pfcoil): monkeypatch.setattr(pfcoil.data.build, "dr_tf_outboard", 1.4) monkeypatch.setattr(pfcoil.data.build, "dr_tf_inboard", 1.4) monkeypatch.setattr(pfcoil.data.build, "r_tf_outboard_mid", 1.66e1) - monkeypatch.setattr(pfcoil.data.build, "dr_bore", 2.15) + monkeypatch.setattr(pfcoil.data.build, "dr_cs_bore", 2.15) monkeypatch.setattr(pfcoil.data.fwbs, "den_steel", 7.8e3) monkeypatch.setattr(pfcoil.data.pf_coil, "dr_pf_cs_middle_offset", 0.0) monkeypatch.setattr(pfcoil.data.pf_coil, "m_pf_coil_structure_total", 0.0) @@ -2584,7 +2584,7 @@ def test_ohcalc(monkeypatch, reinitialise_error_module, cs_coil): monkeypatch.setattr(cs_coil.data.build, "z_tf_inside_half", 8.864) monkeypatch.setattr(cs_coil.data.build, "dr_cs", 6.510e-1) monkeypatch.setattr(cs_coil.data.fwbs, "den_steel", 7.8e3) - monkeypatch.setattr(cs_coil.data.build, "dr_bore", 2.6745) + monkeypatch.setattr(cs_coil.data.build, "dr_cs_bore", 2.6745) monkeypatch.setattr(cs_coil.data.pf_coil, "n_cs_pf_coils", 5) monkeypatch.setattr(cs_coil.data.pf_coil, "b_cs_peak_flat_top_end", 1.4e1) monkeypatch.setattr(cs_coil.data.pf_coil, "j_cs_flat_top_end", 1.693e7)