From ec87eb7cf549691db6239c07618a88c36f4faf12 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Wed, 4 Feb 2026 11:37:02 +0000 Subject: [PATCH 1/5] Add method to calculate D-shaped inboard blanket segment poloidal length --- process/blanket_library.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/process/blanket_library.py b/process/blanket_library.py index aa447c98f..0c38d09aa 100644 --- a/process/blanket_library.py +++ b/process/blanket_library.py @@ -1008,6 +1008,26 @@ def thermo_hydraulic_model_pressure_drop_calculations(self, output: bool): dpres_blkt_outboard_coolant, ] + @staticmethod + def calculate_dshaped_inboard_blkt_segment_poloidal( + dz_blkt_half: float, n_blkt_inboard_modules_poloidal: int + ) -> float: + """Calculations for D-shaped inboard blanket module poloidal segment length + + :param dz_blkt_half: Half-height of the blanket module (m) + :type dz_blkt_half: float + :param n_blkt_inboard_modules_poloidal: Number of inboard blanket modules in poloidal direction + :type n_blkt_inboard_modules_poloidal: int + + :return: Segment length of inboard blanket module in poloidal direction (m) + :rtype: float + + """ + + # D-shaped machine + # Segment vertical inboard surface (m) + return (2.0 * dz_blkt_half) / n_blkt_inboard_modules_poloidal + def blanket_module_poloidal_height(self): """Calculations for blanket module poloidal height author: J. Morris, CCFE, Culham Science Centre From aad84d7ed6bdf0515f848070aafd7b94ba147251 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Wed, 4 Feb 2026 11:40:42 +0000 Subject: [PATCH 2/5] Add method to calculate D-shaped outboard blanket segment poloidal length --- process/blanket_library.py | 64 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/process/blanket_library.py b/process/blanket_library.py index 0c38d09aa..86b2af224 100644 --- a/process/blanket_library.py +++ b/process/blanket_library.py @@ -1028,6 +1028,70 @@ def calculate_dshaped_inboard_blkt_segment_poloidal( # Segment vertical inboard surface (m) return (2.0 * dz_blkt_half) / n_blkt_inboard_modules_poloidal + @staticmethod + def calculate_dshaped_outboard_blkt_segment_poloidal( + n_blkt_outboard_modules_poloidal: int, + dr_fw_plasma_gap_inboard: float, + rminor: float, + dr_fw_plasma_gap_outboard: float, + dz_blkt_half: float, + n_divertors: int, + f_ster_div_single: float, + ) -> float: + """ + Calculations for D-shaped outboard blanket module poloidal segment length + + :param n_blkt_outboard_modules_poloidal: Number of outboard blanket modules in poloidal direction + :type n_blkt_outboard_modules_poloidal: int + :param dr_fw_plasma_gap_inboard: Radial gap between inboard first wall and plasma (m) + :type dr_fw_plasma_gap_inboard: float + :param rminor: Minor radius of the plasma (m) + :type rminor: float + :param dr_fw_plasma_gap_outboard: Radial gap between outboard first wall and plasma (m) + :type dr_fw_plasma_gap_outboard: float + :param dz_blkt_half: Half-height of the blanket module (m) + :type dz_blkt_half: float + :param n_divertors: Number of divertors (1 for single null, 2 for double null) + :type n_divertors: int + :param f_ster_div_single: Fractional poloidal length of the divertor in single null configuration + :type f_ster_div_single: float + + :return: Segment length of outboard blanket module in poloidal direction (m) + :rtype: float + + + """ + + # Calculate perimeter of ellipse that defines the internal + # surface of the outboard first wall / blanket + + # Mid-plane distance from inboard to outboard side (m) + a = dr_fw_plasma_gap_inboard + 2.0 * rminor + dr_fw_plasma_gap_outboard + + # Internal half-height of blanket (m) + b = dz_blkt_half + + # Calculate ellipse circumference using Ramanujan approximation (m) + ptor = np.pi * (3.0 * (a + b) - np.sqrt((3.0 * a + b) * (a + 3.0 * b))) + + # Calculate blanket poloidal length and segment, subtracting divertor length (m) + # kit hcll version only had the single null option + if n_divertors == 2: + # Double null configuration + len_blkt_outboard_segment_poloidal = ( + 0.5 + * ptor + * (1.0 - 2.0 * f_ster_div_single) + / n_blkt_outboard_modules_poloidal + ) + else: + # single null configuration + len_blkt_outboard_segment_poloidal = ( + 0.5 * ptor * (1.0 - f_ster_div_single) / n_blkt_outboard_modules_poloidal + ) + + return len_blkt_outboard_segment_poloidal + def blanket_module_poloidal_height(self): """Calculations for blanket module poloidal height author: J. Morris, CCFE, Culham Science Centre From 040ae0ded41b234aa223d4a924d602277e47cb08 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Thu, 5 Feb 2026 09:22:49 +0000 Subject: [PATCH 3/5] Add method to calculate elliptical inboard blanket segment poloidal length --- process/blanket_library.py | 68 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/process/blanket_library.py b/process/blanket_library.py index 86b2af224..6d129868b 100644 --- a/process/blanket_library.py +++ b/process/blanket_library.py @@ -1092,6 +1092,74 @@ def calculate_dshaped_outboard_blkt_segment_poloidal( return len_blkt_outboard_segment_poloidal + @staticmethod + def calculate_elliptical_inboard_blkt_segment_poloidal( + rmajor: float, + rminor: float, + triang: float, + dr_fw_plasma_gap_inboard: float, + dz_blkt_half: float, + n_blkt_inboard_modules_poloidal: int, + n_divertors: int, + f_ster_div_single: float, + ) -> float: + """ + Calculations for elliptical inboard blanket module poloidal segment length + + :param rmajor: Major radius of the plasma (m) + :type rmajor: float + :param rminor: Minor radius of the plasma (m) + :type rminor: float + :param triang: Triangularity of the plasma + :type triang: float + :param dr_fw_plasma_gap_inboard: Radial gap between inboard first wall and plasma (m) + :type dr_fw_plasma_gap_inboard: float + :param dz_blkt_half: Half-height of the blanket module (m) + :type dz_blkt_half: float + :param n_blkt_inboard_modules_poloidal: Number of inboard blanket modules in poloidal direction + :type n_blkt_inboard_modules_poloidal: int + :param n_divertors: Number of divertors (1 for single null, 2 for double null) + :type n_divertors: int + :param f_ster_div_single: Fractional poloidal length of the divertor in single null configuration + :type f_ster_div_single: float + + :return: Segment length of inboard blanket module in poloidal direction (m) + :rtype: float + + """ + + # Major radius where half-ellipses 'meet' (m) + r1 = rmajor - rminor * triang + + # Internal half-height of blanket (m) + b = dz_blkt_half + + # Distance between r1 and nearest edge of inboard first wall / blanket (m) + a = r1 - (rmajor - rminor - dr_fw_plasma_gap_inboard) + + # Calculate ellipse circumference using Ramanujan approximation (m) + ptor = np.pi * (3.0 * (a + b) - np.sqrt((3.0 * a + b) * (a + 3.0 * b))) + + # Calculate inboard blanket poloidal length and segment, subtracting divertor length (m) + # Assume divertor lies between the two ellipses, so fraction f_ster_div_single still applies + + # kit hcll version only had the single null option + if n_divertors == 2: + # Double null configuration + len_blkt_inboard_segment_poloidal = ( + 0.5 + * ptor + * (1.0 - 2.0 * f_ster_div_single) + / n_blkt_inboard_modules_poloidal + ) + else: + # single null configuration + len_blkt_inboard_segment_poloidal = ( + 0.5 * ptor * (1.0 - f_ster_div_single) / n_blkt_inboard_modules_poloidal + ) + + return len_blkt_inboard_segment_poloidal + def blanket_module_poloidal_height(self): """Calculations for blanket module poloidal height author: J. Morris, CCFE, Culham Science Centre From eb11917dacf034ef2a7ebf69cfc11550faa117fb Mon Sep 17 00:00:00 2001 From: mn3981 Date: Thu, 5 Feb 2026 09:31:28 +0000 Subject: [PATCH 4/5] Add method to calculate elliptical outboard blanket segment poloidal length --- process/blanket_library.py | 66 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/process/blanket_library.py b/process/blanket_library.py index 6d129868b..26b9208a9 100644 --- a/process/blanket_library.py +++ b/process/blanket_library.py @@ -1160,6 +1160,72 @@ def calculate_elliptical_inboard_blkt_segment_poloidal( return len_blkt_inboard_segment_poloidal + @staticmethod + def calculate_elliptical_outboard_blkt_segment_poloidal( + rmajor: float, + rminor: float, + triang: float, + dz_blkt_half: float, + dr_fw_plasma_gap_outboard: float, + n_blkt_outboard_modules_poloidal: int, + n_divertors: int, + f_ster_div_single: float, + ) -> float: + """ + Calculations for elliptical outboard blanket module poloidal segment length + + :param rmajor: Major radius of the plasma (m) + :type rmajor: float + :param rminor: Minor radius of the plasma (m) + :type rminor: float + :param triang: Triangularity of the plasma + :type triang: float + :param dz_blkt_half: Half-height of the blanket module (m) + :type dz_blkt_half: float + :param dr_fw_plasma_gap_outboard: Radial gap between outboard first wall and plasma (m) + :type dr_fw_plasma_gap_outboard: float + :param n_blkt_outboard_modules_poloidal: Number of outboard blanket modules in poloidal direction + :type n_blkt_outboard_modules_poloidal: int + :param n_divertors: Number of divertors (1 for single null, 2 for double null) + :type n_divertors: int + :param f_ster_div_single: Fractional poloidal length of the divertor in single null configuration + :type f_ster_div_single: float + + :return: Segment length of outboard blanket module in poloidal direction (m) + :rtype: float + + + """ + + # Major radius where half-ellipses 'meet' (m) + r1 = rmajor - rminor * triang + + # Internal half-height of blanket (m) + b = dz_blkt_half + + # Distance between r1 and inner edge of outboard first wall / blanket (m) + a = rmajor + rminor + dr_fw_plasma_gap_outboard - r1 + + # Calculate ellipse circumference using Ramanujan approximation (m) + ptor = np.pi * (3.0 * (a + b) - np.sqrt((3.0 * a + b) * (a + 3.0 * b))) + + # kit hcll version only had the single null option + # Calculate outboard blanket poloidal length and segment, subtracting divertor length (m) + if n_divertors == 2: + # Double null configuration + len_blkt_outboard_segment_poloidal = ( + 0.5 + * ptor + * (1.0 - 2.0 * f_ster_div_single) + / n_blkt_outboard_modules_poloidal + ) + else: + # single null configuration + len_blkt_outboard_segment_poloidal = ( + 0.5 * ptor * (1.0 - f_ster_div_single) / n_blkt_outboard_modules_poloidal + ) + return len_blkt_outboard_segment_poloidal + def blanket_module_poloidal_height(self): """Calculations for blanket module poloidal height author: J. Morris, CCFE, Culham Science Centre From d5a2243fd59c99a27fb0293fdb7b626fe3e46af3 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Thu, 5 Feb 2026 09:55:26 +0000 Subject: [PATCH 5/5] Refactor blanket module poloidal height calculations to support D-shaped and elliptical configurations --- process/blanket_library.py | 39 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/process/blanket_library.py b/process/blanket_library.py index 26b9208a9..f95be76e3 100644 --- a/process/blanket_library.py +++ b/process/blanket_library.py @@ -477,8 +477,43 @@ def set_blanket_module_geometry(self): fwbs_variables.n_blkt_inboard_modules_poloidal = 1 fwbs_variables.n_blkt_outboard_modules_poloidal = 1 - # Calculate poloidal height of blanket modules - self.blanket_module_poloidal_height() + if physics_variables.itart == 1 or fwbs_variables.i_fw_blkt_vv_shape == 1: + blanket_library.len_blkt_inboard_segment_poloidal = self.calculate_dshaped_inboard_blkt_segment_poloidal( + dz_blkt_half=blanket_library.dz_blkt_half, + n_blkt_inboard_modules_poloidal=fwbs_variables.n_blkt_inboard_modules_poloidal, + ) + + blanket_library.len_blkt_outboard_segment_poloidal = self.calculate_dshaped_outboard_blkt_segment_poloidal( + n_blkt_outboard_modules_poloidal=fwbs_variables.n_blkt_outboard_modules_poloidal, + dr_fw_plasma_gap_inboard=build_variables.dr_fw_plasma_gap_inboard, + rminor=physics_variables.rminor, + dr_fw_plasma_gap_outboard=build_variables.dr_fw_plasma_gap_outboard, + dz_blkt_half=blanket_library.dz_blkt_half, + n_divertors=divertor_variables.n_divertors, + f_ster_div_single=fwbs_variables.f_ster_div_single, + ) + else: + blanket_library.len_blkt_inboard_segment_poloidal = self.calculate_elliptical_inboard_blkt_segment_poloidal( + rmajor=physics_variables.rmajor, + rminor=physics_variables.rminor, + triang=physics_variables.triang, + dr_fw_plasma_gap_inboard=build_variables.dr_fw_plasma_gap_inboard, + dz_blkt_half=blanket_library.dz_blkt_half, + n_blkt_inboard_modules_poloidal=fwbs_variables.n_blkt_inboard_modules_poloidal, + n_divertors=divertor_variables.n_divertors, + f_ster_div_single=fwbs_variables.f_ster_div_single, + ) + + blanket_library.len_blkt_outboard_segment_poloidal = self.calculate_elliptical_outboard_blkt_segment_poloidal( + rmajor=physics_variables.rmajor, + rminor=physics_variables.rminor, + triang=physics_variables.triang, + dz_blkt_half=blanket_library.dz_blkt_half, + dr_fw_plasma_gap_outboard=build_variables.dr_fw_plasma_gap_outboard, + n_blkt_outboard_modules_poloidal=fwbs_variables.n_blkt_outboard_modules_poloidal, + n_divertors=divertor_variables.n_divertors, + f_ster_div_single=fwbs_variables.f_ster_div_single, + ) # If liquid breeder or dual coolant blanket then calculate if fwbs_variables.i_blkt_dual_coolant > 0: