From 7e61092b49fd6cd4bf09526fa159acfac8161ad2 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Fri, 30 Jan 2026 13:59:27 +0000 Subject: [PATCH 01/11] =?UTF-8?q?=F0=9F=94=84=20Rename=20`component=5Fhalf?= =?UTF-8?q?=5Fheight`=20method=20to=20`calculate=5Fblkt=5Fhalf=5Fheight`?= =?UTF-8?q?=20for=20clarity=20and=20update=20references=20in=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- process/models/blankets/blanket_library.py | 4 ++-- tests/unit/test_blanket_library.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/process/models/blankets/blanket_library.py b/process/models/blankets/blanket_library.py index 24549d2c4..deb47e8fe 100644 --- a/process/models/blankets/blanket_library.py +++ b/process/models/blankets/blanket_library.py @@ -52,7 +52,7 @@ def component_volumes(self): # Calculate half-height # Blanket - blanket_library.dz_blkt_half = self.component_half_height(icomponent=0) + blanket_library.dz_blkt_half = self.calculate_blkt_half_height(icomponent=0) # D-shaped blanket and shield if physics_variables.itart == 1 or fwbs_variables.i_fw_blkt_vv_shape == 1: @@ -65,7 +65,7 @@ def component_volumes(self): # Apply coverage factors to volumes and surface areas self.apply_coverage_factors() - def component_half_height(self, icomponent: int): + def calculate_blkt_half_height(self, icomponent: int): """Calculate the blanket, shield or vacuum vessel half-height Based on blanket_half_height, shield_half_height, vv_half_height diff --git a/tests/unit/test_blanket_library.py b/tests/unit/test_blanket_library.py index abbca9fdc..37be55f60 100644 --- a/tests/unit/test_blanket_library.py +++ b/tests/unit/test_blanket_library.py @@ -422,7 +422,7 @@ class ComponentHalfHeightParam(NamedTuple): ), ), ) -def test_component_half_height( +def test_calculate_blkt_half_height( componenthalfheightparam, monkeypatch, blanket_library_fixture ): """ @@ -494,7 +494,7 @@ def test_component_half_height( divertor_variables, "dz_divertor", componenthalfheightparam.dz_divertor ) - half_height = blanket_library_fixture.component_half_height( + half_height = blanket_library_fixture.calculate_blkt_half_height( componenthalfheightparam.icomponent ) From 19716fc588506523d1d1aa97d258fc6d645b53d6 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Fri, 30 Jan 2026 14:16:22 +0000 Subject: [PATCH 02/11] Refactor `calculate_blkt_half_height` method to accept parameters directly instead of using an `icomponent` switch; update corresponding tests for consistency. --- process/models/blankets/blanket_library.py | 86 +++++++++++++++------- tests/unit/test_blanket_library.py | 85 ++++----------------- 2 files changed, 75 insertions(+), 96 deletions(-) diff --git a/process/models/blankets/blanket_library.py b/process/models/blankets/blanket_library.py index deb47e8fe..feb91be6c 100644 --- a/process/models/blankets/blanket_library.py +++ b/process/models/blankets/blanket_library.py @@ -47,12 +47,21 @@ def component_volumes(self): Calculate the blanket, shield, vacuum vessel and cryostat volumes """ - # N.B. icomponent is a switch used to specify selected component: blanket=0, shield=1, vacuum vessel=2 - # Replaced separate subroutines for blnkt, shld and vv with fuction/subroutine with icomponent switch. # Calculate half-height # Blanket - blanket_library.dz_blkt_half = self.calculate_blkt_half_height(icomponent=0) + blanket_library.dz_blkt_half = self.calculate_blkt_half_height( + z_plasma_xpoint_lower=build_variables.z_plasma_xpoint_lower, + dz_xpoint_divertor=build_variables.dz_xpoint_divertor, + dz_divertor=divertor_variables.dz_divertor, + z_plasma_xpoint_upper=build_variables.z_plasma_xpoint_upper, + dr_fw_plasma_gap_inboard=build_variables.dr_fw_plasma_gap_inboard, + dr_fw_plasma_gap_outboard=build_variables.dr_fw_plasma_gap_outboard, + dr_fw_inboard=build_variables.dr_fw_inboard, + dr_fw_outboard=build_variables.dr_fw_outboard, + dz_blkt_upper=build_variables.dz_blkt_upper, + n_divertors=divertor_variables.n_divertors, + ) # D-shaped blanket and shield if physics_variables.itart == 1 or fwbs_variables.i_fw_blkt_vv_shape == 1: @@ -65,40 +74,67 @@ def component_volumes(self): # Apply coverage factors to volumes and surface areas self.apply_coverage_factors() - def calculate_blkt_half_height(self, icomponent: int): - """Calculate the blanket, shield or vacuum vessel half-height - Based on blanket_half_height, shield_half_height, vv_half_height - - Parameters - ---------- - icomponent: int : + @staticmethod + def calculate_blkt_half_height( + z_plasma_xpoint_lower: float, + dz_xpoint_divertor: float, + dz_divertor: float, + z_plasma_xpoint_upper: float, + dr_fw_plasma_gap_inboard: float, + dr_fw_plasma_gap_outboard: float, + dr_fw_inboard: float, + dr_fw_outboard: float, + dz_blkt_upper: float, + n_divertors: int, + ) -> float: + """ + Calculate the blanket half-height based on plasma and component geometry. + + :param z_plasma_xpoint_lower: Lower vertical position of the plasma x-point (m) + :type z_plasma_xpoint_lower: float + :param dz_xpoint_divertor: Vertical distance from x-point to divertor (m) + :type dz_xpoint_divertor: float + :param dz_divertor: Vertical thickness of the divertor (m) + :type dz_divertor: float + :param z_plasma_xpoint_upper: Upper vertical position of the plasma x-point (m) + :type z_plasma_xpoint_upper: float + :param dr_fw_plasma_gap_inboard: Radial gap between first wall and plasma on inboard side (m) + :type dr_fw_plasma_gap_inboard: float + :param dr_fw_plasma_gap_outboard: Radial gap between first wall and plasma on outboard side (m) + :type dr_fw_plasma_gap_outboard: float + :param dr_fw_inboard: Radial thickness of the first wall on inboard side (m) + :type dr_fw_inboard: float + :param dr_fw_outboard: Radial thickness of the first wall on outboard side (m) + :type dr_fw_outboard: float + :param dz_blkt_upper: Vertical thickness of the upper blanket (m) + :type dz_blkt_upper: float + :param n_divertors: Number of divertors (1 for single null, 2 for double null) + :type n_divertors: int + :return: Calculated blanket half-height (m) + :rtype: float """ # Calculate component internal lower half-height (m) # Blanket - if icomponent == 0: - hbot = ( - build_variables.z_plasma_xpoint_lower - + build_variables.dz_xpoint_divertor - + divertor_variables.dz_divertor - - build_variables.dz_blkt_upper - ) + z_bottom = ( + z_plasma_xpoint_lower + dz_xpoint_divertor + dz_divertor - dz_blkt_upper + ) # Calculate component internal upper half-height (m) # If a double null machine then symmetric - if divertor_variables.n_divertors == 2: - htop = hbot + if n_divertors == 2: + z_top = z_bottom else: # Blanket - htop = build_variables.z_plasma_xpoint_upper + 0.5 * ( - build_variables.dr_fw_plasma_gap_inboard - + build_variables.dr_fw_plasma_gap_outboard - + build_variables.dr_fw_inboard - + build_variables.dr_fw_outboard + z_top = z_plasma_xpoint_upper + 0.5 * ( + dr_fw_plasma_gap_inboard + + dr_fw_plasma_gap_outboard + + dr_fw_inboard + + dr_fw_outboard ) # Average of top and bottom (m) - return 0.5 * (htop + hbot) + return 0.5 * (z_top + z_bottom) def dshaped_component(self): """Calculate component surface area and volume using dshaped scheme diff --git a/tests/unit/test_blanket_library.py b/tests/unit/test_blanket_library.py index 37be55f60..799848ea9 100644 --- a/tests/unit/test_blanket_library.py +++ b/tests/unit/test_blanket_library.py @@ -392,7 +392,6 @@ class ComponentHalfHeightParam(NamedTuple): z_plasma_xpoint_upper: Any = None n_divertors: Any = None dz_divertor: Any = None - icomponent: Any = None expected_icomponent: Any = None expected_half_height: Any = None @@ -416,86 +415,30 @@ class ComponentHalfHeightParam(NamedTuple): z_plasma_xpoint_upper=4.93333333333333333, n_divertors=1, dz_divertor=0.62000000000000011, - icomponent=0, - expected_icomponent=0, expected_half_height=5.9532752487304119, ), ), ) -def test_calculate_blkt_half_height( - componenthalfheightparam, monkeypatch, blanket_library_fixture -): +def test_calculate_blkt_half_height(componenthalfheightparam, blanket_library_fixture): """ - Automatically generated Regression Unit Test for component_half_height. + Regression Unit Test for component_half_height. - This test was generated using data from tests/regression/input_files/large_tokamak.IN.DAT. + This test was generated using data from large_tokamak.IN.DAT. - :param componenthalfheightparam: the data used to mock and assert in this test. + :param componenthalfheightparam: the data used in this test. :type componenthalfheightparam: componenthalfheightparam - - :param monkeypatch: pytest fixture used to mock module/class variables - :type monkeypatch: _pytest.monkeypatch.monkeypatch """ - monkeypatch.setattr( - build_variables, "z_tf_inside_half", componenthalfheightparam.z_tf_inside_half - ) - monkeypatch.setattr( - build_variables, - "dz_xpoint_divertor", - componenthalfheightparam.dz_xpoint_divertor, - ) - monkeypatch.setattr( - build_variables, - "dz_shld_vv_gap", - componenthalfheightparam.dz_shld_vv_gap, - ) - monkeypatch.setattr( - build_variables, "dz_blkt_upper", componenthalfheightparam.dz_blkt_upper - ) - monkeypatch.setattr( - build_variables, "dz_shld_upper", componenthalfheightparam.dz_shld_upper - ) - monkeypatch.setattr( - build_variables, - "dr_fw_plasma_gap_inboard", - componenthalfheightparam.dr_fw_plasma_gap_inboard, - ) - monkeypatch.setattr( - build_variables, - "dr_fw_plasma_gap_outboard", - componenthalfheightparam.dr_fw_plasma_gap_outboard, - ) - monkeypatch.setattr( - build_variables, "dr_fw_inboard", componenthalfheightparam.dr_fw_inboard - ) - monkeypatch.setattr( - build_variables, "dr_fw_outboard", componenthalfheightparam.dr_fw_outboard - ) - monkeypatch.setattr( - build_variables, "dz_vv_lower", componenthalfheightparam.dz_vv_lower - ) - monkeypatch.setattr( - build_variables, "dz_vv_upper", componenthalfheightparam.dz_vv_upper - ) - monkeypatch.setattr( - build_variables, - "z_plasma_xpoint_lower", - componenthalfheightparam.z_plasma_xpoint_lower, - ) - monkeypatch.setattr( - build_variables, - "z_plasma_xpoint_upper", - componenthalfheightparam.z_plasma_xpoint_upper, - ) - monkeypatch.setattr( - divertor_variables, "n_divertors", componenthalfheightparam.n_divertors - ) - monkeypatch.setattr( - divertor_variables, "dz_divertor", componenthalfheightparam.dz_divertor - ) - half_height = blanket_library_fixture.calculate_blkt_half_height( - componenthalfheightparam.icomponent + z_plasma_xpoint_lower=componenthalfheightparam.z_plasma_xpoint_lower, + dz_xpoint_divertor=componenthalfheightparam.dz_xpoint_divertor, + dz_divertor=componenthalfheightparam.dz_divertor, + z_plasma_xpoint_upper=componenthalfheightparam.z_plasma_xpoint_upper, + dr_fw_plasma_gap_inboard=componenthalfheightparam.dr_fw_plasma_gap_inboard, + dr_fw_plasma_gap_outboard=componenthalfheightparam.dr_fw_plasma_gap_outboard, + dr_fw_inboard=componenthalfheightparam.dr_fw_inboard, + dr_fw_outboard=componenthalfheightparam.dr_fw_outboard, + dz_blkt_upper=componenthalfheightparam.dz_blkt_upper, + n_divertors=componenthalfheightparam.n_divertors, ) assert half_height == pytest.approx(componenthalfheightparam.expected_half_height) From 58ad0eb48779e6b5bee5bffab59e1fccb33c901d Mon Sep 17 00:00:00 2001 From: mn3981 Date: Fri, 30 Jan 2026 14:52:31 +0000 Subject: [PATCH 03/11] Add methods to calculate D-shaped blanket areas and volumes --- process/models/blankets/blanket_library.py | 169 ++++++++++++++++++++- 1 file changed, 168 insertions(+), 1 deletion(-) diff --git a/process/models/blankets/blanket_library.py b/process/models/blankets/blanket_library.py index feb91be6c..76142c8b8 100644 --- a/process/models/blankets/blanket_library.py +++ b/process/models/blankets/blanket_library.py @@ -65,7 +65,39 @@ def component_volumes(self): # D-shaped blanket and shield if physics_variables.itart == 1 or fwbs_variables.i_fw_blkt_vv_shape == 1: - self.dshaped_component() + ( + build_variables.a_blkt_inboard_surface, + build_variables.a_blkt_outboard_surface, + build_variables.a_blkt_total_surface, + ) = self.calculate_dshaped_blkt_areas( + r_shld_inboard_inner=build_variables.r_shld_inboard_inner, + dr_shld_inboard=build_variables.dr_shld_inboard, + dr_blkt_inboard=build_variables.dr_blkt_inboard, + dr_fw_inboard=build_variables.dr_fw_inboard, + 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, + dr_fw_outboard=build_variables.dr_fw_outboard, + dz_blkt_half=blanket_library.dz_blkt_half, + ) + + ( + fwbs_variables.vol_blkt_inboard, + fwbs_variables.vol_blkt_outboard, + fwbs_variables.vol_blkt_total, + ) = self.calculate_dshaped_blkt_volumes( + r_shld_inboard_inner=build_variables.r_shld_inboard_inner, + dr_shld_inboard=build_variables.dr_shld_inboard, + dr_blkt_inboard=build_variables.dr_blkt_inboard, + dr_fw_inboard=build_variables.dr_fw_inboard, + 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, + dr_fw_outboard=build_variables.dr_fw_outboard, + dz_blkt_half=blanket_library.dz_blkt_half, + dr_blkt_outboard=build_variables.dr_blkt_outboard, + dz_blkt_upper=build_variables.dz_blkt_upper, + ) # Elliptical blanket and shield else: @@ -178,6 +210,141 @@ def dshaped_component(self): build_variables.dz_blkt_upper, ) + @staticmethod + def calculate_dshaped_blkt_areas( + r_shld_inboard_inner: float, + dr_shld_inboard: float, + dr_blkt_inboard: float, + dr_fw_inboard: float, + dr_fw_plasma_gap_inboard: float, + rminor: float, + dr_fw_plasma_gap_outboard: float, + dr_fw_outboard: float, + dz_blkt_half: float, + ) -> tuple[float, float, float]: + """ + Calculate D-shaped blanket surface areas. + + :param r_shld_inboard_inner: Inner radius of inboard shield (m) + :type r_shld_inboard_inner: float + :param dr_shld_inboard: Thickness of inboard shield (m) + :type dr_shld_inboard: float + :param dr_blkt_inboard: Thickness of inboard blanket (m) + :type dr_blkt_inboard: float + :param dr_fw_inboard: Thickness of inboard first wall (m) + :type dr_fw_inboard: float + :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 dr_fw_outboard: Thickness of outboard first wall (m) + :type dr_fw_outboard: float + :param dz_blkt_half: Half-height of the blanket (m) + :type dz_blkt_half: float + + :return: Tuple containing inboard blanket surface area (m²), outboard blanket surface area (m²), and total blanket surface area (m²) + """ + # Calculate major radius to outer edge of inboard ... + # ... section (m) + r1 = r_shld_inboard_inner + + # ... blanket (m) + + r1 = r1 + dr_shld_inboard + dr_blkt_inboard + # Horizontal distance between inside edges (m) + # i.e. outer radius of inboard part to inner radius of outboard part + + r2 = ( + dr_fw_inboard + + dr_fw_plasma_gap_inboard + + 2.0 * rminor + + dr_fw_plasma_gap_outboard + + dr_fw_outboard + ) + + ( + a_blkt_inboard_surface, + a_blkt_outboard_surface, + a_blkt_total_surface, + ) = dshellarea(rmajor=r1, rminor=r2, zminor=dz_blkt_half) + + return a_blkt_inboard_surface, a_blkt_outboard_surface, a_blkt_total_surface + + @staticmethod + def calculate_dshaped_blkt_volumes( + r_shld_inboard_inner: float, + dr_shld_inboard: float, + dr_blkt_inboard: float, + dr_fw_inboard: float, + dr_fw_plasma_gap_inboard: float, + rminor: float, + dr_fw_plasma_gap_outboard: float, + dr_fw_outboard: float, + dz_blkt_half: float, + dr_blkt_outboard: float, + dz_blkt_upper: float, + ) -> tuple[float, float, float]: + """ + Calculate D-shaped blanket volumes. + + :param r_shld_inboard_inner: Inner radius of inboard shield (m) + :type r_shld_inboard_inner: float + :param dr_shld_inboard: Thickness of inboard shield (m) + :type dr_shld_inboard: float + :param dr_blkt_inboard: Thickness of inboard blanket (m) + :type dr_blkt_inboard: float + :param dr_fw_inboard: Thickness of inboard first wall (m) + :type dr_fw_inboard: float + :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 dr_fw_outboard: Thickness of outboard first wall (m) + :type dr_fw_outboard: float + :param dz_blkt_half: Half-height of the blanket (m) + :type dz_blkt_half: float + :param dr_blkt_outboard: Thickness of outboard blanket (m) + :type dr_blkt_outboard: float + :param dz_blkt_upper: Upper vertical thickness of the blanket (m) + :type dz_blkt_upper: float + + :return: Tuple containing inboard blanket volume (m³), outboard blanket volume (m³), and total blanket volume (m³) + """ + # Calculate major radius to outer edge of inboard ... + # ... section (m) + r1 = r_shld_inboard_inner + + r1 = r1 + dr_shld_inboard + dr_blkt_inboard + # Horizontal distance between inside edges (m) + # i.e. outer radius of inboard part to inner radius of outboard part + + r2 = ( + dr_fw_inboard + + dr_fw_plasma_gap_inboard + + 2.0 * rminor + + dr_fw_plasma_gap_outboard + + dr_fw_outboard + ) + + ( + vol_blkt_inboard, + vol_blkt_outboard, + vol_blkt_total, + ) = dshellvol( + rmajor=r1, + rminor=r2, + zminor=dz_blkt_half, + drin=dr_blkt_inboard, + drout=dr_blkt_outboard, + dz=dz_blkt_upper, + ) + + return vol_blkt_inboard, vol_blkt_outboard, vol_blkt_total + def elliptical_component(self): """Calculate component surface area and volume using elliptical scheme Based on elliptical_blanket, elliptical_shield, elliptical_vv From 215fc3c854be7b73fb9acdefcfa0657f15af9a3b Mon Sep 17 00:00:00 2001 From: mn3981 Date: Fri, 30 Jan 2026 15:13:47 +0000 Subject: [PATCH 04/11] Add methods to calculate elliptical blanket areas and volumes --- process/models/blankets/blanket_library.py | 176 ++++++++++++++++++++- 1 file changed, 175 insertions(+), 1 deletion(-) diff --git a/process/models/blankets/blanket_library.py b/process/models/blankets/blanket_library.py index 76142c8b8..d55e24967 100644 --- a/process/models/blankets/blanket_library.py +++ b/process/models/blankets/blanket_library.py @@ -101,7 +101,40 @@ def component_volumes(self): # Elliptical blanket and shield else: - self.elliptical_component() + ( + build_variables.a_blkt_inboard_surface, + build_variables.a_blkt_outboard_surface, + build_variables.a_blkt_total_surface, + ) = self.calculate_elliptical_blkt_areas( + rmajor=physics_variables.rmajor, + rminor=physics_variables.rminor, + triang=physics_variables.triang, + r_shld_inboard_inner=build_variables.r_shld_inboard_inner, + dr_shld_inboard=build_variables.dr_shld_inboard, + dr_blkt_inboard=build_variables.dr_blkt_inboard, + r_shld_outboard_outer=build_variables.r_shld_outboard_outer, + dr_shld_outboard=build_variables.dr_shld_outboard, + dr_blkt_outboard=build_variables.dr_blkt_outboard, + dz_blkt_half=blanket_library.dz_blkt_half, + ) + + ( + fwbs_variables.vol_blkt_inboard, + fwbs_variables.vol_blkt_outboard, + fwbs_variables.vol_blkt_total, + ) = self.calculate_elliptical_blkt_volumes( + rmajor=physics_variables.rmajor, + rminor=physics_variables.rminor, + triang=physics_variables.triang, + r_shld_inboard_inner=build_variables.r_shld_inboard_inner, + dr_shld_inboard=build_variables.dr_shld_inboard, + dr_blkt_inboard=build_variables.dr_blkt_inboard, + r_shld_outboard_outer=build_variables.r_shld_outboard_outer, + dr_shld_outboard=build_variables.dr_shld_outboard, + dr_blkt_outboard=build_variables.dr_blkt_outboard, + dz_blkt_half=blanket_library.dz_blkt_half, + dz_blkt_upper=build_variables.dz_blkt_upper, + ) # Apply coverage factors to volumes and surface areas self.apply_coverage_factors() @@ -345,6 +378,147 @@ def calculate_dshaped_blkt_volumes( return vol_blkt_inboard, vol_blkt_outboard, vol_blkt_total + @staticmethod + def calculate_elliptical_blkt_areas( + rmajor: float, + rminor: float, + triang: float, + r_shld_inboard_inner: float, + dr_shld_inboard: float, + dr_blkt_inboard: float, + r_shld_outboard_outer: float, + dr_shld_outboard: float, + dr_blkt_outboard: float, + dz_blkt_half: float, + ) -> tuple[float, float, float]: + """Calculate elliptical blanket surface areas. + + :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 r_shld_inboard_inner: Inner radius of inboard shield (m) + :type r_shld_inboard_inner: float + :param dr_shld_inboard: Thickness of inboard shield (m) + :type dr_shld_inboard: float + :param dr_blkt_inboard: Thickness of inboard blanket (m) + :type dr_blkt_inboard: float + :param r_shld_outboard_outer: Outer radius of outboard shield (m) + :type r_shld_outboard_outer: float + :param dr_shld_outboard: Thickness of outboard shield (m) + :type dr_shld_outboard: float + :param dr_blkt_outboard: Thickness of outboard blanket (m) + :type dr_blkt_outboard: float + :param dz_blkt_half: Half-height of the blanket (m) + :type dz_blkt_half: float + + :return: Tuple containing inboard blanket surface area (m²), outboard blanket surface area (m²), and total blanket surface area (m²) + + """ + # Major radius to centre of inboard and outboard ellipses (m) + # (coincident in radius with top of plasma) + r1 = rmajor - rminor * triang + + # Calculate distance between r1 and outer edge of inboard ... + # ... section (m) + r2 = r1 - r_shld_inboard_inner + + r2 = r2 - dr_shld_inboard - dr_blkt_inboard + + # Calculate distance between r1 and inner edge of outboard ... + # ... section (m) + r3 = r_shld_outboard_outer - r1 + + r3 = r3 - dr_shld_outboard - dr_blkt_outboard + + # Calculate surface area, assuming 100% coverage + + ( + a_blkt_inboard_surface, + a_blkt_outboard_surface, + a_blkt_total_surface, + ) = eshellarea(r1, r2, r3, dz_blkt_half) + + return a_blkt_inboard_surface, a_blkt_outboard_surface, a_blkt_total_surface + + @staticmethod + def calculate_elliptical_blkt_volumes( + rmajor: float, + rminor: float, + triang: float, + r_shld_inboard_inner: float, + dr_shld_inboard: float, + dr_blkt_inboard: float, + r_shld_outboard_outer: float, + dr_shld_outboard: float, + dr_blkt_outboard: float, + dz_blkt_half: float, + dz_blkt_upper: float, + ) -> tuple[float, float, float]: + """Calculate elliptical blanket volumes. + + :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 r_shld_inboard_inner: Inner radius of inboard shield (m) + :type r_shld_inboard_inner: float + :param dr_shld_inboard: Thickness of inboard shield (m) + :type dr_shld_inboard: float + :param dr_blkt_inboard: Thickness of inboard blanket (m) + :type dr_blkt_inboard: float + :param r_shld_outboard_outer: Outer radius of outboard shield (m) + :type r_shld_outboard_outer: float + :param dr_shld_outboard: Thickness of outboard shield (m) + :type dr_shld_outboard: float + :param dr_blkt_outboard: Thickness of outboard blanket (m) + :type dr_blkt_outboard: float + :param dz_blkt_half: Half-height of the blanket (m) + :type dz_blkt_half: float + :param dz_blkt_upper: Upper vertical thickness of the blanket (m) + :type dz_blkt_upper: float + + :return: Tuple containing inboard blanket volume (m³), outboard blanket volume (m³), and total blanket volume (m³) + + """ + # Major radius to centre of inboard and outboard ellipses (m) + # (coincident in radius with top of plasma) + r1 = rmajor - rminor * triang + + # Calculate distance between r1 and outer edge of inboard ... + # ... section (m) + r2 = r1 - r_shld_inboard_inner + + r2 = r2 - dr_shld_inboard - dr_blkt_inboard + + # Calculate distance between r1 and inner edge of outboard ... + # ... section (m) + r3 = r_shld_outboard_outer - r1 + + r3 = r3 - dr_shld_outboard - dr_blkt_outboard + + # Calculate surface area, assuming 100% coverage + + ( + vol_blkt_inboard, + vol_blkt_outboard, + vol_blkt_total, + ) = eshellvol( + rshell=r1, + rmini=r2, + rmino=r3, + zminor=dz_blkt_half, + drin=dr_blkt_inboard, + drout=dr_blkt_outboard, + dz=dz_blkt_upper, + ) + + return vol_blkt_inboard, vol_blkt_outboard, vol_blkt_total + def elliptical_component(self): """Calculate component surface area and volume using elliptical scheme Based on elliptical_blanket, elliptical_shield, elliptical_vv From 3e98ea9b8a6a81511ca8d4395ff1efbaaed3b1b6 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Fri, 30 Jan 2026 16:11:31 +0000 Subject: [PATCH 05/11] Add `plot_blkt_structure` function to visualize blanket and first wall cross-section --- process/core/io/plot_proc.py | 115 +++++++++++++++++++++++------------ 1 file changed, 75 insertions(+), 40 deletions(-) diff --git a/process/core/io/plot_proc.py b/process/core/io/plot_proc.py index f73ce582d..82e11f556 100644 --- a/process/core/io/plot_proc.py +++ b/process/core/io/plot_proc.py @@ -13224,6 +13224,80 @@ def plot_inequality_constraint_equations(axis: plt.Axes, m_file: mf.MFile, scan: axis.set_xticklabels([]) +def plot_blkt_structure( + ax: plt.Axes, + m_file: mf.MFile, + scan: int, + radial_build: dict[str, float], + colour_scheme: Literal[1, 2], +): + """Plot the BLKT structure on the given axis.""" + + rmajor = m_file.get("rmajor", scan=scan) + + plot_blanket(ax, m_file, scan, radial_build, colour_scheme) + plot_firstwall(ax, m_file, scan, radial_build, colour_scheme) + ax.set_xlabel("Radial position [m]") + ax.set_ylabel("Vertical position [m]") + ax.set_title("Blanket and First Wall Poloidal Cross-Section") + ax.minorticks_on() + ax.grid(which="minor", linestyle=":", linewidth=0.5, alpha=0.5) + # Plot major radius line (vertical dashed line at rmajor) + ax.axvline( + m_file.get("rminor", scan=scan), + color="black", + linestyle="--", + linewidth=1.5, + label="Major Radius $R_0$", + ) + # Plot a horizontal line at dz_blkt_half (blanket half height) + dz_blkt_half = m_file.get("dz_blkt_half", scan=scan) + ax.axhline( + dz_blkt_half, + color="purple", + linestyle="--", + linewidth=1.5, + label="Blanket Half Height", + ) + ax.axhline( + -dz_blkt_half, + color="purple", + linestyle="--", + linewidth=1.5, + label="Blanket Half Height", + ) + + ax.annotate( + "", + xy=(rmajor, dz_blkt_half), + xytext=(rmajor, -dz_blkt_half), + arrowprops={"arrowstyle": "<->", "color": "black"}, + ) + + # Add a label for the internal coil width + ax.text( + rmajor, + 0.0, + f"{2 * dz_blkt_half:.3f} m", + fontsize=7, + color="black", + rotation=270, + verticalalignment="center", + horizontalalignment="center", + bbox={"boxstyle": "round", "facecolor": "pink", "alpha": 1.0}, + zorder=101, # Ensure label is on top of all plots + ) + + # Plot midplane line (horizontal dashed line at Z=0) + ax.axhline( + 0.0, + color="black", + linestyle="--", + linewidth=1.5, + label="Midplane", + ) + + def main_plot( figs: list[Axes], m_file: mf.MFile, @@ -13506,46 +13580,7 @@ def main_plot( plot_blkt_pipe_bends(figs[28], m_file, scan) ax_blanket = figs[28].add_subplot(122, aspect="equal") - plot_blanket(ax_blanket, m_file, scan, radial_build, colour_scheme) - plot_firstwall(ax_blanket, m_file, scan, radial_build, colour_scheme) - ax_blanket.set_xlabel("Radial position [m]") - ax_blanket.set_ylabel("Vertical position [m]") - ax_blanket.set_title("Blanket and First Wall Poloidal Cross-Section") - ax_blanket.minorticks_on() - ax_blanket.grid(which="minor", linestyle=":", linewidth=0.5, alpha=0.5) - # Plot major radius line (vertical dashed line at rmajor) - ax_blanket.axvline( - m_file.get("rminor", scan=scan), - color="black", - linestyle="--", - linewidth=1.5, - label="Major Radius $R_0$", - ) - # Plot a horizontal line at dz_blkt_half (blanket half height) - dz_blkt_half = m_file.get("dz_blkt_half", scan=scan) - ax_blanket.axhline( - dz_blkt_half, - color="purple", - linestyle="--", - linewidth=1.5, - label="Blanket Half Height", - ) - ax_blanket.axhline( - -dz_blkt_half, - color="purple", - linestyle="--", - linewidth=1.5, - label="Blanket Half Height", - ) - - # Plot midplane line (horizontal dashed line at Z=0) - ax_blanket.axhline( - 0.0, - color="black", - linestyle="--", - linewidth=1.5, - label="Midplane", - ) + plot_blkt_structure(ax_blanket, m_file, scan, radial_build, colour_scheme) plot_main_power_flow( figs[29].add_subplot(111, aspect="equal"), m_file, scan, figs[29] From ba2f367eee1910bf0c3f0cf6e6f15c004b639ad6 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Fri, 30 Jan 2026 16:24:43 +0000 Subject: [PATCH 06/11] Refactor blanket area and volume calculations to include full coverage variables for D-shaped and elliptical shapes --- process/models/blankets/blanket_library.py | 41 +++++++++++----------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/process/models/blankets/blanket_library.py b/process/models/blankets/blanket_library.py index d55e24967..0905be456 100644 --- a/process/models/blankets/blanket_library.py +++ b/process/models/blankets/blanket_library.py @@ -66,9 +66,9 @@ def component_volumes(self): # D-shaped blanket and shield if physics_variables.itart == 1 or fwbs_variables.i_fw_blkt_vv_shape == 1: ( - build_variables.a_blkt_inboard_surface, - build_variables.a_blkt_outboard_surface, - build_variables.a_blkt_total_surface, + build_variables.a_blkt_inboard_surface_full_coverage, + build_variables.a_blkt_outboard_surface_full_coverage, + build_variables.a_blkt_total_surface_full_coverage, ) = self.calculate_dshaped_blkt_areas( r_shld_inboard_inner=build_variables.r_shld_inboard_inner, dr_shld_inboard=build_variables.dr_shld_inboard, @@ -82,9 +82,9 @@ def component_volumes(self): ) ( - fwbs_variables.vol_blkt_inboard, - fwbs_variables.vol_blkt_outboard, - fwbs_variables.vol_blkt_total, + fwbs_variables.vol_blkt_inboard_full_coverage, + fwbs_variables.vol_blkt_outboard_full_coverage, + fwbs_variables.vol_blkt_total_full_coverage, ) = self.calculate_dshaped_blkt_volumes( r_shld_inboard_inner=build_variables.r_shld_inboard_inner, dr_shld_inboard=build_variables.dr_shld_inboard, @@ -102,9 +102,9 @@ def component_volumes(self): # Elliptical blanket and shield else: ( - build_variables.a_blkt_inboard_surface, - build_variables.a_blkt_outboard_surface, - build_variables.a_blkt_total_surface, + build_variables.a_blkt_inboard_surface_full_coverage, + build_variables.a_blkt_outboard_surface_full_coverage, + build_variables.a_blkt_total_surface_full_coverage, ) = self.calculate_elliptical_blkt_areas( rmajor=physics_variables.rmajor, rminor=physics_variables.rminor, @@ -119,9 +119,9 @@ def component_volumes(self): ) ( - fwbs_variables.vol_blkt_inboard, - fwbs_variables.vol_blkt_outboard, - fwbs_variables.vol_blkt_total, + fwbs_variables.vol_blkt_inboard_full_coverage, + fwbs_variables.vol_blkt_outboard_full_coverage, + fwbs_variables.vol_blkt_total_full_coverage, ) = self.calculate_elliptical_blkt_volumes( rmajor=physics_variables.rmajor, rminor=physics_variables.rminor, @@ -575,42 +575,43 @@ def apply_coverage_factors(self): if divertor_variables.n_divertors == 2: # double null configuration build_variables.a_blkt_outboard_surface = ( - build_variables.a_blkt_total_surface + build_variables.a_blkt_total_surface_full_coverage * ( 1.0 - 2.0 * fwbs_variables.f_ster_div_single - fwbs_variables.f_a_fw_outboard_hcd ) - - build_variables.a_blkt_inboard_surface + - build_variables.a_blkt_inboard_surface_full_coverage ) else: # single null configuration build_variables.a_blkt_outboard_surface = ( - build_variables.a_blkt_total_surface + build_variables.a_blkt_total_surface_full_coverage * ( 1.0 - fwbs_variables.f_ster_div_single - fwbs_variables.f_a_fw_outboard_hcd ) - - build_variables.a_blkt_inboard_surface + - build_variables.a_blkt_inboard_surface_full_coverage ) build_variables.a_blkt_total_surface = ( - build_variables.a_blkt_inboard_surface + build_variables.a_blkt_inboard_surface_full_coverage + build_variables.a_blkt_outboard_surface ) fwbs_variables.vol_blkt_outboard = ( - fwbs_variables.vol_blkt_total + fwbs_variables.vol_blkt_total_full_coverage * ( 1.0 - fwbs_variables.f_ster_div_single - fwbs_variables.f_a_fw_outboard_hcd ) - - fwbs_variables.vol_blkt_inboard + - fwbs_variables.vol_blkt_inboard_full_coverage ) fwbs_variables.vol_blkt_total = ( - fwbs_variables.vol_blkt_inboard + fwbs_variables.vol_blkt_outboard + fwbs_variables.vol_blkt_inboard_full_coverage + + fwbs_variables.vol_blkt_outboard ) def primary_coolant_properties(self, output: bool): From 3b7b325586b0784d10f98152da83e94a0c17120c Mon Sep 17 00:00:00 2001 From: mn3981 Date: Fri, 30 Jan 2026 17:05:39 +0000 Subject: [PATCH 07/11] Add output function for blanket volumes and areas in blanket_library; integrate into DCLL and CCFE_HCPB classes --- process/models/blankets/blanket_library.py | 83 ++++++++++++++++++++++ process/models/blankets/dcll.py | 2 + process/models/blankets/hcpb.py | 3 + 3 files changed, 88 insertions(+) diff --git a/process/models/blankets/blanket_library.py b/process/models/blankets/blanket_library.py index 0905be456..0220a562d 100644 --- a/process/models/blankets/blanket_library.py +++ b/process/models/blankets/blanket_library.py @@ -609,11 +609,94 @@ def apply_coverage_factors(self): ) - fwbs_variables.vol_blkt_inboard_full_coverage ) + fwbs_variables.vol_blkt_inboard = fwbs_variables.vol_blkt_inboard_full_coverage + fwbs_variables.vol_blkt_total = ( fwbs_variables.vol_blkt_inboard_full_coverage + fwbs_variables.vol_blkt_outboard ) + def output_blkt_volumes_and_areas(self): + """Outputs blanket volumes and areas to the output file""" + + po.oheadr(self.outfile, "Blanket Volumes and Surface Areas") + + po.ovarst( + self.outfile, + "Inboard Blanket Volume with gaps and holes (m3)", + "(vol_blkt_inboard)", + fwbs_variables.vol_blkt_inboard, + ) + po.ovarst( + self.outfile, + "Outboard Blanket Volume with gaps and holes (m3)", + "(vol_blkt_outboard)", + fwbs_variables.vol_blkt_outboard, + ) + po.ovarst( + self.outfile, + "Total Blanket Volume with gaps and holes (m3)", + "(vol_blkt_total)", + fwbs_variables.vol_blkt_total, + ) + + po.ovarst( + self.outfile, + "Inboard Blanket Volume if toridally continuous (m3)", + "(vol_blkt_inboard_full_coverage)", + fwbs_variables.vol_blkt_inboard_full_coverage, + ) + po.ovarst( + self.outfile, + "Outboard Blanket Volume if toridally continuous (m3)", + "(vol_blkt_outboard_full_coverage)", + fwbs_variables.vol_blkt_outboard_full_coverage, + ) + po.ovarst( + self.outfile, + "Total Blanket Volume if toridally continuous (m3)", + "(vol_blkt_total_full_coverage)", + fwbs_variables.vol_blkt_total_full_coverage, + ) + + po.ovarst( + self.outfile, + "Inboard Blanket Surface Area with gaps and holes (m2)", + "(a_blkt_inboard_surface)", + build_variables.a_blkt_inboard_surface, + ) + po.ovarst( + self.outfile, + "Outboard Blanket Surface Area with gaps and holes (m2)", + "(a_blkt_outboard_surface)", + build_variables.a_blkt_outboard_surface, + ) + po.ovarst( + self.outfile, + "Total Blanket Surface Area with gaps and holes (m2)", + "(a_blkt_total_surface)", + build_variables.a_blkt_total_surface, + ) + + po.ovarst( + self.outfile, + "Inboard blanket surface area if toridally continuous (m2)", + "(a_blkt_inboard_surface_full_coverage)", + build_variables.a_blkt_inboard_surface_full_coverage, + ) + po.ovarst( + self.outfile, + "Outboard blanket surface area if toridally continuous (m2)", + "(a_blkt_outboard_surface_full_coverage)", + build_variables.a_blkt_outboard_surface_full_coverage, + ) + po.ovarst( + self.outfile, + "Total blanket surface area if toridally continuous (m2)", + "(a_blkt_total_surface_full_coverage)", + build_variables.a_blkt_total_surface_full_coverage, + ) + def primary_coolant_properties(self, output: bool): """Calculates the fluid properties of the Primary Coolant in the FW and BZ. Uses middle value of input and output temperatures of coolant. diff --git a/process/models/blankets/dcll.py b/process/models/blankets/dcll.py index 756804a9f..aaf26d5f9 100644 --- a/process/models/blankets/dcll.py +++ b/process/models/blankets/dcll.py @@ -923,6 +923,8 @@ def write_output(self): # Component Volumes po.osubhd(self.outfile, "Component Volumes :") + self.output_blkt_volumes_and_areas() + po.ovarrf( self.outfile, "First Wall Armour Volume (m3)", diff --git a/process/models/blankets/hcpb.py b/process/models/blankets/hcpb.py index 1b084173b..73bb970e0 100644 --- a/process/models/blankets/hcpb.py +++ b/process/models/blankets/hcpb.py @@ -1260,6 +1260,9 @@ def st_centrepost_nuclear_heating(self, pneut, sh_width): def write_output(self): po.oheadr(self.outfile, "First wall and blanket : CCFE HCPB model") + + self.output_blkt_volumes_and_areas() + po.osubhd(self.outfile, "Blanket Composition by volume :") po.ovarrf( From 099899262d2485d9ed412d176f83f9460aedea19 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Fri, 30 Jan 2026 17:29:53 +0000 Subject: [PATCH 08/11] Add surface area and volume calculations for blanket with full coverage; update plotting functions to display these metrics --- process/core/io/plot_proc.py | 59 ++++++++++++++++++++-- process/models/blankets/blanket_library.py | 4 ++ 2 files changed, 60 insertions(+), 3 deletions(-) diff --git a/process/core/io/plot_proc.py b/process/core/io/plot_proc.py index 82e11f556..7fd594077 100644 --- a/process/core/io/plot_proc.py +++ b/process/core/io/plot_proc.py @@ -10752,8 +10752,8 @@ def plot_blkt_pipe_bends(fig, m_file, scan: int): """ - ax_90 = fig.add_subplot(331) - ax_180 = fig.add_subplot(334) + ax_90 = fig.add_subplot(341) + ax_180 = fig.add_subplot(342) # Get pipe radius from m_file, fallback to 0.1 m r = m_file.get("radius_blkt_channel", scan=scan) @@ -13226,6 +13226,7 @@ def plot_inequality_constraint_equations(axis: plt.Axes, m_file: mf.MFile, scan: def plot_blkt_structure( ax: plt.Axes, + fig: plt.Figure, m_file: mf.MFile, scan: int, radial_build: dict[str, float], @@ -13297,6 +13298,58 @@ def plot_blkt_structure( label="Midplane", ) + textstr_blkt_areas = ( + f"$\\mathbf{{Blanket \\ Areas:}}$\n\n" + f"Inboard blanket, with holes and gaps: {m_file.get('a_blkt_inboard_surface', scan=scan):,.3f} $\\text{{m}}^2$ \n" + f"Outboard blanket, with holes and gaps: {m_file.get('a_blkt_outboard_surface', scan=scan):,.3f} $\\text{{m}}^2$ \n" + f"Total blanket, with holes and gaps: {m_file.get('a_blkt_total_surface', scan=scan):,.3f} $\\text{{m}}^2$ \n\n" + f"Inboard blanket, full coverage: {m_file.get('a_blkt_inboard_surface_full_coverage', scan=scan):,.3f} $\\text{{m}}^2$ \n" + f"Outboard blanket, full coverage: {m_file.get('a_blkt_outboard_surface_full_coverage', scan=scan):,.3f} $\\text{{m}}^2$ \n" + f"Total blanket, full coverage: {m_file.get('a_blkt_total_surface_full_coverage', scan=scan):,.3f} $\\text{{m}}^2$ " + ) + + ax.text( + 0.05, + 0.3, + textstr_blkt_areas, + fontsize=9, + verticalalignment="bottom", + horizontalalignment="left", + transform=fig.transFigure, + bbox={ + "boxstyle": "round", + "facecolor": "wheat", + "alpha": 1.0, + "linewidth": 2, + }, + ) + + textstr_blkt_volumes = ( + f"$\\mathbf{{Blanket \\ Volumes:}}$\n\n" + f"Inboard blanket, with holes and gaps: {m_file.get('vol_blkt_inboard', scan=scan):,.3f} $\\text{{m}}^3$ \n" + f"Outboard blanket, with holes and gaps: {m_file.get('vol_blkt_outboard', scan=scan):,.3f} $\\text{{m}}^3$ \n" + f"Total blanket, with holes and gaps: {m_file.get('vol_blkt_total', scan=scan):,.3f} $\\text{{m}}^3$ \n\n" + f"Inboard blanket, full coverage: {m_file.get('vol_blkt_inboard_full_coverage', scan=scan):,.3f} $\\text{{m}}^3$ \n" + f"Outboard blanket, full coverage: {m_file.get('vol_blkt_outboard_full_coverage', scan=scan):,.3f} $\\text{{m}}^3$ \n" + f"Total blanket, full coverage: {m_file.get('vol_blkt_total_full_coverage', scan=scan):,.3f} $\\text{{m}}^3$ " + ) + + ax.text( + 0.05, + 0.05, + textstr_blkt_volumes, + fontsize=9, + verticalalignment="bottom", + horizontalalignment="left", + transform=fig.transFigure, + bbox={ + "boxstyle": "round", + "facecolor": "wheat", + "alpha": 1.0, + "linewidth": 2, + }, + ) + def main_plot( figs: list[Axes], @@ -13580,7 +13633,7 @@ def main_plot( plot_blkt_pipe_bends(figs[28], m_file, scan) ax_blanket = figs[28].add_subplot(122, aspect="equal") - plot_blkt_structure(ax_blanket, m_file, scan, radial_build, colour_scheme) + plot_blkt_structure(ax_blanket, figs[28], m_file, scan, radial_build, colour_scheme) plot_main_power_flow( figs[29].add_subplot(111, aspect="equal"), m_file, scan, figs[29] diff --git a/process/models/blankets/blanket_library.py b/process/models/blankets/blanket_library.py index 0220a562d..02d3fd105 100644 --- a/process/models/blankets/blanket_library.py +++ b/process/models/blankets/blanket_library.py @@ -611,6 +611,10 @@ def apply_coverage_factors(self): ) fwbs_variables.vol_blkt_inboard = fwbs_variables.vol_blkt_inboard_full_coverage + build_variables.a_blkt_inboard_surface = ( + build_variables.a_blkt_inboard_surface_full_coverage + ) + fwbs_variables.vol_blkt_total = ( fwbs_variables.vol_blkt_inboard_full_coverage + fwbs_variables.vol_blkt_outboard From 9957254c89a616780804da98b95ad74375e1056b Mon Sep 17 00:00:00 2001 From: mn3981 Date: Thu, 5 Mar 2026 16:15:26 +0000 Subject: [PATCH 09/11] Refactor docstrings in BlanketLibrary for improved clarity and consistency; remove unused Dshaped and Elliptical component test parameters --- process/models/blankets/blanket_library.py | 350 ++++++-------- tests/unit/test_blanket_library.py | 512 --------------------- 2 files changed, 142 insertions(+), 720 deletions(-) diff --git a/process/models/blankets/blanket_library.py b/process/models/blankets/blanket_library.py index 02d3fd105..197bd434d 100644 --- a/process/models/blankets/blanket_library.py +++ b/process/models/blankets/blanket_library.py @@ -152,32 +152,35 @@ def calculate_blkt_half_height( dz_blkt_upper: float, n_divertors: int, ) -> float: - """ - Calculate the blanket half-height based on plasma and component geometry. - - :param z_plasma_xpoint_lower: Lower vertical position of the plasma x-point (m) - :type z_plasma_xpoint_lower: float - :param dz_xpoint_divertor: Vertical distance from x-point to divertor (m) - :type dz_xpoint_divertor: float - :param dz_divertor: Vertical thickness of the divertor (m) - :type dz_divertor: float - :param z_plasma_xpoint_upper: Upper vertical position of the plasma x-point (m) - :type z_plasma_xpoint_upper: float - :param dr_fw_plasma_gap_inboard: Radial gap between first wall and plasma on inboard side (m) - :type dr_fw_plasma_gap_inboard: float - :param dr_fw_plasma_gap_outboard: Radial gap between first wall and plasma on outboard side (m) - :type dr_fw_plasma_gap_outboard: float - :param dr_fw_inboard: Radial thickness of the first wall on inboard side (m) - :type dr_fw_inboard: float - :param dr_fw_outboard: Radial thickness of the first wall on outboard side (m) - :type dr_fw_outboard: float - :param dz_blkt_upper: Vertical thickness of the upper blanket (m) - :type dz_blkt_upper: float - :param n_divertors: Number of divertors (1 for single null, 2 for double null) - :type n_divertors: int + """Calculate the blanket half-height based on plasma and component geometry. - :return: Calculated blanket half-height (m) - :rtype: float + Parameters + ---------- + z_plasma_xpoint_lower : float + Lower vertical position of the plasma x-point (m) + dz_xpoint_divertor : float + Vertical distance from x-point to divertor (m) + dz_divertor : float + Vertical thickness of the divertor (m) + z_plasma_xpoint_upper : float + Upper vertical position of the plasma x-point (m) + dr_fw_plasma_gap_inboard : float + Radial gap between first wall and plasma on inboard side (m) + dr_fw_plasma_gap_outboard : float + Radial gap between first wall and plasma on outboard side (m) + dr_fw_inboard : float + Radial thickness of the first wall on inboard side (m) + dr_fw_outboard : float + Radial thickness of the first wall on outboard side (m) + dz_blkt_upper : float + Vertical thickness of the upper blanket (m) + n_divertors : int + Number of divertors (1 for single null, 2 for double null) + + Returns + ------- + float + Calculated blanket half-height (m) """ # Calculate component internal lower half-height (m) # Blanket @@ -201,48 +204,6 @@ def calculate_blkt_half_height( # Average of top and bottom (m) return 0.5 * (z_top + z_bottom) - def dshaped_component(self): - """Calculate component surface area and volume using dshaped scheme - Based on dshaped_blanket, dshaped_shield, dshaped_vv - """ - # Calculate major radius to outer edge of inboard ... - # ... section (m) - r1 = build_variables.r_shld_inboard_inner - - # ... blanket (m) - - r1 = r1 + build_variables.dr_shld_inboard + build_variables.dr_blkt_inboard - - # Horizontal distance between inside edges (m) - # i.e. outer radius of inboard part to inner radius of outboard part - # Blanket - r2 = ( - build_variables.dr_fw_inboard - + build_variables.dr_fw_plasma_gap_inboard - + 2.0 * physics_variables.rminor - + build_variables.dr_fw_plasma_gap_outboard - + build_variables.dr_fw_outboard - ) - - ( - build_variables.a_blkt_inboard_surface, - build_variables.a_blkt_outboard_surface, - build_variables.a_blkt_total_surface, - ) = dshellarea(r1, r2, blanket_library.dz_blkt_half) - - ( - fwbs_variables.vol_blkt_inboard, - fwbs_variables.vol_blkt_outboard, - fwbs_variables.vol_blkt_total, - ) = dshellvol( - r1, - r2, - blanket_library.dz_blkt_half, - build_variables.dr_blkt_inboard, - build_variables.dr_blkt_outboard, - build_variables.dz_blkt_upper, - ) - @staticmethod def calculate_dshaped_blkt_areas( r_shld_inboard_inner: float, @@ -255,29 +216,34 @@ def calculate_dshaped_blkt_areas( dr_fw_outboard: float, dz_blkt_half: float, ) -> tuple[float, float, float]: - """ - Calculate D-shaped blanket surface areas. - - :param r_shld_inboard_inner: Inner radius of inboard shield (m) - :type r_shld_inboard_inner: float - :param dr_shld_inboard: Thickness of inboard shield (m) - :type dr_shld_inboard: float - :param dr_blkt_inboard: Thickness of inboard blanket (m) - :type dr_blkt_inboard: float - :param dr_fw_inboard: Thickness of inboard first wall (m) - :type dr_fw_inboard: float - :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 dr_fw_outboard: Thickness of outboard first wall (m) - :type dr_fw_outboard: float - :param dz_blkt_half: Half-height of the blanket (m) - :type dz_blkt_half: float + """Calculate D-shaped blanket surface areas. + + Parameters + ---------- + r_shld_inboard_inner : float + Inner radius of inboard shield (m) + dr_shld_inboard : float + Thickness of inboard shield (m) + dr_blkt_inboard : float + Thickness of inboard blanket (m) + dr_fw_inboard : float + Thickness of inboard first wall (m) + dr_fw_plasma_gap_inboard : float + Radial gap between inboard first wall and plasma (m) + rminor : float + Minor radius of the plasma (m) + dr_fw_plasma_gap_outboard : float + Radial gap between outboard first wall and plasma (m) + dr_fw_outboard : float + Thickness of outboard first wall (m) + dz_blkt_half : float + Half-height of the blanket (m) - :return: Tuple containing inboard blanket surface area (m²), outboard blanket surface area (m²), and total blanket surface area (m²) + Returns + ------- + tuple[float, float, float] + Tuple containing inboard blanket surface area (m²), outboard blanket surface area (m²), + and total blanket surface area (m²) """ # Calculate major radius to outer edge of inboard ... # ... section (m) @@ -319,33 +285,38 @@ def calculate_dshaped_blkt_volumes( dr_blkt_outboard: float, dz_blkt_upper: float, ) -> tuple[float, float, float]: - """ - Calculate D-shaped blanket volumes. - - :param r_shld_inboard_inner: Inner radius of inboard shield (m) - :type r_shld_inboard_inner: float - :param dr_shld_inboard: Thickness of inboard shield (m) - :type dr_shld_inboard: float - :param dr_blkt_inboard: Thickness of inboard blanket (m) - :type dr_blkt_inboard: float - :param dr_fw_inboard: Thickness of inboard first wall (m) - :type dr_fw_inboard: float - :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 dr_fw_outboard: Thickness of outboard first wall (m) - :type dr_fw_outboard: float - :param dz_blkt_half: Half-height of the blanket (m) - :type dz_blkt_half: float - :param dr_blkt_outboard: Thickness of outboard blanket (m) - :type dr_blkt_outboard: float - :param dz_blkt_upper: Upper vertical thickness of the blanket (m) - :type dz_blkt_upper: float + """Calculate D-shaped blanket volumes. - :return: Tuple containing inboard blanket volume (m³), outboard blanket volume (m³), and total blanket volume (m³) + Parameters + ---------- + r_shld_inboard_inner : float + Inner radius of inboard shield (m) + dr_shld_inboard : float + Thickness of inboard shield (m) + dr_blkt_inboard : float + Thickness of inboard blanket (m) + dr_fw_inboard : float + Thickness of inboard first wall (m) + dr_fw_plasma_gap_inboard : float + Radial gap between inboard first wall and plasma (m) + rminor : float + Minor radius of the plasma (m) + dr_fw_plasma_gap_outboard : float + Radial gap between outboard first wall and plasma (m) + dr_fw_outboard : float + Thickness of outboard first wall (m) + dz_blkt_half : float + Half-height of the blanket (m) + dr_blkt_outboard : float + Thickness of outboard blanket (m) + dz_blkt_upper : float + Upper vertical thickness of the blanket (m) + + Returns + ------- + tuple[float, float, float] + Tuple containing inboard blanket volume (m³), outboard blanket volume (m³), + and total blanket volume (m³) """ # Calculate major radius to outer edge of inboard ... # ... section (m) @@ -393,29 +364,34 @@ def calculate_elliptical_blkt_areas( ) -> tuple[float, float, float]: """Calculate elliptical blanket surface areas. - :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 r_shld_inboard_inner: Inner radius of inboard shield (m) - :type r_shld_inboard_inner: float - :param dr_shld_inboard: Thickness of inboard shield (m) - :type dr_shld_inboard: float - :param dr_blkt_inboard: Thickness of inboard blanket (m) - :type dr_blkt_inboard: float - :param r_shld_outboard_outer: Outer radius of outboard shield (m) - :type r_shld_outboard_outer: float - :param dr_shld_outboard: Thickness of outboard shield (m) - :type dr_shld_outboard: float - :param dr_blkt_outboard: Thickness of outboard blanket (m) - :type dr_blkt_outboard: float - :param dz_blkt_half: Half-height of the blanket (m) - :type dz_blkt_half: float - - :return: Tuple containing inboard blanket surface area (m²), outboard blanket surface area (m²), and total blanket surface area (m²) + Parameters + ---------- + rmajor : float + Major radius of the plasma (m) + rminor : float + Minor radius of the plasma (m) + triang : float + Triangularity of the plasma + r_shld_inboard_inner : float + Inner radius of inboard shield (m) + dr_shld_inboard : float + Thickness of inboard shield (m) + dr_blkt_inboard : float + Thickness of inboard blanket (m) + r_shld_outboard_outer : float + Outer radius of outboard shield (m) + dr_shld_outboard : float + Thickness of outboard shield (m) + dr_blkt_outboard : float + Thickness of outboard blanket (m) + dz_blkt_half : float + Half-height of the blanket (m) + Returns + ------- + tuple[float, float, float] + Tuple containing inboard blanket surface area (m²), outboard blanket surface area (m²), + and total blanket surface area (m²) """ # Major radius to centre of inboard and outboard ellipses (m) # (coincident in radius with top of plasma) @@ -459,31 +435,36 @@ def calculate_elliptical_blkt_volumes( ) -> tuple[float, float, float]: """Calculate elliptical blanket volumes. - :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 r_shld_inboard_inner: Inner radius of inboard shield (m) - :type r_shld_inboard_inner: float - :param dr_shld_inboard: Thickness of inboard shield (m) - :type dr_shld_inboard: float - :param dr_blkt_inboard: Thickness of inboard blanket (m) - :type dr_blkt_inboard: float - :param r_shld_outboard_outer: Outer radius of outboard shield (m) - :type r_shld_outboard_outer: float - :param dr_shld_outboard: Thickness of outboard shield (m) - :type dr_shld_outboard: float - :param dr_blkt_outboard: Thickness of outboard blanket (m) - :type dr_blkt_outboard: float - :param dz_blkt_half: Half-height of the blanket (m) - :type dz_blkt_half: float - :param dz_blkt_upper: Upper vertical thickness of the blanket (m) - :type dz_blkt_upper: float - - :return: Tuple containing inboard blanket volume (m³), outboard blanket volume (m³), and total blanket volume (m³) + Parameters + ---------- + rmajor : float + Major radius of the plasma (m) + rminor : float + Minor radius of the plasma (m) + triang : float + Triangularity of the plasma + r_shld_inboard_inner : float + Inner radius of inboard shield (m) + dr_shld_inboard : float + Thickness of inboard shield (m) + dr_blkt_inboard : float + Thickness of inboard blanket (m) + r_shld_outboard_outer : float + Outer radius of outboard shield (m) + dr_shld_outboard : float + Thickness of outboard shield (m) + dr_blkt_outboard : float + Thickness of outboard blanket (m) + dz_blkt_half : float + Half-height of the blanket (m) + dz_blkt_upper : float + Upper vertical thickness of the blanket (m) + Returns + ------- + tuple[float, float, float] + Tuple containing inboard blanket volume (m³), outboard blanket volume (m³), + and total blanket volume (m³) """ # Major radius to centre of inboard and outboard ellipses (m) # (coincident in radius with top of plasma) @@ -519,53 +500,6 @@ def calculate_elliptical_blkt_volumes( return vol_blkt_inboard, vol_blkt_outboard, vol_blkt_total - def elliptical_component(self): - """Calculate component surface area and volume using elliptical scheme - Based on elliptical_blanket, elliptical_shield, elliptical_vv - """ - # Major radius to centre of inboard and outboard ellipses (m) - # (coincident in radius with top of plasma) - r1 = ( - physics_variables.rmajor - - physics_variables.rminor * physics_variables.triang - ) - - # Calculate distance between r1 and outer edge of inboard ... - # ... section (m) - r2 = r1 - build_variables.r_shld_inboard_inner - - r2 = r2 - build_variables.dr_shld_inboard - build_variables.dr_blkt_inboard - - # Calculate distance between r1 and inner edge of outboard ... - # ... section (m) - r3 = build_variables.r_shld_outboard_outer - r1 - - r3 = r3 - build_variables.dr_shld_outboard - build_variables.dr_blkt_outboard - - # Calculate surface area, assuming 100% coverage - - ( - build_variables.a_blkt_inboard_surface, - build_variables.a_blkt_outboard_surface, - build_variables.a_blkt_total_surface, - ) = eshellarea(r1, r2, r3, blanket_library.dz_blkt_half) - - # Calculate volumes, assuming 100% coverage - - ( - fwbs_variables.vol_blkt_inboard, - fwbs_variables.vol_blkt_outboard, - fwbs_variables.vol_blkt_total, - ) = eshellvol( - r1, - r2, - r3, - blanket_library.dz_blkt_half, - build_variables.dr_blkt_inboard, - build_variables.dr_blkt_outboard, - build_variables.dz_blkt_upper, - ) - def apply_coverage_factors(self): """Apply coverage factors to volumes diff --git a/tests/unit/test_blanket_library.py b/tests/unit/test_blanket_library.py index 799848ea9..c286e7601 100644 --- a/tests/unit/test_blanket_library.py +++ b/tests/unit/test_blanket_library.py @@ -4,7 +4,6 @@ import pytest from process.data_structure import ( - blanket_library, build_variables, divertor_variables, fwbs_variables, @@ -444,517 +443,6 @@ def test_calculate_blkt_half_height(componenthalfheightparam, blanket_library_fi assert half_height == pytest.approx(componenthalfheightparam.expected_half_height) -class DshapedComponentParam(NamedTuple): - r_shld_inboard_inner: Any = None - dr_shld_inboard: Any = None - dr_blkt_inboard: Any = None - dr_fw_inboard: Any = None - dr_fw_plasma_gap_inboard: Any = None - dr_fw_plasma_gap_outboard: Any = None - dr_fw_outboard: Any = None - a_blkt_inboard_surface: Any = None - a_blkt_outboard_surface: Any = None - a_blkt_total_surface: Any = None - dr_blkt_outboard: Any = None - dz_blkt_upper: Any = None - a_shld_inboard_surface: Any = None - a_shld_outboard_surface: Any = None - a_shld_total_surface: Any = None - dr_shld_outboard: Any = None - dz_shld_upper: Any = None - r_shld_outboard_outer: Any = None - dr_vv_inboard: Any = None - dr_vv_outboard: Any = None - dz_vv_upper: Any = None - dz_vv_lower: Any = None - vol_blkt_inboard: Any = None - vol_blkt_outboard: Any = None - vol_blkt_total: Any = None - vol_shld_total: Any = None - vol_vv: Any = None - rminor: Any = None - vol_shld_inboard: Any = None - vol_shld_outboard: Any = None - vol_vv_inboard: Any = None - vol_vv_outboard: Any = None - dz_blkt_half: Any = None - dz_shld_half: Any = None - dz_vv_half: Any = None - expected_a_blkt_inboard_surface: Any = None - expected_a_blkt_outboard_surface: Any = None - expected_a_blkt_total_surface: Any = None - expected_a_shld_inboard_surface: Any = None - expected_a_shld_outboard_surface: Any = None - expected_a_shld_total_surface: Any = None - expected_vol_blkt_outboard: Any = None - expected_volblkt: Any = None - expected_vol_shld_total: Any = None - expected_vol_vv: Any = None - expected_vol_shld_inboard: Any = None - expected_vol_shld_outboard: Any = None - expected_vol_vv_inboard: Any = None - expected_vol_vv_outboard: Any = None - expected_icomponent: Any = None - - -@pytest.mark.parametrize( - "dshapedcomponentparam", - ( - DshapedComponentParam( - r_shld_inboard_inner=1.5, - dr_shld_inboard=0.40000000000000002, - dr_blkt_inboard=0, - dr_fw_inboard=0.018000000000000002, - dr_fw_plasma_gap_inboard=0.10000000000000001, - dr_fw_plasma_gap_outboard=0.10000000000000001, - dr_fw_outboard=0.018000000000000002, - a_blkt_inboard_surface=0, - a_blkt_outboard_surface=0, - a_blkt_total_surface=0, - dr_blkt_outboard=1, - dz_blkt_upper=0.5, - a_shld_inboard_surface=0, - a_shld_outboard_surface=0, - a_shld_total_surface=0, - dr_shld_outboard=0.30000000000000004, - dz_shld_upper=0.60000000000000009, - r_shld_outboard_outer=8.4000000000000004, - dr_vv_inboard=0.20000000000000001, - dr_vv_outboard=0.30000000000000004, - dz_vv_upper=0.30000000000000004, - dz_vv_lower=0.30000000000000004, - vol_blkt_inboard=0, - vol_blkt_outboard=0, - vol_blkt_total=0, - vol_shld_total=0, - vol_vv=0, - rminor=2.5, - vol_shld_inboard=0, - vol_shld_outboard=0, - vol_vv_inboard=0, - vol_vv_outboard=0, - dz_blkt_half=8.25, - dz_shld_half=8.75, - dz_vv_half=9.4349999999999987, - expected_a_blkt_inboard_surface=196.97785938008002, - expected_a_blkt_outboard_surface=852.24160940262459, - expected_a_blkt_total_surface=1049.2194687827046, - expected_a_shld_inboard_surface=0, - expected_a_shld_outboard_surface=0, - expected_a_shld_total_surface=0, - expected_vol_blkt_outboard=691.06561956756764, - expected_volblkt=691.06561956756764, - expected_vol_shld_total=0, - expected_vol_vv=0, - expected_vol_shld_inboard=0, - expected_vol_shld_outboard=0, - expected_vol_vv_inboard=0, - expected_vol_vv_outboard=0, - expected_icomponent=0, - ), - ), -) -def test_dshaped_component(dshapedcomponentparam, monkeypatch, blanket_library_fixture): - """ - Automatically generated Regression Unit Test for dshaped_component. - - This test was generated using data from tests/regression/input_files/st_regression.IN.DAT. - - :param dshapedcomponentparam: the data used to mock and assert in this test. - :type dshapedcomponentparam: dshapedcomponentparam - - :param monkeypatch: pytest fixture used to mock module/class variables - :type monkeypatch: _pytest.monkeypatch.monkeypatch - """ - monkeypatch.setattr( - build_variables, - "r_shld_inboard_inner", - dshapedcomponentparam.r_shld_inboard_inner, - ) - monkeypatch.setattr( - build_variables, "dr_shld_inboard", dshapedcomponentparam.dr_shld_inboard - ) - monkeypatch.setattr( - build_variables, "dr_blkt_inboard", dshapedcomponentparam.dr_blkt_inboard - ) - monkeypatch.setattr( - build_variables, "dr_fw_inboard", dshapedcomponentparam.dr_fw_inboard - ) - monkeypatch.setattr( - build_variables, - "dr_fw_plasma_gap_inboard", - dshapedcomponentparam.dr_fw_plasma_gap_inboard, - ) - monkeypatch.setattr( - build_variables, - "dr_fw_plasma_gap_outboard", - dshapedcomponentparam.dr_fw_plasma_gap_outboard, - ) - monkeypatch.setattr( - build_variables, "dr_fw_outboard", dshapedcomponentparam.dr_fw_outboard - ) - monkeypatch.setattr( - build_variables, - "a_blkt_inboard_surface", - dshapedcomponentparam.a_blkt_inboard_surface, - ) - monkeypatch.setattr( - build_variables, - "a_blkt_outboard_surface", - dshapedcomponentparam.a_blkt_outboard_surface, - ) - monkeypatch.setattr( - build_variables, - "a_blkt_total_surface", - dshapedcomponentparam.a_blkt_total_surface, - ) - monkeypatch.setattr( - build_variables, "dr_blkt_outboard", dshapedcomponentparam.dr_blkt_outboard - ) - monkeypatch.setattr( - build_variables, "dz_blkt_upper", dshapedcomponentparam.dz_blkt_upper - ) - monkeypatch.setattr( - build_variables, - "a_shld_inboard_surface", - dshapedcomponentparam.a_shld_inboard_surface, - ) - monkeypatch.setattr( - build_variables, - "a_shld_outboard_surface", - dshapedcomponentparam.a_shld_outboard_surface, - ) - monkeypatch.setattr( - build_variables, - "a_shld_total_surface", - dshapedcomponentparam.a_shld_total_surface, - ) - monkeypatch.setattr( - build_variables, "dr_shld_outboard", dshapedcomponentparam.dr_shld_outboard - ) - monkeypatch.setattr( - build_variables, "dz_shld_upper", dshapedcomponentparam.dz_shld_upper - ) - monkeypatch.setattr( - build_variables, - "r_shld_outboard_outer", - dshapedcomponentparam.r_shld_outboard_outer, - ) - monkeypatch.setattr( - build_variables, "dr_vv_inboard", dshapedcomponentparam.dr_vv_inboard - ) - monkeypatch.setattr( - build_variables, "dr_vv_outboard", dshapedcomponentparam.dr_vv_outboard - ) - monkeypatch.setattr( - build_variables, "dz_vv_upper", dshapedcomponentparam.dz_vv_upper - ) - monkeypatch.setattr( - build_variables, "dz_vv_lower", dshapedcomponentparam.dz_vv_lower - ) - monkeypatch.setattr( - fwbs_variables, "vol_blkt_inboard", dshapedcomponentparam.vol_blkt_inboard - ) - monkeypatch.setattr( - fwbs_variables, "vol_blkt_outboard", dshapedcomponentparam.vol_blkt_outboard - ) - monkeypatch.setattr( - fwbs_variables, "vol_blkt_total", dshapedcomponentparam.vol_blkt_total - ) - monkeypatch.setattr( - fwbs_variables, "vol_shld_total", dshapedcomponentparam.vol_shld_total - ) - monkeypatch.setattr(fwbs_variables, "vol_vv", dshapedcomponentparam.vol_vv) - monkeypatch.setattr(physics_variables, "rminor", dshapedcomponentparam.rminor) - monkeypatch.setattr( - blanket_library, "vol_shld_inboard", dshapedcomponentparam.vol_shld_inboard - ) - monkeypatch.setattr( - blanket_library, "vol_shld_outboard", dshapedcomponentparam.vol_shld_outboard - ) - monkeypatch.setattr( - blanket_library, "vol_vv_inboard", dshapedcomponentparam.vol_vv_inboard - ) - monkeypatch.setattr( - blanket_library, "vol_vv_outboard", dshapedcomponentparam.vol_vv_outboard - ) - monkeypatch.setattr( - blanket_library, "dz_blkt_half", dshapedcomponentparam.dz_blkt_half - ) - monkeypatch.setattr( - blanket_library, "dz_shld_half", dshapedcomponentparam.dz_shld_half - ) - monkeypatch.setattr(blanket_library, "dz_vv_half", dshapedcomponentparam.dz_vv_half) - - blanket_library_fixture.dshaped_component() - - assert build_variables.a_blkt_inboard_surface == pytest.approx( - dshapedcomponentparam.expected_a_blkt_inboard_surface - ) - assert build_variables.a_blkt_outboard_surface == pytest.approx( - dshapedcomponentparam.expected_a_blkt_outboard_surface - ) - assert build_variables.a_blkt_total_surface == pytest.approx( - dshapedcomponentparam.expected_a_blkt_total_surface - ) - assert fwbs_variables.vol_blkt_outboard == pytest.approx( - dshapedcomponentparam.expected_vol_blkt_outboard - ) - assert fwbs_variables.vol_blkt_total == pytest.approx( - dshapedcomponentparam.expected_volblkt - ) - - -class EllipticalComponentParam(NamedTuple): - r_shld_inboard_inner: Any = None - dr_shld_inboard: Any = None - dr_blkt_inboard: Any = None - r_shld_outboard_outer: Any = None - dr_shld_outboard: Any = None - dr_blkt_outboard: Any = None - a_blkt_inboard_surface: Any = None - a_blkt_outboard_surface: Any = None - a_blkt_total_surface: Any = None - dz_blkt_upper: Any = None - a_shld_inboard_surface: Any = None - a_shld_outboard_surface: Any = None - a_shld_total_surface: Any = None - dz_shld_upper: Any = None - dr_vv_inboard: Any = None - dr_vv_outboard: Any = None - dz_vv_upper: Any = None - dz_vv_lower: Any = None - vol_blkt_inboard: Any = None - vol_blkt_outboard: Any = None - vol_blkt_total: Any = None - vol_shld_total: Any = None - vol_vv: Any = None - rmajor: Any = None - rminor: Any = None - triang: Any = None - vol_shld_inboard: Any = None - vol_shld_outboard: Any = None - vol_vv_inboard: Any = None - vol_vv_outboard: Any = None - dz_blkt_half: Any = None - dz_shld_half: Any = None - dz_vv_half: Any = None - icomponent: Any = None - expected_a_blkt_inboard_surface: Any = None - expected_a_blkt_outboard_surface: Any = None - expected_a_blkt_total_surface: Any = None - expected_a_shld_inboard_surface: Any = None - expected_a_shld_outboard_surface: Any = None - expected_a_shld_total_surface: Any = None - expected_vol_blkt_inboard: Any = None - expected_vol_blkt_outboard: Any = None - expected_volblkt: Any = None - expected_vol_shld_total: Any = None - expected_vol_vv: Any = None - expected_vol_shld_inboard: Any = None - expected_vol_shld_outboard: Any = None - expected_vol_vv_inboard: Any = None - expected_vol_vv_outboard: Any = None - expected_icomponent: Any = None - - -@pytest.mark.parametrize( - "ellipticalcomponentparam", - ( - EllipticalComponentParam( - r_shld_inboard_inner=4.0833333333333339, - dr_shld_inboard=0.30000000000000004, - dr_blkt_inboard=0.70000000000000007, - r_shld_outboard_outer=12.716666666666667, - dr_shld_outboard=0.80000000000000004, - dr_blkt_outboard=1, - a_blkt_inboard_surface=0, - a_blkt_outboard_surface=0, - a_blkt_total_surface=0, - dz_blkt_upper=0.85000000000000009, - a_shld_inboard_surface=0, - a_shld_outboard_surface=0, - a_shld_total_surface=0, - dz_shld_upper=0.59999999999999998, - dr_vv_inboard=0.30000000000000004, - dr_vv_outboard=0.30000000000000004, - dz_vv_upper=0.30000000000000004, - dz_vv_lower=0.30000000000000004, - vol_blkt_inboard=0, - vol_blkt_outboard=0, - vol_blkt_total=0, - vol_shld_total=0, - vol_vv=0, - rmajor=8, - rminor=2.6666666666666665, - triang=0.5, - vol_shld_inboard=0, - vol_shld_outboard=0, - vol_vv_inboard=0, - vol_vv_outboard=0, - dz_blkt_half=5.9532752487304119, - dz_shld_half=6.8032752487304133, - dz_vv_half=7.5032752487304135, - icomponent=0, - expected_a_blkt_inboard_surface=664.9687712975541, - expected_a_blkt_outboard_surface=1101.3666396424403, - expected_a_blkt_total_surface=1766.3354109399943, - expected_a_shld_inboard_surface=0, - expected_a_shld_outboard_surface=0, - expected_a_shld_total_surface=0, - expected_vol_blkt_inboard=315.83946385183026, - expected_vol_blkt_outboard=1020.3677420460117, - expected_volblkt=1336.207205897842, - expected_vol_shld_total=0, - expected_vol_vv=0, - expected_vol_shld_inboard=0, - expected_vol_shld_outboard=0, - expected_vol_vv_inboard=0, - expected_vol_vv_outboard=0, - expected_icomponent=0, - ), - ), -) -def test_elliptical_component( - ellipticalcomponentparam, monkeypatch, blanket_library_fixture -): - """ - Automatically generated Regression Unit Test for elliptical_component. - - This test was generated using data from tests/regression/input_files/large_tokamak_eval.IN.DAT. - - :param ellipticalcomponentparam: the data used to mock and assert in this test. - :type ellipticalcomponentparam: ellipticalcomponentparam - - :param monkeypatch: pytest fixture used to mock module/class variables - :type monkeypatch: _pytest.monkeypatch.monkeypatch - """ - monkeypatch.setattr( - build_variables, - "r_shld_inboard_inner", - ellipticalcomponentparam.r_shld_inboard_inner, - ) - monkeypatch.setattr( - build_variables, "dr_shld_inboard", ellipticalcomponentparam.dr_shld_inboard - ) - monkeypatch.setattr( - build_variables, "dr_blkt_inboard", ellipticalcomponentparam.dr_blkt_inboard - ) - monkeypatch.setattr( - build_variables, - "r_shld_outboard_outer", - ellipticalcomponentparam.r_shld_outboard_outer, - ) - monkeypatch.setattr( - build_variables, "dr_shld_outboard", ellipticalcomponentparam.dr_shld_outboard - ) - monkeypatch.setattr( - build_variables, "dr_blkt_outboard", ellipticalcomponentparam.dr_blkt_outboard - ) - monkeypatch.setattr( - build_variables, - "a_blkt_inboard_surface", - ellipticalcomponentparam.a_blkt_inboard_surface, - ) - monkeypatch.setattr( - build_variables, - "a_blkt_outboard_surface", - ellipticalcomponentparam.a_blkt_outboard_surface, - ) - monkeypatch.setattr( - build_variables, - "a_blkt_total_surface", - ellipticalcomponentparam.a_blkt_total_surface, - ) - monkeypatch.setattr( - build_variables, "dz_blkt_upper", ellipticalcomponentparam.dz_blkt_upper - ) - monkeypatch.setattr( - build_variables, - "a_shld_inboard_surface", - ellipticalcomponentparam.a_shld_inboard_surface, - ) - monkeypatch.setattr( - build_variables, - "a_shld_outboard_surface", - ellipticalcomponentparam.a_shld_outboard_surface, - ) - monkeypatch.setattr( - build_variables, - "a_shld_total_surface", - ellipticalcomponentparam.a_shld_total_surface, - ) - monkeypatch.setattr( - build_variables, "dz_shld_upper", ellipticalcomponentparam.dz_shld_upper - ) - monkeypatch.setattr( - fwbs_variables, "vol_blkt_inboard", ellipticalcomponentparam.vol_blkt_inboard - ) - monkeypatch.setattr( - fwbs_variables, "vol_blkt_outboard", ellipticalcomponentparam.vol_blkt_outboard - ) - monkeypatch.setattr( - fwbs_variables, "vol_blkt_total", ellipticalcomponentparam.vol_blkt_total - ) - monkeypatch.setattr( - fwbs_variables, "vol_shld_total", ellipticalcomponentparam.vol_shld_total - ) - monkeypatch.setattr(physics_variables, "rmajor", ellipticalcomponentparam.rmajor) - monkeypatch.setattr(physics_variables, "rminor", ellipticalcomponentparam.rminor) - monkeypatch.setattr(physics_variables, "triang", ellipticalcomponentparam.triang) - monkeypatch.setattr( - blanket_library, "vol_shld_inboard", ellipticalcomponentparam.vol_shld_inboard - ) - monkeypatch.setattr( - blanket_library, "vol_shld_outboard", ellipticalcomponentparam.vol_shld_outboard - ) - monkeypatch.setattr( - blanket_library, "dz_blkt_half", ellipticalcomponentparam.dz_blkt_half - ) - monkeypatch.setattr( - blanket_library, "dz_shld_half", ellipticalcomponentparam.dz_shld_half - ) - - blanket_library_fixture.elliptical_component() - - assert build_variables.a_blkt_inboard_surface == pytest.approx( - ellipticalcomponentparam.expected_a_blkt_inboard_surface - ) - assert build_variables.a_blkt_outboard_surface == pytest.approx( - ellipticalcomponentparam.expected_a_blkt_outboard_surface - ) - assert build_variables.a_blkt_total_surface == pytest.approx( - ellipticalcomponentparam.expected_a_blkt_total_surface - ) - assert build_variables.a_shld_inboard_surface == pytest.approx( - ellipticalcomponentparam.expected_a_shld_inboard_surface - ) - assert build_variables.a_shld_outboard_surface == pytest.approx( - ellipticalcomponentparam.expected_a_shld_outboard_surface - ) - assert build_variables.a_shld_total_surface == pytest.approx( - ellipticalcomponentparam.expected_a_shld_total_surface - ) - assert fwbs_variables.vol_blkt_inboard == pytest.approx( - ellipticalcomponentparam.expected_vol_blkt_inboard - ) - assert fwbs_variables.vol_blkt_outboard == pytest.approx( - ellipticalcomponentparam.expected_vol_blkt_outboard - ) - assert fwbs_variables.vol_blkt_total == pytest.approx( - ellipticalcomponentparam.expected_volblkt - ) - assert fwbs_variables.vol_shld_total == pytest.approx( - ellipticalcomponentparam.expected_vol_shld_total - ) - assert blanket_library.vol_shld_inboard == pytest.approx( - ellipticalcomponentparam.expected_vol_shld_inboard - ) - assert blanket_library.vol_shld_outboard == pytest.approx( - ellipticalcomponentparam.expected_vol_shld_outboard - ) - - class ApplyCoverageFactorsParam(NamedTuple): a_blkt_outboard_surface: Any = None a_blkt_total_surface: Any = None From 5ffb0b4445193c39cf142b79f945685cb6f01714 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Thu, 5 Mar 2026 16:25:46 +0000 Subject: [PATCH 10/11] Add full coverage parameters to ApplyCoverageFactorsParam and update tests --- tests/unit/test_blanket_library.py | 35 ++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/tests/unit/test_blanket_library.py b/tests/unit/test_blanket_library.py index c286e7601..8ee272879 100644 --- a/tests/unit/test_blanket_library.py +++ b/tests/unit/test_blanket_library.py @@ -445,13 +445,18 @@ def test_calculate_blkt_half_height(componenthalfheightparam, blanket_library_fi class ApplyCoverageFactorsParam(NamedTuple): a_blkt_outboard_surface: Any = None + a_blkt_outboard_surface_full_coverage: Any = None a_blkt_total_surface: Any = None + a_blkt_total_surface_full_coverage: Any = None a_blkt_inboard_surface: Any = None + a_blkt_inboard_surface_full_coverage: Any = None f_ster_div_single: Any = None f_a_fw_outboard_hcd: Any = None vol_blkt_outboard: Any = None vol_blkt_inboard: Any = None + vol_blkt_inboard_full_coverage: Any = None vol_blkt_total: Any = None + vol_blkt_total_full_coverage: Any = None fvolsi: Any = None fvolso: Any = None vol_shld_total: Any = None @@ -470,13 +475,18 @@ class ApplyCoverageFactorsParam(NamedTuple): ( ApplyCoverageFactorsParam( a_blkt_outboard_surface=1101.3666396424403, + a_blkt_outboard_surface_full_coverage=1101.3666396424403, a_blkt_total_surface=1766.3354109399943, + a_blkt_total_surface_full_coverage=1766.3354109399943, a_blkt_inboard_surface=664.9687712975541, + a_blkt_inboard_surface_full_coverage=664.9687712975541, f_ster_div_single=0.115, f_a_fw_outboard_hcd=0, vol_blkt_outboard=1020.3677420460117, vol_blkt_inboard=315.83946385183026, + vol_blkt_inboard_full_coverage=315.83946385183026, vol_blkt_total=1336.207205897842, + vol_blkt_total_full_coverage=1336.207205897842, fvolsi=1, fvolso=0.64000000000000001, n_divertors=1, @@ -507,16 +517,31 @@ def test_apply_coverage_factors( "a_blkt_outboard_surface", applycoveragefactorsparam.a_blkt_outboard_surface, ) + monkeypatch.setattr( + build_variables, + "a_blkt_outboard_surface_full_coverage", + applycoveragefactorsparam.a_blkt_outboard_surface_full_coverage, + ) monkeypatch.setattr( build_variables, "a_blkt_total_surface", applycoveragefactorsparam.a_blkt_total_surface, ) + monkeypatch.setattr( + build_variables, + "a_blkt_total_surface_full_coverage", + applycoveragefactorsparam.a_blkt_total_surface_full_coverage, + ) monkeypatch.setattr( build_variables, "a_blkt_inboard_surface", applycoveragefactorsparam.a_blkt_inboard_surface, ) + monkeypatch.setattr( + build_variables, + "a_blkt_inboard_surface_full_coverage", + applycoveragefactorsparam.a_blkt_inboard_surface_full_coverage, + ) monkeypatch.setattr( fwbs_variables, "f_ster_div_single", applycoveragefactorsparam.f_ster_div_single ) @@ -531,9 +556,19 @@ def test_apply_coverage_factors( monkeypatch.setattr( fwbs_variables, "vol_blkt_inboard", applycoveragefactorsparam.vol_blkt_inboard ) + monkeypatch.setattr( + fwbs_variables, + "vol_blkt_inboard_full_coverage", + applycoveragefactorsparam.vol_blkt_inboard_full_coverage, + ) monkeypatch.setattr( fwbs_variables, "vol_blkt_total", applycoveragefactorsparam.vol_blkt_total ) + monkeypatch.setattr( + fwbs_variables, + "vol_blkt_total_full_coverage", + applycoveragefactorsparam.vol_blkt_total_full_coverage, + ) monkeypatch.setattr(fwbs_variables, "fvolsi", applycoveragefactorsparam.fvolsi) monkeypatch.setattr(fwbs_variables, "fvolso", applycoveragefactorsparam.fvolso) monkeypatch.setattr( From 126754bc89ad06482c5241d2cdcbaa9ce191ba72 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Fri, 6 Mar 2026 16:27:06 +0000 Subject: [PATCH 11/11] Add regression tests for D-shaped and elliptical blanket area and volume calculations --- tests/unit/test_blanket_library.py | 303 +++++++++++++++++++++++++++++ 1 file changed, 303 insertions(+) diff --git a/tests/unit/test_blanket_library.py b/tests/unit/test_blanket_library.py index 8ee272879..f43bb2cc5 100644 --- a/tests/unit/test_blanket_library.py +++ b/tests/unit/test_blanket_library.py @@ -1216,3 +1216,306 @@ def test_liquid_breeder_pressure_drop_mhd( assert liquid_breeder_pressure_drop_mhd_out == pytest.approx( liquidbreederpressuredropmhdparam.expected_liquid_breeder_pressure_drop_mhd_out ) + + +class CalculateDshapedBlktAreasParam(NamedTuple): + r_shld_inboard_inner: Any = None + dr_shld_inboard: Any = None + dr_blkt_inboard: Any = None + dr_fw_inboard: Any = None + dr_fw_plasma_gap_inboard: Any = None + rminor: Any = None + dr_fw_plasma_gap_outboard: Any = None + dr_fw_outboard: Any = None + dz_blkt_half: Any = None + expected_a_blkt_inboard_surface: Any = None + expected_a_blkt_outboard_surface: Any = None + expected_a_blkt_total_surface: Any = None + + +@pytest.mark.parametrize( + "calculatedshapedblktareasparam", + ( + CalculateDshapedBlktAreasParam( + r_shld_inboard_inner=1.5, + dr_shld_inboard=0.4, + dr_blkt_inboard=0.0, + dr_fw_inboard=0.018, + dr_fw_plasma_gap_inboard=0.1, + rminor=2.5, + dr_fw_plasma_gap_outboard=0.1, + dr_fw_outboard=0.018, + dz_blkt_half=8.25, + expected_a_blkt_inboard_surface=196.97785938008002, + expected_a_blkt_outboard_surface=852.24160940262459, + expected_a_blkt_total_surface=1049.2194687827046, + ), + ), +) +def test_calculate_dshaped_blkt_areas( + calculatedshapedblktareasparam, blanket_library_fixture +): + """ + Regression Unit Test for calculate_dshaped_blkt_areas. + + This test was generated using data from tests/regression/input_files/st_regression.IN.DAT. + + :param calculatedshapedblktareasparam: the data used in this test. + :type calculatedshapedblktareasparam: CalculateDshapedBlktAreasParam + """ + ( + a_blkt_inboard_surface, + a_blkt_outboard_surface, + a_blkt_total_surface, + ) = blanket_library_fixture.calculate_dshaped_blkt_areas( + r_shld_inboard_inner=calculatedshapedblktareasparam.r_shld_inboard_inner, + dr_shld_inboard=calculatedshapedblktareasparam.dr_shld_inboard, + dr_blkt_inboard=calculatedshapedblktareasparam.dr_blkt_inboard, + dr_fw_inboard=calculatedshapedblktareasparam.dr_fw_inboard, + dr_fw_plasma_gap_inboard=calculatedshapedblktareasparam.dr_fw_plasma_gap_inboard, + rminor=calculatedshapedblktareasparam.rminor, + dr_fw_plasma_gap_outboard=calculatedshapedblktareasparam.dr_fw_plasma_gap_outboard, + dr_fw_outboard=calculatedshapedblktareasparam.dr_fw_outboard, + dz_blkt_half=calculatedshapedblktareasparam.dz_blkt_half, + ) + + assert a_blkt_inboard_surface == pytest.approx( + calculatedshapedblktareasparam.expected_a_blkt_inboard_surface + ) + assert a_blkt_outboard_surface == pytest.approx( + calculatedshapedblktareasparam.expected_a_blkt_outboard_surface + ) + assert a_blkt_total_surface == pytest.approx( + calculatedshapedblktareasparam.expected_a_blkt_total_surface + ) + + +class CalculateDshapedBlktVolumesParam(NamedTuple): + r_shld_inboard_inner: Any = None + dr_shld_inboard: Any = None + dr_blkt_inboard: Any = None + dr_fw_inboard: Any = None + dr_fw_plasma_gap_inboard: Any = None + rminor: Any = None + dr_fw_plasma_gap_outboard: Any = None + dr_fw_outboard: Any = None + dz_blkt_half: Any = None + dr_blkt_outboard: Any = None + dz_blkt_upper: Any = None + expected_vol_blkt_inboard: Any = None + expected_vol_blkt_outboard: Any = None + expected_vol_blkt_total: Any = None + + +@pytest.mark.parametrize( + "calculatedshapedblktvolumesparam", + ( + CalculateDshapedBlktVolumesParam( + r_shld_inboard_inner=1.5, + dr_shld_inboard=0.4, + dr_blkt_inboard=0.6, + dr_fw_inboard=0.018, + dr_fw_plasma_gap_inboard=0.1, + rminor=2.5, + dr_fw_plasma_gap_outboard=0.1, + dr_fw_outboard=0.018, + dz_blkt_half=8.25, + dr_blkt_outboard=1.0, + dz_blkt_upper=0.85, + expected_vol_blkt_inboard=150.94724381968237, + expected_vol_blkt_outboard=869.2500537130913, + expected_vol_blkt_total=1020.1972975327737, + ), + ), +) +def test_calculate_dshaped_blkt_volumes( + calculatedshapedblktvolumesparam, blanket_library_fixture +): + """ + Regression Unit Test for calculate_dshaped_blkt_volumes. + + This test was generated using data from tests/regression/input_files/st_regression.IN.DAT. + + :param calculatedshapedblktvolumesparam: the data used in this test. + :type calculatedshapedblktvolumesparam: CalculateDshapedBlktVolumesParam + """ + ( + vol_blkt_inboard, + vol_blkt_outboard, + vol_blkt_total, + ) = blanket_library_fixture.calculate_dshaped_blkt_volumes( + r_shld_inboard_inner=calculatedshapedblktvolumesparam.r_shld_inboard_inner, + dr_shld_inboard=calculatedshapedblktvolumesparam.dr_shld_inboard, + dr_blkt_inboard=calculatedshapedblktvolumesparam.dr_blkt_inboard, + dr_fw_inboard=calculatedshapedblktvolumesparam.dr_fw_inboard, + dr_fw_plasma_gap_inboard=calculatedshapedblktvolumesparam.dr_fw_plasma_gap_inboard, + rminor=calculatedshapedblktvolumesparam.rminor, + dr_fw_plasma_gap_outboard=calculatedshapedblktvolumesparam.dr_fw_plasma_gap_outboard, + dr_fw_outboard=calculatedshapedblktvolumesparam.dr_fw_outboard, + dz_blkt_half=calculatedshapedblktvolumesparam.dz_blkt_half, + dr_blkt_outboard=calculatedshapedblktvolumesparam.dr_blkt_outboard, + dz_blkt_upper=calculatedshapedblktvolumesparam.dz_blkt_upper, + ) + + assert vol_blkt_inboard == pytest.approx( + calculatedshapedblktvolumesparam.expected_vol_blkt_inboard + ) + assert vol_blkt_outboard == pytest.approx( + calculatedshapedblktvolumesparam.expected_vol_blkt_outboard + ) + assert vol_blkt_total == pytest.approx( + calculatedshapedblktvolumesparam.expected_vol_blkt_total + ) + + +class CalculateEllipticalBlktAreasParam(NamedTuple): + rmajor: Any = None + rminor: Any = None + triang: Any = None + r_shld_inboard_inner: Any = None + dr_shld_inboard: Any = None + dr_blkt_inboard: Any = None + r_shld_outboard_outer: Any = None + dr_shld_outboard: Any = None + dr_blkt_outboard: Any = None + dz_blkt_half: Any = None + expected_a_blkt_inboard_surface: Any = None + expected_a_blkt_outboard_surface: Any = None + expected_a_blkt_total_surface: Any = None + + +@pytest.mark.parametrize( + "calculateellipticalblktareasparam", + ( + CalculateEllipticalBlktAreasParam( + rmajor=8, + rminor=2.6666666666666665, + triang=0.5, + r_shld_inboard_inner=4.0833333333333339, + dr_shld_inboard=0.30000000000000004, + dr_blkt_inboard=0.70000000000000007, + r_shld_outboard_outer=12.716666666666667, + dr_shld_outboard=0.80000000000000004, + dr_blkt_outboard=1, + dz_blkt_half=5.9532752487304119, + expected_a_blkt_inboard_surface=664.9687712975541, + expected_a_blkt_outboard_surface=1101.3666396424403, + expected_a_blkt_total_surface=1766.3354109399943, + ), + ), +) +def test_calculate_elliptical_blkt_areas( + calculateellipticalblktareasparam, blanket_library_fixture +): + """ + Regression Unit Test for calculate_elliptical_blkt_areas. + + This test was generated using data from tests/regression/input_files/large_tokamak_eval.IN.DAT. + + :param calculateellipticalblktareasparam: the data used in this test. + :type calculateellipticalblktareasparam: CalculateEllipticalBlktAreasParam + """ + ( + a_blkt_inboard_surface, + a_blkt_outboard_surface, + a_blkt_total_surface, + ) = blanket_library_fixture.calculate_elliptical_blkt_areas( + rmajor=calculateellipticalblktareasparam.rmajor, + rminor=calculateellipticalblktareasparam.rminor, + triang=calculateellipticalblktareasparam.triang, + r_shld_inboard_inner=calculateellipticalblktareasparam.r_shld_inboard_inner, + dr_shld_inboard=calculateellipticalblktareasparam.dr_shld_inboard, + dr_blkt_inboard=calculateellipticalblktareasparam.dr_blkt_inboard, + r_shld_outboard_outer=calculateellipticalblktareasparam.r_shld_outboard_outer, + dr_shld_outboard=calculateellipticalblktareasparam.dr_shld_outboard, + dr_blkt_outboard=calculateellipticalblktareasparam.dr_blkt_outboard, + dz_blkt_half=calculateellipticalblktareasparam.dz_blkt_half, + ) + + assert a_blkt_inboard_surface == pytest.approx( + calculateellipticalblktareasparam.expected_a_blkt_inboard_surface + ) + assert a_blkt_outboard_surface == pytest.approx( + calculateellipticalblktareasparam.expected_a_blkt_outboard_surface + ) + assert a_blkt_total_surface == pytest.approx( + calculateellipticalblktareasparam.expected_a_blkt_total_surface + ) + + +class CalculateEllipticalBlktVolumesParam(NamedTuple): + rmajor: Any = None + rminor: Any = None + triang: Any = None + r_shld_inboard_inner: Any = None + dr_shld_inboard: Any = None + dr_blkt_inboard: Any = None + r_shld_outboard_outer: Any = None + dr_shld_outboard: Any = None + dr_blkt_outboard: Any = None + dz_blkt_half: Any = None + dz_blkt_upper: Any = None + expected_vol_blkt_inboard: Any = None + expected_vol_blkt_outboard: Any = None + expected_vol_blkt_total: Any = None + + +@pytest.mark.parametrize( + "calculateellipticalblktvolumesparam", + ( + CalculateEllipticalBlktVolumesParam( + rmajor=8, + rminor=2.6666666666666665, + triang=0.5, + r_shld_inboard_inner=4.0833333333333339, + dr_shld_inboard=0.30000000000000004, + dr_blkt_inboard=0.70000000000000007, + r_shld_outboard_outer=12.716666666666667, + dr_shld_outboard=0.80000000000000004, + dr_blkt_outboard=1, + dz_blkt_half=5.9532752487304119, + dz_blkt_upper=0.85000000000000009, + expected_vol_blkt_inboard=315.83946385183026, + expected_vol_blkt_outboard=1020.3677420460117, + expected_vol_blkt_total=1336.207205897842, + ), + ), +) +def test_calculate_elliptical_blkt_volumes( + calculateellipticalblktvolumesparam, blanket_library_fixture +): + """ + Regression Unit Test for calculate_elliptical_blkt_volumes. + + This test was generated using data from tests/regression/input_files/large_tokamak_eval.IN.DAT. + + :param calculateellipticalblktvolumesparam: the data used in this test. + :type calculateellipticalblktvolumesparam: CalculateEllipticalBlktVolumesParam + """ + ( + vol_blkt_inboard, + vol_blkt_outboard, + vol_blkt_total, + ) = blanket_library_fixture.calculate_elliptical_blkt_volumes( + rmajor=calculateellipticalblktvolumesparam.rmajor, + rminor=calculateellipticalblktvolumesparam.rminor, + triang=calculateellipticalblktvolumesparam.triang, + r_shld_inboard_inner=calculateellipticalblktvolumesparam.r_shld_inboard_inner, + dr_shld_inboard=calculateellipticalblktvolumesparam.dr_shld_inboard, + dr_blkt_inboard=calculateellipticalblktvolumesparam.dr_blkt_inboard, + r_shld_outboard_outer=calculateellipticalblktvolumesparam.r_shld_outboard_outer, + dr_shld_outboard=calculateellipticalblktvolumesparam.dr_shld_outboard, + dr_blkt_outboard=calculateellipticalblktvolumesparam.dr_blkt_outboard, + dz_blkt_half=calculateellipticalblktvolumesparam.dz_blkt_half, + dz_blkt_upper=calculateellipticalblktvolumesparam.dz_blkt_upper, + ) + + assert vol_blkt_inboard == pytest.approx( + calculateellipticalblktvolumesparam.expected_vol_blkt_inboard + ) + assert vol_blkt_outboard == pytest.approx( + calculateellipticalblktvolumesparam.expected_vol_blkt_outboard + ) + assert vol_blkt_total == pytest.approx( + calculateellipticalblktvolumesparam.expected_vol_blkt_total + )