diff --git a/process/blanket_library.py b/process/blanket_library.py index fc16881d13..694c9211db 100644 --- a/process/blanket_library.py +++ b/process/blanket_library.py @@ -630,30 +630,6 @@ def set_blanket_module_geometry(self): fwbs_variables.n_blkt_inboard_modules_poloidal = 1 fwbs_variables.n_blkt_outboard_modules_poloidal = 1 - # Calculate mid-plane toroidal circumference and segment - # of inboard blanket - blanket_library.len_blkt_inboard_segment_toroidal = ( - 2.0e0 - * np.pi - * ( - physics_variables.rmajor - - physics_variables.rminor - - build_variables.dr_fw_plasma_gap_inboard - ) - ) / fwbs_variables.n_blkt_inboard_modules_toroidal - - # Calculate mid-plane toroidal circumference and segment - # of outboard blanke - blanket_library.len_blkt_outboard_segment_toroidal = ( - 2.0e0 - * np.pi - * ( - physics_variables.rmajor - + physics_variables.rminor - + build_variables.dr_fw_plasma_gap_outboard - ) - ) / fwbs_variables.n_blkt_outboard_modules_toroidal - # Calculate poloidal height of blanket modules self.blanket_module_poloidal_height() @@ -1921,7 +1897,6 @@ def thermo_hydraulic_model(self, output: bool): # load in pressures if primary pumping == 2 if fwbs_variables.i_p_coolant_pumping == 2: - self.set_blanket_module_geometry() deltap = self.thermo_hydraulic_model_pressure_drop_calculations( output=output ) @@ -2978,35 +2953,71 @@ def coolant_pumping_power( return pumppower -def set_pumping_powers_as_fractions(): - # User sets mechanical pumping power as a fraction of thermal power in component - - heat_transport_variables.p_fw_coolant_pump_mw = ( - heat_transport_variables.f_p_fw_coolant_pump_total_heat - * ( - fwbs_variables.p_fw_nuclear_heat_total_mw - + fwbs_variables.psurffwi - + fwbs_variables.psurffwo - ) +def set_pumping_powers_as_fractions( + f_p_fw_coolant_pump_total_heat: float, + f_p_blkt_coolant_pump_total_heat: float, + f_p_shld_coolant_pump_total_heat: float, + f_p_div_coolant_pump_total_heat: float, + p_fw_nuclear_heat_total_mw: float, + psurffwi: float, + psurffwo: float, + p_blkt_nuclear_heat_total_mw: float, + p_shld_nuclear_heat_mw: float, + p_cp_shield_nuclear_heat_mw: float, + p_plasma_separatrix_mw: float, + p_div_nuclear_heat_total_mw: float, + p_div_rad_total_mw: float, +) -> tuple[float, float, float, float]: + """ + Calculate mechanical pumping powers as fractions of thermal power in each component. + + :param f_p_fw_coolant_pump_total_heat: Fraction for FW coolant pump. + :type f_p_fw_coolant_pump_total_heat: float + :param f_p_blkt_coolant_pump_total_heat: Fraction for blanket coolant pump. + :type f_p_blkt_coolant_pump_total_heat: float + :param f_p_shld_coolant_pump_total_heat: Fraction for shield coolant pump. + :type f_p_shld_coolant_pump_total_heat: float + :param f_p_div_coolant_pump_total_heat: Fraction for divertor coolant pump. + :type f_p_div_coolant_pump_total_heat: float + :param p_fw_nuclear_heat_total_mw: Total FW nuclear heating (MW). + :type p_fw_nuclear_heat_total_mw: float + :param psurffwi: Inboard FW surface heating (MW). + :type psurffwi: float + :param psurffwo: Outboard FW surface heating (MW). + :type psurffwo: float + :param p_blkt_nuclear_heat_total_mw: Total blanket nuclear heating (MW). + :type p_blkt_nuclear_heat_total_mw: float + :param p_shld_nuclear_heat_mw: Shield nuclear heating (MW). + :type p_shld_nuclear_heat_mw: float + :param p_cp_shield_nuclear_heat_mw: CP shield nuclear heating (MW). + :type p_cp_shield_nuclear_heat_mw: float + :param p_plasma_separatrix_mw: Plasma separatrix power (MW). + :type p_plasma_separatrix_mw: float + :param p_div_nuclear_heat_total_mw: Divertor nuclear heating (MW). + :type p_div_nuclear_heat_total_mw: float + :param p_div_rad_total_mw: Divertor radiative power (MW). + :type p_div_rad_total_mw: float + + :return: Tuple of pumping powers (MW) for FW, blanket, shield, and divertor. + :rtype: tuple[float, float, float, float] + """ + p_fw_coolant_pump_mw = f_p_fw_coolant_pump_total_heat * ( + p_fw_nuclear_heat_total_mw + psurffwi + psurffwo ) - heat_transport_variables.p_blkt_coolant_pump_mw = ( - heat_transport_variables.f_p_blkt_coolant_pump_total_heat - * fwbs_variables.p_blkt_nuclear_heat_total_mw + p_blkt_coolant_pump_mw = ( + f_p_blkt_coolant_pump_total_heat * p_blkt_nuclear_heat_total_mw ) - heat_transport_variables.p_shld_coolant_pump_mw = ( - heat_transport_variables.f_p_shld_coolant_pump_total_heat - * ( - fwbs_variables.p_shld_nuclear_heat_mw - + fwbs_variables.p_cp_shield_nuclear_heat_mw - ) + p_shld_coolant_pump_mw = f_p_shld_coolant_pump_total_heat * ( + p_shld_nuclear_heat_mw + p_cp_shield_nuclear_heat_mw ) - heat_transport_variables.p_div_coolant_pump_mw = ( - heat_transport_variables.f_p_div_coolant_pump_total_heat - * ( - physics_variables.p_plasma_separatrix_mw - + fwbs_variables.p_div_nuclear_heat_total_mw - + fwbs_variables.p_div_rad_total_mw - ) + p_div_coolant_pump_mw = f_p_div_coolant_pump_total_heat * ( + p_plasma_separatrix_mw + p_div_nuclear_heat_total_mw + p_div_rad_total_mw + ) + return ( + p_fw_coolant_pump_mw, + p_blkt_coolant_pump_mw, + p_shld_coolant_pump_mw, + p_div_coolant_pump_mw, ) @@ -3177,3 +3188,79 @@ def dshellvol(rmajor, rminor, zminor, drin, drout, dz): vout = v2 - v1 return vin, vout, vin + vout + + +class OutboardBlanket(BlanketLibrary): + def calculate_basic_geometry(self): + self.component_volumes() + + dia_blkt_channel = self.pipe_hydraulic_diameter(i_channel_shape=1) + fwbs_variables.radius_blkt_channel = dia_blkt_channel / 2 + ( + fwbs_variables.radius_blkt_channel_90_bend, + fwbs_variables.radius_blkt_channel_180_bend, + ) = self.calculate_pipe_bend_radius(i_ps=1) + + def calculate_blanket_outboard_module_geometry( + self, + n_blkt_outboard_modules_toroidal: int, + rmajor: float, + rminor: float, + dr_fw_plasma_gap_outboard: float, + ) -> float: + """ + Calculate the mid-plane toroidal circumference and segment length of the outboard blanket. + + :param n_blkt_outboard_modules_toroidal: Number of outboard blanket modules in the toroidal direction. + :type n_blkt_outboard_modules_toroidal: int + :param rmajor: Major radius (m). + :type rmajor: float + :param rminor: Minor radius (m). + :type rminor: float + :param dr_fw_plasma_gap_outboard: Outboard first wall to plasma gap (m). + :type dr_fw_plasma_gap_outboard: float + :return: Length of outboard blanket segment in the toroidal direction (m). + :rtype: float + """ + return ( + 2.0 * np.pi * (rmajor + rminor + dr_fw_plasma_gap_outboard) + ) / n_blkt_outboard_modules_toroidal + + +class InboardBlanket(BlanketLibrary): + def calculate_basic_geometry(self): + self.component_volumes() + + dia_blkt_channel = self.pipe_hydraulic_diameter(i_channel_shape=1) + fwbs_variables.radius_blkt_channel = dia_blkt_channel / 2 + ( + fwbs_variables.radius_blkt_channel_90_bend, + fwbs_variables.radius_blkt_channel_180_bend, + ) = self.calculate_pipe_bend_radius(i_ps=1) + + self.set_blanket_module_geometry() + + def calculate_blanket_inboard_module_geometry( + self, + n_blkt_inboard_modules_toroidal: int, + rmajor: float, + rminor: float, + dr_fw_plasma_gap_inboard: float, + ) -> float: + """ + Calculate the mid-plane toroidal circumference and segment length of the inboard blanket. + + :param n_blkt_inboard_modules_toroidal: Number of inboard blanket modules in the toroidal direction. + :type n_blkt_inboard_modules_toroidal: int + :param rmajor: Major radius (m). + :type rmajor: float + :param rminor: Minor radius (m). + :type rminor: float + :param dr_fw_plasma_gap_inboard: Inboard first wall to plasma gap (m). + :type dr_fw_plasma_gap_inboard: float + :return: Length of inboard blanket segment in the toroidal direction (m). + :rtype: float + """ + return ( + 2.0 * np.pi * (rmajor + rminor + dr_fw_plasma_gap_inboard) + ) / n_blkt_inboard_modules_toroidal diff --git a/process/dcll.py b/process/dcll.py index 8f1198c5af..0d14496888 100644 --- a/process/dcll.py +++ b/process/dcll.py @@ -3,7 +3,7 @@ from process import ( process_output as po, ) -from process.blanket_library import BlanketLibrary +from process.blanket_library import InboardBlanket, OutboardBlanket from process.data_structure import ( build_variables, current_drive_variables, @@ -15,7 +15,7 @@ ) -class DCLL(BlanketLibrary): +class DCLL(InboardBlanket, OutboardBlanket): """This module contains the Dual Coolant Lead Lithium (DCLL) specific submods of PROCESSS. author: G. Graham, CCFE @@ -96,6 +96,21 @@ def run(self, output: bool): fwbs_variables.radius_blkt_channel_180_bend, ) = self.calculate_pipe_bend_radius(i_ps=1) + self.set_blanket_module_geometry() + + blanket_library.len_blkt_inboard_segment_toroidal = self.calculate_blanket_inboard_module_geometry( + n_blkt_inboard_modules_toroidal=fwbs_variables.n_blkt_inboard_modules_toroidal, + rmajor=physics_variables.rmajor, + rminor=physics_variables.rminor, + dr_fw_plasma_gap_inboard=build_variables.dr_fw_plasma_gap_inboard, + ) + blanket_library.len_blkt_outboard_segment_toroidal = self.calculate_blanket_outboard_module_geometry( + n_blkt_outboard_modules_toroidal=fwbs_variables.n_blkt_outboard_modules_toroidal, + rmajor=physics_variables.rmajor, + rminor=physics_variables.rminor, + dr_fw_plasma_gap_outboard=build_variables.dr_fw_plasma_gap_outboard, + ) + self.primary_coolant_properties(output=output) self.liquid_breeder_properties(output=output) self.dcll_neutronics_and_power(output=output) @@ -309,7 +324,26 @@ def dcll_power_and_heating(self, output: bool): if fwbs_variables.i_p_coolant_pumping == 1: # User sets mechanical pumping power directly - blanket_library.set_pumping_powers_as_fractions() + ( + heat_transport_variables.p_fw_coolant_pump_mw, + heat_transport_variables.p_blkt_coolant_pump_mw, + heat_transport_variables.p_shld_coolant_pump_mw, + heat_transport_variables.p_div_coolant_pump_mw, + ) = blanket_library.set_pumping_powers_as_fractions( + f_p_fw_coolant_pump_total_heat=heat_transport_variables.f_p_fw_coolant_pump_total_heat, + f_p_blkt_coolant_pump_total_heat=heat_transport_variables.f_p_blkt_coolant_pump_total_heat, + f_p_shld_coolant_pump_total_heat=heat_transport_variables.f_p_shld_coolant_pump_total_heat, + f_p_div_coolant_pump_total_heat=heat_transport_variables.f_p_div_coolant_pump_total_heat, + p_fw_nuclear_heat_total_mw=fwbs_variables.p_fw_nuclear_heat_total_mw, + psurffwi=fwbs_variables.psurffwi, + psurffwo=fwbs_variables.psurffwo, + p_blkt_nuclear_heat_total_mw=fwbs_variables.p_blkt_nuclear_heat_total_mw, + p_shld_nuclear_heat_mw=fwbs_variables.p_shld_nuclear_heat_mw, + p_cp_shield_nuclear_heat_mw=fwbs_variables.p_cp_shield_nuclear_heat_mw, + p_plasma_separatrix_mw=physics_variables.p_plasma_separatrix_mw, + p_div_nuclear_heat_total_mw=fwbs_variables.p_div_nuclear_heat_total_mw, + p_div_rad_total_mw=fwbs_variables.p_div_rad_total_mw, + ) elif fwbs_variables.i_p_coolant_pumping in [2, 3]: # Mechanical pumping power is calculated for first wall and blanket diff --git a/process/hcpb.py b/process/hcpb.py index 0bbbb515c3..94d5424853 100644 --- a/process/hcpb.py +++ b/process/hcpb.py @@ -8,7 +8,7 @@ from process import ( process_output as po, ) -from process.blanket_library import BlanketLibrary +from process.blanket_library import InboardBlanket, OutboardBlanket from process.coolprop_interface import FluidProperties from process.data_structure import ( build_variables, @@ -27,7 +27,7 @@ logger = logging.getLogger(__name__) -class CCFE_HCPB(BlanketLibrary): +class CCFE_HCPB(OutboardBlanket, InboardBlanket): """This module contains the PROCESS CCFE HCPB blanket model based on CCFE HCPB model from the PROCESS engineering paper PROCESS Engineering paper (M. Kovari et al.) @@ -53,6 +53,21 @@ def run(self, output: bool): fwbs_variables.radius_blkt_channel_180_bend, ) = self.calculate_pipe_bend_radius(i_ps=1) + self.set_blanket_module_geometry() + + blanket_library.len_blkt_inboard_segment_toroidal = self.calculate_blanket_inboard_module_geometry( + n_blkt_inboard_modules_toroidal=fwbs_variables.n_blkt_inboard_modules_toroidal, + rmajor=physics_variables.rmajor, + rminor=physics_variables.rminor, + dr_fw_plasma_gap_inboard=build_variables.dr_fw_plasma_gap_inboard, + ) + blanket_library.len_blkt_outboard_segment_toroidal = self.calculate_blanket_outboard_module_geometry( + n_blkt_outboard_modules_toroidal=fwbs_variables.n_blkt_outboard_modules_toroidal, + rmajor=physics_variables.rmajor, + rminor=physics_variables.rminor, + dr_fw_plasma_gap_outboard=build_variables.dr_fw_plasma_gap_outboard, + ) + # Centrepost neutronics if physics_variables.itart == 1: # CP radius at the point of maximum sield radius [m] @@ -813,7 +828,26 @@ def powerflow_calc(self, output: bool): if fwbs_variables.i_p_coolant_pumping == 1: # User sets mechanical pumping power directly - blanket_library.set_pumping_powers_as_fractions() + ( + heat_transport_variables.p_fw_coolant_pump_mw, + heat_transport_variables.p_blkt_coolant_pump_mw, + heat_transport_variables.p_shld_coolant_pump_mw, + heat_transport_variables.p_div_coolant_pump_mw, + ) = blanket_library.set_pumping_powers_as_fractions( + f_p_fw_coolant_pump_total_heat=heat_transport_variables.f_p_fw_coolant_pump_total_heat, + f_p_blkt_coolant_pump_total_heat=heat_transport_variables.f_p_blkt_coolant_pump_total_heat, + f_p_shld_coolant_pump_total_heat=heat_transport_variables.f_p_shld_coolant_pump_total_heat, + f_p_div_coolant_pump_total_heat=heat_transport_variables.f_p_div_coolant_pump_total_heat, + p_fw_nuclear_heat_total_mw=fwbs_variables.p_fw_nuclear_heat_total_mw, + psurffwi=fwbs_variables.psurffwi, + psurffwo=fwbs_variables.psurffwo, + p_blkt_nuclear_heat_total_mw=fwbs_variables.p_blkt_nuclear_heat_total_mw, + p_shld_nuclear_heat_mw=heat_transport_variables.p_shld_nuclear_heat_mw, + p_cp_shield_nuclear_heat_mw=fwbs_variables.p_cp_shield_nuclear_heat_mw, + p_plasma_separatrix_mw=physics_variables.p_plasma_separatrix_mw, + p_div_nuclear_heat_total_mw=fwbs_variables.p_div_nuclear_heat_total_mw, + p_div_rad_total_mw=fwbs_variables.p_div_rad_total_mw, + ) elif fwbs_variables.i_p_coolant_pumping == 2: # Calculate the required material properties of the FW and BB coolant.