From 0924bfadd6a49da1ee43d22ff73a43a3f322ca91 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Fri, 5 Dec 2025 10:42:56 +0000 Subject: [PATCH 1/7] Add VacuumVessel class and integrate into Caller model --- process/caller.py | 2 ++ process/main.py | 3 ++- process/vacuum.py | 58 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 1 deletion(-) diff --git a/process/caller.py b/process/caller.py index 0a93243a15..3f5b0a0eff 100644 --- a/process/caller.py +++ b/process/caller.py @@ -276,6 +276,8 @@ def _call_models_once(self, xc: np.ndarray) -> None: # First wall model self.models.fw.run() + self.models.vacuum_vessel.run() + # Blanket model """Blanket switch values No. | model diff --git a/process/main.py b/process/main.py index 367fe51a76..6a8ab9b678 100644 --- a/process/main.py +++ b/process/main.py @@ -105,7 +105,7 @@ from process.structure import Structure from process.superconducting_tf_coil import SuperconductingTFCoil from process.tf_coil import TFCoil -from process.vacuum import Vacuum +from process.vacuum import Vacuum, VacuumVessel from process.water_use import WaterUse os.environ["PYTHON_PROCESS_ROOT"] = os.path.join(os.path.dirname(__file__)) @@ -664,6 +664,7 @@ def __init__(self): self.availability = Availability() self.buildings = Buildings() self.vacuum = Vacuum() + self.vacuum_vessel = VacuumVessel() self.water_use = WaterUse() self.pulse = Pulse() self.ife = IFE(availability=self.availability, costs=self.costs) diff --git a/process/vacuum.py b/process/vacuum.py index d2afcb856e..4ab39a9f01 100644 --- a/process/vacuum.py +++ b/process/vacuum.py @@ -5,6 +5,7 @@ from process import constants from process import process_output as po +from process.data_structure import blanket_library as blanket_library from process.data_structure import build_variables as buv from process.data_structure import divertor_variables as dv from process.data_structure import physics_variables as pv @@ -684,3 +685,60 @@ def vacuum( ) return pumpn, nduct, dlscalc, mvdsh, dimax + + +class VacuumVessel: + """Class containing vacuum vessel routines""" + + def __init__(self) -> None: + pass + + def run(self) -> None: + blanket_library.dz_vv_half = self.calculate_vessel_half_height( + z_tf_inside_half=buv.z_tf_inside_half, + dz_shld_vv_gap=buv.dz_shld_vv_gap, + dz_vv_lower=buv.dz_vv_lower, + n_divertors=pv.n_divertors, + dz_blkt_upper=buv.dz_blkt_upper, + dz_shld_upper=buv.dz_shld_upper, + z_plasma_xpoint_upper=buv.z_plasma_xpoint_upper, + dr_fw_plasma_gap_inboard=buv.dr_fw_plasma_gap_inboard, + dr_fw_plasma_gap_outboard=buv.dr_fw_plasma_gap_outboard, + dr_fw_inboard=buv.dr_fw_inboard, + dr_fw_outboard=buv.dr_fw_outboard, + ) + + def calculate_vessel_half_height( + self, + z_tf_inside_half: float, + dz_shld_vv_gap: float, + dz_vv_lower: float, + n_divertors: int, + dz_blkt_upper: float, + dz_shld_upper: 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, + ) -> float: + """Calculate vacuum vessel internal half-height (m)""" + + z_bottom = z_tf_inside_half - dz_shld_vv_gap - dz_vv_lower + + # Calculate component internal upper half-height (m) + # If a double null machine then symmetric + if n_divertors == 2: + z_top = z_bottom + else: + z_top = z_plasma_xpoint_upper + 0.5 * ( + dr_fw_plasma_gap_inboard + + dr_fw_plasma_gap_outboard + + dr_fw_inboard + + dr_fw_outboard + + dz_blkt_upper + + dz_shld_upper + ) + + # Average of top and bottom (m) + return 0.5 * (z_top + z_bottom) From 2df8f4d42a18e8739671ebf1d506c409739edc8b Mon Sep 17 00:00:00 2001 From: mn3981 Date: Fri, 5 Dec 2025 11:01:36 +0000 Subject: [PATCH 2/7] Add calculate_dshaped_vessel_volumes method to VacuumVessel class --- process/vacuum.py | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/process/vacuum.py b/process/vacuum.py index 4ab39a9f01..f23eaff45f 100644 --- a/process/vacuum.py +++ b/process/vacuum.py @@ -5,9 +5,11 @@ from process import constants from process import process_output as po +from process.blanket_library import dshellvol from process.data_structure import blanket_library as blanket_library from process.data_structure import build_variables as buv from process.data_structure import divertor_variables as dv +from process.data_structure import fwbs_variables as fwbs_variables from process.data_structure import physics_variables as pv from process.data_structure import tfcoil_variables as tfv from process.data_structure import times_variables as tv @@ -708,6 +710,20 @@ def run(self) -> None: dr_fw_outboard=buv.dr_fw_outboard, ) + ( + blanket_library.vol_vv_inboard, + blanket_library.vol_vv_outboard, + fwbs_variables.vol_vv, + ) = self.calculate_dshaped_vessel_volumes( + rsldi=buv.rsldi, + rsldo=buv.rsldo, + dz_vv_half=blanket_library.dz_vv_half, + dr_vv_inboard=buv.dr_vv_inboard, + dr_vv_outboard=buv.dr_vv_outboard, + dz_vv_upper=buv.dz_vv_upper, + dz_vv_lower=buv.dz_vv_lower, + ) + def calculate_vessel_half_height( self, z_tf_inside_half: float, @@ -742,3 +758,33 @@ def calculate_vessel_half_height( # Average of top and bottom (m) return 0.5 * (z_top + z_bottom) + + def calculate_dshaped_vessel_volumes( + self, + rsldi: float, + rsldo: float, + dz_vv_half: float, + dr_vv_inboard: float, + dr_vv_outboard: float, + dz_vv_upper: float, + dz_vv_lower: float, + ) -> None: + """Calculate volumes of D-shaped vacuum vessel segments""" + + r_1 = rsldi + r_2 = rsldo - r_1 + + ( + vol_vv_inboard, + vol_vv_outboard, + vol_vv, + ) = dshellvol( + rmajor=r_1, + rminor=r_2, + zminor=dz_vv_half, + drin=dr_vv_inboard, + drout=dr_vv_outboard, + dz=(dz_vv_upper + dz_vv_lower) / 2, + ) + + return vol_vv_inboard, vol_vv_outboard, vol_vv From fc56ac324a756352e0d30e03f43257f44f6762a0 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Fri, 5 Dec 2025 11:14:48 +0000 Subject: [PATCH 3/7] Add calculate_elliptical_vessel_volumes method to VacuumVessel class --- process/vacuum.py | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/process/vacuum.py b/process/vacuum.py index f23eaff45f..0daa03d51b 100644 --- a/process/vacuum.py +++ b/process/vacuum.py @@ -5,7 +5,7 @@ from process import constants from process import process_output as po -from process.blanket_library import dshellvol +from process.blanket_library import dshellvol, eshellvol from process.data_structure import blanket_library as blanket_library from process.data_structure import build_variables as buv from process.data_structure import divertor_variables as dv @@ -768,7 +768,7 @@ def calculate_dshaped_vessel_volumes( dr_vv_outboard: float, dz_vv_upper: float, dz_vv_lower: float, - ) -> None: + ) -> tuple[float, float, float]: """Calculate volumes of D-shaped vacuum vessel segments""" r_1 = rsldi @@ -788,3 +788,40 @@ def calculate_dshaped_vessel_volumes( ) return vol_vv_inboard, vol_vv_outboard, vol_vv + + def calculate_elliptical_vessel_volumes( + self, + rmajor: float, + rminor: float, + triang: float, + rsldi: float, + rsldo: float, + dz_vv_half: float, + dr_vv_inboard: float, + dr_vv_outboard: float, + dz_vv_upper: float, + dz_vv_lower: float, + ) -> tuple[float, float, float]: + # Major radius to centre of inboard and outboard ellipses (m) + # (coincident in radius with top of plasma) + r_1 = rmajor - rminor * triang + + # Calculate distance between r1 and outer edge of inboard ... + # ... section (m) + r_2 = r_1 - rsldi + r_3 = rsldo - r_1 + + ( + vol_vv_inboard, + vol_vv_outboard, + vol_vv, + ) = eshellvol( + r_1, + r_2, + r_3, + dz_vv_half, + dr_vv_inboard, + dr_vv_outboard, + (dz_vv_upper + dz_vv_lower) / 2, + ) + return vol_vv_inboard, vol_vv_outboard, vol_vv From b6a7a8e135a7e07cf81b2f81718bb2fedc13c4d2 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Wed, 7 Jan 2026 15:00:24 +0000 Subject: [PATCH 4/7] :fire: Remove now redundant vacuum calcs from blanket library --- process/blanket_library.py | 51 ++------------------------------- process/caller.py | 4 +-- process/hcpb.py | 8 +++--- process/vacuum.py | 58 +++++++++++++++++++++++++++----------- 4 files changed, 51 insertions(+), 70 deletions(-) diff --git a/process/blanket_library.py b/process/blanket_library.py index cee5cef18d..8b4f4e2bdc 100644 --- a/process/blanket_library.py +++ b/process/blanket_library.py @@ -57,25 +57,17 @@ def component_volumes(self): blanket_library.dz_blkt_half = self.component_half_height(icomponent=0) # Shield blanket_library.dz_shld_half = self.component_half_height(icomponent=1) - # Vacuum Vessel - blanket_library.dz_vv_half = self.component_half_height(icomponent=2) # D-shaped blanket and shield if physics_variables.itart == 1 or fwbs_variables.i_fw_blkt_vv_shape == 1: - for icomponent in range(3): + for icomponent in range(2): self.dshaped_component(icomponent) # Elliptical blanket and shield else: - for icomponent in range(3): + for icomponent in range(2): self.elliptical_component(icomponent) - # This will fail the hts_REBCO and 2D_scan regression tests, - # the number of VMCON iterations (nviter) is different. - # Seems to be because in the blanket calculations (icomponent=0): - # r2 = 1.3836567143743970 rather than old value of r2 = 1.3836567143743972, - # r3 = 3.7009701431231936 rather than r3 = 3.7009701431231923. - # Apply coverage factors to volumes and surface areas self.apply_coverage_factors() @@ -109,7 +101,7 @@ def component_half_height(self, icomponent: int): - build_variables.dz_vv_lower ) else: - raise ProcessValueError(f"{icomponent=} is invalid, it must be either 0,1,2") + raise ProcessValueError(f"{icomponent=} is invalid, it must be either 0,1") # Calculate component internal upper half-height (m) # If a double null machine then symmetric @@ -126,11 +118,6 @@ def component_half_height(self, icomponent: int): # Shield if icomponent == 1: htop = htop + build_variables.dz_blkt_upper - # Vacuum Vessel - if icomponent == 2: - htop = ( - htop + build_variables.dz_blkt_upper + build_variables.dz_shld_upper - ) # Average of top and bottom (m) return 0.5 * (htop + hbot) @@ -209,19 +196,6 @@ def dshaped_component(self, icomponent: int): build_variables.dr_shld_outboard, build_variables.dz_shld_upper, ) - elif icomponent == 2: - ( - blanket_library.vol_vv_inboard, - blanket_library.vol_vv_outboard, - fwbs_variables.vol_vv, - ) = dshellvol( - r1, - r2, - blanket_library.dz_vv_half, - build_variables.dr_vv_inboard, - build_variables.dr_vv_outboard, - (build_variables.dz_vv_upper + build_variables.dz_vv_lower) / 2, - ) def elliptical_component(self, icomponent: int): """Calculate component surface area and volume using elliptical scheme @@ -299,20 +273,6 @@ def elliptical_component(self, icomponent: int): build_variables.dr_shld_outboard, build_variables.dz_shld_upper, ) - if icomponent == 2: - ( - blanket_library.vol_vv_inboard, - blanket_library.vol_vv_outboard, - fwbs_variables.vol_vv, - ) = eshellvol( - r1, - r2, - r3, - blanket_library.dz_vv_half, - build_variables.dr_vv_inboard, - build_variables.dr_vv_outboard, - (build_variables.dz_vv_upper + build_variables.dz_vv_lower) / 2, - ) def apply_coverage_factors(self): """Apply coverage factors to volumes @@ -383,11 +343,6 @@ def apply_coverage_factors(self): blanket_library.vol_shld_inboard + blanket_library.vol_shld_outboard ) - # Apply vacuum vessel coverage factor - # moved from dshaped_* and elliptical_* to keep coverage factor - # changes in the same location. - fwbs_variables.vol_vv = fwbs_variables.fvoldw * fwbs_variables.vol_vv - 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/caller.py b/process/caller.py index 3f5b0a0eff..8cd74fefc8 100644 --- a/process/caller.py +++ b/process/caller.py @@ -276,8 +276,6 @@ def _call_models_once(self, xc: np.ndarray) -> None: # First wall model self.models.fw.run() - self.models.vacuum_vessel.run() - # Blanket model """Blanket switch values No. | model @@ -298,6 +296,8 @@ def _call_models_once(self, xc: np.ndarray) -> None: # DCLL model self.models.dcll.run(output=False) + self.models.vacuum_vessel.run() + self.models.divertor.run(output=False) self.models.cryostat.run() diff --git a/process/hcpb.py b/process/hcpb.py index 288beb7a51..6b96e6cd6e 100644 --- a/process/hcpb.py +++ b/process/hcpb.py @@ -474,10 +474,10 @@ def nuclear_heating_magnets(self, output: bool): if build_variables.dr_vv_outboard > d_vv_all: d_vv_all = build_variables.dr_vv_outboard - if d_vv_all > 1.0e-6: - ccfe_hcpb_module.vv_density = fwbs_variables.m_vv / fwbs_variables.vol_vv - else: - ccfe_hcpb_module.vv_density = 0.0 + # if d_vv_all > 1.0e-6: + # ccfe_hcpb_module.vv_density = fwbs_variables.m_vv / fwbs_variables.vol_vv + # else: + # ccfe_hcpb_module.vv_density = 0.0 # Calculation of average blanket/shield thickness [m] if physics_variables.itart == 1: diff --git a/process/vacuum.py b/process/vacuum.py index 0daa03d51b..65c2601797 100644 --- a/process/vacuum.py +++ b/process/vacuum.py @@ -9,7 +9,9 @@ from process.data_structure import blanket_library as blanket_library from process.data_structure import build_variables as buv from process.data_structure import divertor_variables as dv +from process.data_structure import ccfe_hcpb_module as ccfe_hcpb_module from process.data_structure import fwbs_variables as fwbs_variables +from process.data_structure import physics_variables as physics_variables from process.data_structure import physics_variables as pv from process.data_structure import tfcoil_variables as tfv from process.data_structure import times_variables as tv @@ -709,20 +711,45 @@ def run(self) -> None: dr_fw_inboard=buv.dr_fw_inboard, dr_fw_outboard=buv.dr_fw_outboard, ) - - ( - blanket_library.vol_vv_inboard, - blanket_library.vol_vv_outboard, - fwbs_variables.vol_vv, - ) = self.calculate_dshaped_vessel_volumes( - rsldi=buv.rsldi, - rsldo=buv.rsldo, - dz_vv_half=blanket_library.dz_vv_half, - dr_vv_inboard=buv.dr_vv_inboard, - dr_vv_outboard=buv.dr_vv_outboard, - dz_vv_upper=buv.dz_vv_upper, - dz_vv_lower=buv.dz_vv_lower, - ) + # D-shaped blanket and shield + if physics_variables.itart == 1 or fwbs_variables.i_fw_blkt_vv_shape == 1: + ( + blanket_library.vol_vv_inboard, + blanket_library.vol_vv_outboard, + fwbs_variables.vol_vv, + ) = self.calculate_dshaped_vessel_volumes( + rsldi=buv.rsldi, + rsldo=buv.rsldo, + dz_vv_half=blanket_library.dz_vv_half, + dr_vv_inboard=buv.dr_vv_inboard, + dr_vv_outboard=buv.dr_vv_outboard, + dz_vv_upper=buv.dz_vv_upper, + dz_vv_lower=buv.dz_vv_lower, + ) + else: + ( + blanket_library.vol_vv_inboard, + blanket_library.vol_vv_outboard, + fwbs_variables.vol_vv, + ) = self.calculate_elliptical_vessel_volumes( + rmajor=pv.rmajor, + rminor=pv.rminor, + triang=pv.triang, + rsldi=buv.rsldi, + rsldo=buv.rsldo, + dz_vv_half=blanket_library.dz_vv_half, + dr_vv_inboard=buv.dr_vv_inboard, + dr_vv_outboard=buv.dr_vv_outboard, + dz_vv_upper=buv.dz_vv_upper, + dz_vv_lower=buv.dz_vv_lower, + ) + + # Apply vacuum vessel coverage factor + # moved from dshaped_* and elliptical_* to keep coverage factor + # changes in the same location. + fwbs_variables.vol_vv = fwbs_variables.fvoldw * fwbs_variables.vol_vv + + ccfe_hcpb_module.vv_density = fwbs_variables.m_vv / fwbs_variables.vol_vv def calculate_vessel_half_height( self, @@ -752,9 +779,8 @@ def calculate_vessel_half_height( + dr_fw_plasma_gap_outboard + dr_fw_inboard + dr_fw_outboard - + dz_blkt_upper - + dz_shld_upper ) + z_top = z_top + dz_blkt_upper + dz_shld_upper # Average of top and bottom (m) return 0.5 * (z_top + z_bottom) From d00a3690867195bec85ba906489830bf2ce87248 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Tue, 20 Jan 2026 11:14:45 +0000 Subject: [PATCH 5/7] Refactor BlanketLibrary: remove vacuum vessel calculations and update tests for elliptical vessel volumes --- process/blanket_library.py | 10 ---- tests/unit/test_blanket_library.py | 92 ------------------------------ tests/unit/test_vacuum.py | 80 +++++++++++++++++++++++++- 3 files changed, 79 insertions(+), 103 deletions(-) diff --git a/process/blanket_library.py b/process/blanket_library.py index 8b4f4e2bdc..73c973129e 100644 --- a/process/blanket_library.py +++ b/process/blanket_library.py @@ -93,13 +93,6 @@ def component_half_height(self, icomponent: int): + build_variables.dz_xpoint_divertor + divertor_variables.dz_divertor ) - # Vacuum vessel - elif icomponent == 2: - hbot = ( - build_variables.z_tf_inside_half - - build_variables.dz_shld_vv_gap - - build_variables.dz_vv_lower - ) else: raise ProcessValueError(f"{icomponent=} is invalid, it must be either 0,1") @@ -151,9 +144,6 @@ def dshaped_component(self, icomponent: int): # Sheild if icomponent == 1: r2 = build_variables.dr_blkt_inboard + r2 + build_variables.dr_blkt_outboard - # Vaccum Vessel - if icomponent == 2: - r2 = build_variables.rsldo - r1 # Calculate surface area, assuming 100% coverage if icomponent == 0: diff --git a/tests/unit/test_blanket_library.py b/tests/unit/test_blanket_library.py index 66b933b905..d9d143005a 100644 --- a/tests/unit/test_blanket_library.py +++ b/tests/unit/test_blanket_library.py @@ -1022,58 +1022,6 @@ class EllipticalComponentParam(NamedTuple): expected_vol_vv_outboard=0, expected_icomponent=1, ), - EllipticalComponentParam( - rsldi=4.0833333333333339, - dr_shld_inboard=0.30000000000000004, - dr_blkt_inboard=0.70000000000000007, - rsldo=12.716666666666667, - dr_shld_outboard=0.80000000000000004, - dr_blkt_outboard=1, - a_blkt_inboard_surface=664.9687712975541, - a_blkt_outboard_surface=1101.3666396424403, - a_blkt_total_surface=1766.3354109399943, - dz_blkt_upper=0.85000000000000009, - a_shld_inboard_surface=700.06731267447844, - a_shld_outboard_surface=1344.1106481995357, - a_shld_total_surface=2044.1779608740142, - 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=315.83946385183026, - vol_blkt_outboard=1020.3677420460117, - vol_blkt_total=1336.207205897842, - vol_shld_total=1124.4621612595051, - vol_vv=0, - rmajor=8, - rminor=2.6666666666666665, - triang=0.5, - vol_shld_inboard=177.89822933168091, - vol_shld_outboard=946.56393192782434, - vol_vv_inboard=0, - vol_vv_outboard=0, - dz_blkt_half=5.9532752487304119, - dz_shld_half=6.8032752487304133, - dz_vv_half=7.5032752487304135, - icomponent=2, - 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=700.06731267447844, - expected_a_shld_outboard_surface=1344.1106481995357, - expected_a_shld_total_surface=2044.1779608740142, - expected_vol_blkt_inboard=315.83946385183026, - expected_vol_blkt_outboard=1020.3677420460117, - expected_volblkt=1336.207205897842, - expected_vol_shld_total=1124.4621612595051, - expected_vol_vv=584.07334775041659, - expected_vol_shld_inboard=177.89822933168091, - expected_vol_shld_outboard=946.56393192782434, - expected_vol_vv_inboard=143.03162449152501, - expected_vol_vv_outboard=441.04172325889158, - expected_icomponent=2, - ), ), ) def test_elliptical_component( @@ -1140,18 +1088,6 @@ def test_elliptical_component( monkeypatch.setattr( build_variables, "dz_shld_upper", ellipticalcomponentparam.dz_shld_upper ) - monkeypatch.setattr( - build_variables, "dr_vv_inboard", ellipticalcomponentparam.dr_vv_inboard - ) - monkeypatch.setattr( - build_variables, "dr_vv_outboard", ellipticalcomponentparam.dr_vv_outboard - ) - monkeypatch.setattr( - build_variables, "dz_vv_upper", ellipticalcomponentparam.dz_vv_upper - ) - monkeypatch.setattr( - build_variables, "dz_vv_lower", ellipticalcomponentparam.dz_vv_lower - ) monkeypatch.setattr( fwbs_variables, "vol_blkt_inboard", ellipticalcomponentparam.vol_blkt_inboard ) @@ -1164,7 +1100,6 @@ def test_elliptical_component( monkeypatch.setattr( fwbs_variables, "vol_shld_total", ellipticalcomponentparam.vol_shld_total ) - monkeypatch.setattr(fwbs_variables, "vol_vv", ellipticalcomponentparam.vol_vv) monkeypatch.setattr(physics_variables, "rmajor", ellipticalcomponentparam.rmajor) monkeypatch.setattr(physics_variables, "rminor", ellipticalcomponentparam.rminor) monkeypatch.setattr(physics_variables, "triang", ellipticalcomponentparam.triang) @@ -1174,21 +1109,12 @@ def test_elliptical_component( monkeypatch.setattr( blanket_library, "vol_shld_outboard", ellipticalcomponentparam.vol_shld_outboard ) - monkeypatch.setattr( - blanket_library, "vol_vv_inboard", ellipticalcomponentparam.vol_vv_inboard - ) - monkeypatch.setattr( - blanket_library, "vol_vv_outboard", ellipticalcomponentparam.vol_vv_outboard - ) monkeypatch.setattr( blanket_library, "dz_blkt_half", ellipticalcomponentparam.dz_blkt_half ) monkeypatch.setattr( blanket_library, "dz_shld_half", ellipticalcomponentparam.dz_shld_half ) - monkeypatch.setattr( - blanket_library, "dz_vv_half", ellipticalcomponentparam.dz_vv_half - ) blanket_library_fixture.elliptical_component(ellipticalcomponentparam.icomponent) @@ -1222,21 +1148,12 @@ def test_elliptical_component( assert fwbs_variables.vol_shld_total == pytest.approx( ellipticalcomponentparam.expected_vol_shld_total ) - assert fwbs_variables.vol_vv == pytest.approx( - ellipticalcomponentparam.expected_vol_vv - ) 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 ) - assert blanket_library.vol_vv_inboard == pytest.approx( - ellipticalcomponentparam.expected_vol_vv_inboard - ) - assert blanket_library.vol_vv_outboard == pytest.approx( - ellipticalcomponentparam.expected_vol_vv_outboard - ) class ApplyCoverageFactorsParam(NamedTuple): @@ -1254,8 +1171,6 @@ class ApplyCoverageFactorsParam(NamedTuple): fvolsi: Any = None fvolso: Any = None vol_shld_total: Any = None - vol_vv: Any = None - fvoldw: Any = None n_divertors: Any = None vol_shld_inboard: Any = None vol_shld_outboard: Any = None @@ -1288,8 +1203,6 @@ class ApplyCoverageFactorsParam(NamedTuple): fvolsi=1, fvolso=0.64000000000000001, vol_shld_total=1124.4621612595051, - vol_vv=584.07334775041659, - fvoldw=1.74, n_divertors=1, vol_shld_inboard=177.89822933168091, vol_shld_outboard=946.56393192782434, @@ -1371,8 +1284,6 @@ def test_apply_coverage_factors( monkeypatch.setattr( fwbs_variables, "vol_shld_total", applycoveragefactorsparam.vol_shld_total ) - monkeypatch.setattr(fwbs_variables, "vol_vv", applycoveragefactorsparam.vol_vv) - monkeypatch.setattr(fwbs_variables, "fvoldw", applycoveragefactorsparam.fvoldw) monkeypatch.setattr( divertor_variables, "n_divertors", applycoveragefactorsparam.n_divertors ) @@ -1408,9 +1319,6 @@ def test_apply_coverage_factors( assert fwbs_variables.vol_shld_total == pytest.approx( applycoveragefactorsparam.expected_vol_shld_total ) - assert fwbs_variables.vol_vv == pytest.approx( - applycoveragefactorsparam.expected_vol_vv - ) assert blanket_library.vol_shld_outboard == pytest.approx( applycoveragefactorsparam.expected_vol_shld_outboard ) diff --git a/tests/unit/test_vacuum.py b/tests/unit/test_vacuum.py index 7479f5cafd..b517d14cf5 100644 --- a/tests/unit/test_vacuum.py +++ b/tests/unit/test_vacuum.py @@ -1,10 +1,12 @@ +from typing import Any, NamedTuple + import pytest from process.data_structure import physics_variables as pv from process.data_structure import tfcoil_variables as tfv from process.data_structure import times_variables as tv from process.data_structure import vacuum_variables as vacv -from process.vacuum import Vacuum +from process.vacuum import Vacuum, VacuumVessel @pytest.fixture @@ -17,6 +19,16 @@ def vacuum(): return Vacuum() +@pytest.fixture +def vacuum_vessel(): + """Provides Vacuum object for testing. + + :return vacuum: initialised Vacuum object + :type vacuum: process.vacuum.Vacuum + """ + return VacuumVessel() + + class TestVacuum: def test_simple_model(self, monkeypatch, vacuum): """Tests `vacuum_simple` subroutine. @@ -109,3 +121,69 @@ def test_old_model(self, monkeypatch, vacuum): assert dlscalc == pytest.approx(2.798765707267961) assert mvdsh == 0.0 assert dimax == pytest.approx(0.42414752916950604) + + +class EllipticalVesselVolumes(NamedTuple): + rmajor: Any = None + rminor: Any = None + triang: Any = None + rsldi: Any = None + rsldo: Any = None + dz_vv_half: Any = None + dr_vv_inboard: Any = None + dr_vv_outboard: Any = None + dz_vv_upper: Any = None + dz_vv_lower: Any = None + + +@pytest.mark.parametrize( + "elliptical_vessel_volumes, expected", + [ + ( + EllipticalVesselVolumes( + rmajor=8, + rminor=2.6666666666666665, + triang=0.5, + rsldi=4.083333333333334, + rsldo=12.716666666666667, + dz_vv_half=7.5032752487304135, + dr_vv_inboard=0.30000000000000004, + dr_vv_outboard=0.30000000000000004, + dz_vv_upper=0.30000000000000004, + dz_vv_lower=0.30000000000000004, + ), + ( + pytest.approx(143.03162449152501), + pytest.approx(441.04172325889158), + pytest.approx(584.07334775041659), + ), + ) + ], +) +def test_elliptical_vessel_volumes(vacuum_vessel, elliptical_vessel_volumes, expected): + """Tests `elliptical_vessel_volumes` function. + + :param elliptical_vessel_volumes: input parameters for the function + :type elliptical_vessel_volumes: EllipticalVesselVolumes + + + """ + + vol_vv_inboard, vol_vv_outboard, vol_vv = ( + vacuum_vessel.calculate_elliptical_vessel_volumes( + rmajor=elliptical_vessel_volumes.rmajor, + rminor=elliptical_vessel_volumes.rminor, + triang=elliptical_vessel_volumes.triang, + rsldi=elliptical_vessel_volumes.rsldi, + rsldo=elliptical_vessel_volumes.rsldo, + dz_vv_half=elliptical_vessel_volumes.dz_vv_half, + dr_vv_inboard=elliptical_vessel_volumes.dr_vv_inboard, + dr_vv_outboard=elliptical_vessel_volumes.dr_vv_outboard, + dz_vv_upper=elliptical_vessel_volumes.dz_vv_upper, + dz_vv_lower=elliptical_vessel_volumes.dz_vv_lower, + ) + ) + + assert vol_vv_inboard == expected[0] + assert vol_vv_outboard == expected[1] + assert vol_vv == expected[2] From e562fa89fd7a8153984cf8e94918f8e3ee3ef14b Mon Sep 17 00:00:00 2001 From: mn3981 Date: Tue, 20 Jan 2026 11:42:01 +0000 Subject: [PATCH 6/7] Add tests for DShaped vessel volume calculations in vacuum module --- process/hcpb.py | 5 --- process/vacuum.py | 3 +- tests/unit/test_blanket_library.py | 55 +---------------------------- tests/unit/test_vacuum.py | 56 ++++++++++++++++++++++++++++++ 4 files changed, 59 insertions(+), 60 deletions(-) diff --git a/process/hcpb.py b/process/hcpb.py index 6b96e6cd6e..a238e1405f 100644 --- a/process/hcpb.py +++ b/process/hcpb.py @@ -474,11 +474,6 @@ def nuclear_heating_magnets(self, output: bool): if build_variables.dr_vv_outboard > d_vv_all: d_vv_all = build_variables.dr_vv_outboard - # if d_vv_all > 1.0e-6: - # ccfe_hcpb_module.vv_density = fwbs_variables.m_vv / fwbs_variables.vol_vv - # else: - # ccfe_hcpb_module.vv_density = 0.0 - # Calculation of average blanket/shield thickness [m] if physics_variables.itart == 1: # There is no inner blanket for TART design [m] diff --git a/process/vacuum.py b/process/vacuum.py index 65c2601797..0a8320f31d 100644 --- a/process/vacuum.py +++ b/process/vacuum.py @@ -780,7 +780,8 @@ def calculate_vessel_half_height( + dr_fw_inboard + dr_fw_outboard ) - z_top = z_top + dz_blkt_upper + dz_shld_upper + + z_top = z_top + dz_blkt_upper + dz_shld_upper # Average of top and bottom (m) return 0.5 * (z_top + z_bottom) diff --git a/tests/unit/test_blanket_library.py b/tests/unit/test_blanket_library.py index d9d143005a..93fc0a4982 100644 --- a/tests/unit/test_blanket_library.py +++ b/tests/unit/test_blanket_library.py @@ -647,7 +647,7 @@ class DshapedComponentParam(NamedTuple): dz_blkt_half=8.25, dz_shld_half=8.75, dz_vv_half=9.4349999999999987, - icomponent=0, + icomponent=1, expected_a_blkt_inboard_surface=196.97785938008002, expected_a_blkt_outboard_surface=852.24160940262459, expected_a_blkt_total_surface=1049.2194687827046, @@ -664,59 +664,6 @@ class DshapedComponentParam(NamedTuple): expected_vol_vv_outboard=0, expected_icomponent=1, ), - DshapedComponentParam( - rsldi=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=196.97785938008002, - a_blkt_outboard_surface=852.24160940262459, - a_blkt_total_surface=1049.2194687827046, - dr_blkt_outboard=1, - dz_blkt_upper=0.5, - a_shld_inboard_surface=208.91591146372122, - a_shld_outboard_surface=1013.8483589087293, - a_shld_total_surface=1222.7642703724505, - dr_shld_outboard=0.30000000000000004, - dz_shld_upper=0.60000000000000009, - rsldo=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=691.06561956756764, - vol_blkt_total=691.06561956756764, - vol_shld_total=450.46122947809488, - vol_vv=0, - rminor=2.5, - vol_shld_inboard=79.896984366095609, - vol_shld_outboard=370.5642451119993, - vol_vv_inboard=0, - vol_vv_outboard=0, - dz_blkt_half=8.25, - dz_shld_half=8.75, - dz_vv_half=9.4349999999999987, - icomponent=1, - 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=208.91591146372122, - expected_a_shld_outboard_surface=1013.8483589087293, - expected_a_shld_total_surface=1222.7642703724505, - expected_vol_blkt_outboard=691.06561956756764, - expected_volblkt=691.06561956756764, - expected_vol_shld_total=450.46122947809488, - expected_vol_vv=340.45369594344834, - expected_vol_shld_inboard=79.896984366095609, - expected_vol_shld_outboard=370.5642451119993, - expected_vol_vv_inboard=34.253413020620215, - expected_vol_vv_outboard=306.20028292282814, - expected_icomponent=2, - ), ), ) def test_dshaped_component(dshapedcomponentparam, monkeypatch, blanket_library_fixture): diff --git a/tests/unit/test_vacuum.py b/tests/unit/test_vacuum.py index b517d14cf5..d0c7bef2ca 100644 --- a/tests/unit/test_vacuum.py +++ b/tests/unit/test_vacuum.py @@ -187,3 +187,59 @@ def test_elliptical_vessel_volumes(vacuum_vessel, elliptical_vessel_volumes, exp assert vol_vv_inboard == expected[0] assert vol_vv_outboard == expected[1] assert vol_vv == expected[2] + + +class DShapedVesselVolumes(NamedTuple): + rsldi: Any = None + rsldo: Any = None + dz_vv_half: Any = None + dr_vv_inboard: Any = None + dr_vv_outboard: Any = None + dz_vv_upper: Any = None + dz_vv_lower: Any = None + + +@pytest.mark.parametrize( + "dshaped_vessel_volumes, expected", + [ + ( + DShapedVesselVolumes( + rsldi=1.5, + rsldo=8.4000000000000004, + dz_vv_half=9.4349999999999987, + dr_vv_inboard=0.20000000000000001, + dr_vv_outboard=0.30000000000000004, + dz_vv_upper=0.30000000000000004, + dz_vv_lower=0.30000000000000004, + ), + ( + pytest.approx(34.253413020620215), + pytest.approx(306.20028292282814), + pytest.approx(340.45369594344834), + ), + ) + ], +) +def test_dshaped_vessel_volumes(vacuum_vessel, dshaped_vessel_volumes, expected): + """Tests `dshaped_vessel_volumes` function. + + :param dshaped_vessel_volumes: input parameters for the function + :type dshaped_vessel_volumes: DShapedVesselVolumes + + """ + + vol_vv_inboard, vol_vv_outboard, vol_vv = ( + vacuum_vessel.calculate_dshaped_vessel_volumes( + rsldi=dshaped_vessel_volumes.rsldi, + rsldo=dshaped_vessel_volumes.rsldo, + dz_vv_half=dshaped_vessel_volumes.dz_vv_half, + dr_vv_inboard=dshaped_vessel_volumes.dr_vv_inboard, + dr_vv_outboard=dshaped_vessel_volumes.dr_vv_outboard, + dz_vv_upper=dshaped_vessel_volumes.dz_vv_upper, + dz_vv_lower=dshaped_vessel_volumes.dz_vv_lower, + ) + ) + + assert vol_vv_inboard == expected[0] + assert vol_vv_outboard == expected[1] + assert vol_vv == expected[2] From b7ec94ade3097913f7c7ac32964a367d1c252fb4 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Tue, 27 Jan 2026 10:16:36 +0000 Subject: [PATCH 7/7] Post rebase changes --- process/vacuum.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/process/vacuum.py b/process/vacuum.py index 0a8320f31d..9899b33898 100644 --- a/process/vacuum.py +++ b/process/vacuum.py @@ -8,8 +8,8 @@ from process.blanket_library import dshellvol, eshellvol from process.data_structure import blanket_library as blanket_library from process.data_structure import build_variables as buv -from process.data_structure import divertor_variables as dv from process.data_structure import ccfe_hcpb_module as ccfe_hcpb_module +from process.data_structure import divertor_variables as dv from process.data_structure import fwbs_variables as fwbs_variables from process.data_structure import physics_variables as physics_variables from process.data_structure import physics_variables as pv @@ -702,7 +702,7 @@ def run(self) -> None: z_tf_inside_half=buv.z_tf_inside_half, dz_shld_vv_gap=buv.dz_shld_vv_gap, dz_vv_lower=buv.dz_vv_lower, - n_divertors=pv.n_divertors, + n_divertors=dv.n_divertors, dz_blkt_upper=buv.dz_blkt_upper, dz_shld_upper=buv.dz_shld_upper, z_plasma_xpoint_upper=buv.z_plasma_xpoint_upper,