From 1260a720168c3fa37f0366dfc0cdb338ffa6bac3 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Thu, 12 Feb 2026 15:47:08 +0000 Subject: [PATCH 01/15] Add PlasmaExhaust class and integrate into Physics model --- process/main.py | 2 + process/models/physics/physics.py | 66 ++++++++++++++++++++++++++++--- 2 files changed, 62 insertions(+), 6 deletions(-) diff --git a/process/main.py b/process/main.py index 7388e750c..ae9e7b106 100644 --- a/process/main.py +++ b/process/main.py @@ -700,12 +700,14 @@ def __init__(self): self.plasma_beta = PlasmaBeta() self.plasma_inductance = PlasmaInductance() self.plasma_density_limit = PlasmaDensityLimit() + self.plasma_exhaust = PlasmaExhaust() self.physics = Physics( plasma_profile=self.plasma_profile, current_drive=self.current_drive, plasma_beta=self.plasma_beta, plasma_inductance=self.plasma_inductance, plasma_density_limit=self.plasma_density_limit, + plasma_exhaust=self.plasma_exhaust, ) self.physics_detailed = DetailedPhysics( plasma_profile=self.plasma_profile, diff --git a/process/models/physics/physics.py b/process/models/physics/physics.py index 02e925af3..8694a5efd 100644 --- a/process/models/physics/physics.py +++ b/process/models/physics/physics.py @@ -1626,12 +1626,19 @@ def _trapped_particle_fraction_sauter( class Physics: def __init__( + self, + plasma_profile, + current_drive, + plasma_beta, + plasma_inductance, plasma_density_limit, + , + plasma_exhaust, ): self.outfile = constants.NOUT self.mfile = constants.MFILE @@ -1640,6 +1647,7 @@ def __init__( self.beta = plasma_beta self.inductance = plasma_inductance self.density_limit = plasma_density_limit + self.exhaust = plasma_exhaust def physics(self): """Routine to calculate tokamak plasma physics information @@ -2377,12 +2385,14 @@ def physics(self): ) physics_variables.p_plasma_separatrix_mw = ( - physics_variables.f_p_alpha_plasma_deposited - * physics_variables.p_alpha_total_mw - + physics_variables.p_non_alpha_charged_mw - + pinj - + physics_variables.p_plasma_ohmic_mw - - physics_variables.p_plasma_rad_mw + self.exhaust.calculate_separatrix_power( + f_p_alpha_plasma_deposited=physics_variables.f_p_alpha_plasma_deposited, + p_alpha_total_mw=physics_variables.p_alpha_total_mw, + p_non_alpha_charged_mw=physics_variables.p_non_alpha_charged_mw, + p_hcd_injected_total_mw=pinj, + p_plasma_ohmic_mw=physics_variables.p_plasma_ohmic_mw, + p_plasma_rad_mw=physics_variables.p_plasma_rad_mw, + ) ) physics_variables.pflux_plasma_surface_neutron_avg_mw = ( @@ -9465,6 +9475,50 @@ def output_volt_second_information(self): po.oblnkl(self.outfile) +class PlasmaExhaust: + """Class to hold plasma exhaust calculations for plasma processing.""" + + def __init__(self): + self.outfile = constants.NOUT + self.mfile = constants.MFILE + + @staticmethod + def calculate_separatrix_power( + f_p_alpha_plasma_deposited: float, + p_alpha_total_mw: float, + p_non_alpha_charged_mw: float, + p_hcd_injected_total_mw: float, + p_plasma_ohmic_mw: float, + p_plasma_rad_mw: float, + ) -> float: + """ + Calculate the power crossing the separatrix (P_sep). + + :param f_p_alpha_plasma_deposited: Fraction of alpha power deposited in plasma. + :type f_p_alpha_plasma_deposited: float + :param p_alpha_total_mw: Total alpha power produced (MW). + :type p_alpha_total_mw: float + :param p_non_alpha_charged_mw: Power from non-alpha charged particles (MW). + :type p_non_alpha_charged_mw: float + :param p_hcd_injected_total_mw: Total power injected by heating and current drive (MW). + :type p_hcd_injected_total_mw: float + :param p_plasma_ohmic_mw: Ohmic heating power (MW). + :type p_plasma_ohmic_mw: float + :param p_plasma_rad_mw: Radiated power from plasma (MW). + :type p_plasma_rad_mw: float + :return: Power crossing the separatrix (MW). + :rtype: float + """ + + return ( + f_p_alpha_plasma_deposited * p_alpha_total_mw + + p_non_alpha_charged_mw + + p_hcd_injected_total_mw + + p_plasma_ohmic_mw + - p_plasma_rad_mw + ) + + class DetailedPhysics: """Class to hold detailed physics models for plasma processing.""" From ec0bc045f1e9c32a7d1461c1ee7d389affbcdaee Mon Sep 17 00:00:00 2001 From: mn3981 Date: Thu, 12 Feb 2026 16:02:28 +0000 Subject: [PATCH 02/15] Add p_plasma_separatrix_rmajor_mw variable to track power per major radius --- process/data_structure/physics_variables.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/process/data_structure/physics_variables.py b/process/data_structure/physics_variables.py index 6ff494442..c48d63e4f 100644 --- a/process/data_structure/physics_variables.py +++ b/process/data_structure/physics_variables.py @@ -911,6 +911,9 @@ p_plasma_separatrix_mw: float = None """power to conducted to the divertor region (MW)""" +p_plasma_separatrix_rmajor_mw: float = None +"""Power to conducted to the divertor region per major radius (MW/m)""" + p_div_lower_separatrix_mw: float = None """Separatrix power conducted to the lower divertor region (calculated if `i_single_null = 0`) (MW)""" @@ -1567,6 +1570,7 @@ def init_physics_variables(): p_dd_total_mw, \ p_dhe3_total_mw, \ p_plasma_separatrix_mw, \ + p_plasma_separatrix_rmajor_mw, \ p_div_lower_separatrix_mw, \ p_div_upper_separatrix_mw, \ p_div_separatrix_max_mw, \ @@ -1838,6 +1842,7 @@ def init_physics_variables(): p_dd_total_mw = 0.0 p_dhe3_total_mw = 0.0 p_plasma_separatrix_mw = 0.0 + p_plasma_separatrix_rmajor_mw = 0.0 p_div_lower_separatrix_mw = 0.0 p_div_upper_separatrix_mw = 0.0 p_div_separatrix_max_mw = 0.0 From dad22994c1af28f9da84a51ba02539364e179704 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Thu, 12 Feb 2026 16:05:36 +0000 Subject: [PATCH 03/15] Add method to calculate power crossing the separatrix per unit major radius in PlasmaExhaust class --- process/models/physics/physics.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/process/models/physics/physics.py b/process/models/physics/physics.py index 8694a5efd..2ae6eb02f 100644 --- a/process/models/physics/physics.py +++ b/process/models/physics/physics.py @@ -9518,6 +9518,23 @@ def calculate_separatrix_power( - p_plasma_rad_mw ) + @staticmethod + def calculate_psep_over_r_metric( + p_plasma_separatrix_mw: float, rmajor: float + ) -> float: + """ + Calculate the power crossing the separatrix per unit major radius (P_sep/R). + + :param p_plasma_separatrix_mw: Power crossing the separatrix (MW). + :type p_plasma_separatrix_mw: float + :param rmajor: Plasma major radius (m). + :type rmajor: float + :return: Power crossing the separatrix per unit major radius (MW/m). + :rtype: float + + """ + return p_plasma_separatrix_mw / rmajor + class DetailedPhysics: """Class to hold detailed physics models for plasma processing.""" From f3f6794058a820111b06b341d358b6c9c83d58fe Mon Sep 17 00:00:00 2001 From: mn3981 Date: Thu, 12 Feb 2026 16:22:20 +0000 Subject: [PATCH 04/15] Add method to calculate EU DEMO divertor protection re-attachment metric in PlasmaExhaust class --- process/models/physics/physics.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/process/models/physics/physics.py b/process/models/physics/physics.py index 2ae6eb02f..2828f3f68 100644 --- a/process/models/physics/physics.py +++ b/process/models/physics/physics.py @@ -9535,6 +9535,35 @@ def calculate_psep_over_r_metric( """ return p_plasma_separatrix_mw / rmajor + @staticmethod + def calculate_eu_demo_re_attachment_metric( + p_plasma_separatrix_mw: float, + b_plasma_toroidal_on_axis: float, + q95: float, + aspect: float, + rmajor: float, + ) -> float: + """Calculate the EU DEMO divertor protection re-attachment metric for plasma exhaust. + + :param p_plasma_separatrix_mw: Power crossing the separatrix (MW). + :type p_plasma_separatrix_mw: float + :param b_plasma_toroidal_on_axis: Toroidal magnetic field on axis (T). + :type b_plasma_toroidal_on_axis: float + :param q95: Safety factor at 95% flux surface. + :type q95: float + :param aspect: Aspect ratio of the plasma. + :type aspect: float + :param rmajor: Plasma major radius (m). + :type rmajor: float + :return: EU DEMO re-attachment metric (MW T /m). + :rtype: float + + """ + + return (p_plasma_separatrix_mw * b_plasma_toroidal_on_axis) / ( + q95 * aspect * rmajor + ) + class DetailedPhysics: """Class to hold detailed physics models for plasma processing.""" From 3c550045963bfdfa1ccb06f793c508a40f6f8e6f Mon Sep 17 00:00:00 2001 From: mn3981 Date: Mon, 23 Feb 2026 21:14:18 +0000 Subject: [PATCH 05/15] post rebase structure update --- process/main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/process/main.py b/process/main.py index ae9e7b106..1f4a9401b 100644 --- a/process/main.py +++ b/process/main.py @@ -98,6 +98,7 @@ DetailedPhysics, Physics, PlasmaBeta, + PlasmaExhaust, PlasmaInductance, ) from process.models.physics.plasma_geometry import PlasmaGeom From a26fbd7213ce87e7b77897b42d278da9064e808b Mon Sep 17 00:00:00 2001 From: mn3981 Date: Thu, 26 Feb 2026 13:47:55 +0000 Subject: [PATCH 06/15] Post rebase integration fixes --- tests/unit/test_physics.py | 2 ++ tests/unit/test_stellarator.py | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/tests/unit/test_physics.py b/tests/unit/test_physics.py index 72be4b201..7a3933fe8 100644 --- a/tests/unit/test_physics.py +++ b/tests/unit/test_physics.py @@ -25,6 +25,7 @@ DetailedPhysics, Physics, PlasmaBeta, + PlasmaExhaust, PlasmaInductance, calculate_current_coefficient_hastie, calculate_plasma_current_peng, @@ -58,6 +59,7 @@ def physics(): PlasmaBeta(), PlasmaInductance(), PlasmaDensityLimit(), + PlasmaExhaust(), ) diff --git a/tests/unit/test_stellarator.py b/tests/unit/test_stellarator.py index 3809b0fa8..dfc71de88 100644 --- a/tests/unit/test_stellarator.py +++ b/tests/unit/test_stellarator.py @@ -31,9 +31,14 @@ ) from process.models.physics.density_limit import PlasmaDensityLimit from process.models.physics.physics import ( + ( Physics, + PlasmaBeta, + + PlasmaExhaust, PlasmaInductance, +), ) from process.models.physics.plasma_profiles import PlasmaProfile from process.models.power import Power @@ -88,6 +93,7 @@ def stellarator(): PlasmaBeta(), PlasmaInductance(), PlasmaDensityLimit(), + PlasmaExhaust(), ), Neoclassics(), plasma_beta=PlasmaBeta(), From 6ea7530c63a3b733716b16b9eb485e28ed25a6b4 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Thu, 26 Feb 2026 13:55:12 +0000 Subject: [PATCH 07/15] Fix variable reference for power per major radius in plot_main_plasma_information and update physics calculations --- process/core/io/plot_proc.py | 2 +- process/models/physics/physics.py | 17 ++++++++++++----- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/process/core/io/plot_proc.py b/process/core/io/plot_proc.py index af8b0dd94..f2d24780e 100644 --- a/process/core/io/plot_proc.py +++ b/process/core/io/plot_proc.py @@ -2776,7 +2776,7 @@ def plot_main_plasma_information( # Add divertor information textstr_div = ( f"\n$P_{{\\text{{sep}}}}$: {mfile.get('p_plasma_separatrix_mw', scan=scan):.2f} MW \n" - f"$\\frac{{P_{{\\text{{sep}}}}}}{{R}}$: {mfile.get('p_plasma_separatrix_mw/rmajor', scan=scan):.2f} MW/m \n" + f"$\\frac{{P_{{\\text{{sep}}}}}}{{R}}$: {mfile.get('p_plasma_separatrix_rmajor_mw', scan=scan):.2f} MW/m \n" f"$\\frac{{P_{{\\text{{sep}}}}}}{{B_T q_a R}}$: {mfile.get('pdivtbt_over_qar', scan=scan):.2f} MW T/m " ) diff --git a/process/models/physics/physics.py b/process/models/physics/physics.py index 2828f3f68..098ad6663 100644 --- a/process/models/physics/physics.py +++ b/process/models/physics/physics.py @@ -2395,6 +2395,13 @@ def physics(self): ) ) + physics_variables.p_plasma_separatrix_rmajor_mw = ( + self.exhaust.calculate_psep_over_r_metric( + p_plasma_separatrix_mw=physics_variables.p_plasma_separatrix_mw, + rmajor=physics_variables.rmajor, + ) + ) + physics_variables.pflux_plasma_surface_neutron_avg_mw = ( physics_variables.p_neutron_total_mw / physics_variables.a_plasma_surface ) @@ -4922,7 +4929,7 @@ def outplas(self): po.oblnkl(self.outfile) po.ovarre( self.outfile, - "Power into divertor zone via charged particles (MW)", + "Plasma separatrix power (MW)", "(p_plasma_separatrix_mw)", physics_variables.p_plasma_separatrix_mw, "OP ", @@ -4949,8 +4956,8 @@ def outplas(self): po.ovarre( self.outfile, "Pdivt / R ratio (MW/m) (On peak divertor)", - "(p_div_separatrix_max_mw/physics_variables.rmajor)", - physics_variables.p_div_separatrix_max_mw / physics_variables.rmajor, + "(p_div_separatrix_rmajor_mw)", + physics_variables.p_div_separatrix_rmajor_mw, "OP ", ) po.ovarre( @@ -4975,8 +4982,8 @@ def outplas(self): po.ovarre( self.outfile, "Psep / R ratio (MW/m)", - "(p_plasma_separatrix_mw/rmajor)", - physics_variables.p_plasma_separatrix_mw / physics_variables.rmajor, + "(p_plasma_separatrix_rmajor_mw)", + physics_variables.p_plasma_separatrix_rmajor_mw, "OP ", ) po.ovarre( From e12cf0e3a9eb5461849a09186f3670ad748f77b4 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Thu, 26 Feb 2026 14:26:26 +0000 Subject: [PATCH 08/15] Add EU DEMO divertor protection parameter to physics variables --- process/data_structure/physics_variables.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/process/data_structure/physics_variables.py b/process/data_structure/physics_variables.py index c48d63e4f..1be58a06f 100644 --- a/process/data_structure/physics_variables.py +++ b/process/data_structure/physics_variables.py @@ -914,6 +914,9 @@ p_plasma_separatrix_rmajor_mw: float = None """Power to conducted to the divertor region per major radius (MW/m)""" +p_div_bt_q_aspect_rmajor_mw: float = None +"""EU DEMO divertor protection parameter (MW/T/m)""" + p_div_lower_separatrix_mw: float = None """Separatrix power conducted to the lower divertor region (calculated if `i_single_null = 0`) (MW)""" @@ -1571,6 +1574,7 @@ def init_physics_variables(): p_dhe3_total_mw, \ p_plasma_separatrix_mw, \ p_plasma_separatrix_rmajor_mw, \ + p_div_bt_q_aspect_rmajor_mw, \ p_div_lower_separatrix_mw, \ p_div_upper_separatrix_mw, \ p_div_separatrix_max_mw, \ @@ -1844,6 +1848,7 @@ def init_physics_variables(): p_plasma_separatrix_mw = 0.0 p_plasma_separatrix_rmajor_mw = 0.0 p_div_lower_separatrix_mw = 0.0 + p_div_lower_separatrix_mw = 0.0 p_div_upper_separatrix_mw = 0.0 p_div_separatrix_max_mw = 0.0 p_dt_total_mw = 0.0 From a4a117f1162741d67f0c21b676712b2fbf36074e Mon Sep 17 00:00:00 2001 From: mn3981 Date: Thu, 26 Feb 2026 14:29:52 +0000 Subject: [PATCH 09/15] Add calculation for p_div_bt_q_aspect_rmajor_mw in Physics class --- process/core/io/plot_proc.py | 2 +- process/core/io/variable_metadata.py | 2 +- process/models/physics/physics.py | 38 ++++++++++------------------ 3 files changed, 16 insertions(+), 26 deletions(-) diff --git a/process/core/io/plot_proc.py b/process/core/io/plot_proc.py index f2d24780e..cc0e3db50 100644 --- a/process/core/io/plot_proc.py +++ b/process/core/io/plot_proc.py @@ -2777,7 +2777,7 @@ def plot_main_plasma_information( textstr_div = ( f"\n$P_{{\\text{{sep}}}}$: {mfile.get('p_plasma_separatrix_mw', scan=scan):.2f} MW \n" f"$\\frac{{P_{{\\text{{sep}}}}}}{{R}}$: {mfile.get('p_plasma_separatrix_rmajor_mw', scan=scan):.2f} MW/m \n" - f"$\\frac{{P_{{\\text{{sep}}}}}}{{B_T q_a R}}$: {mfile.get('pdivtbt_over_qar', scan=scan):.2f} MW T/m " + f"$\\frac{{P_{{\\text{{sep}}}}}}{{B_T q_a R}}$: {mfile.get('p_div_bt_q_aspect_rmajor_mw', scan=scan):.2f} MW T/m " ) axis.text( diff --git a/process/core/io/variable_metadata.py b/process/core/io/variable_metadata.py index 3e9dfd5d2..2e4cdbdf4 100644 --- a/process/core/io/variable_metadata.py +++ b/process/core/io/variable_metadata.py @@ -247,7 +247,7 @@ class VariableMetadata: "p_plasma_rad_mw": VariableMetadata( latex=r"$P_{\mathrm{rad}}$ [$MW$]", description="Radiation power", units="MW" ), - "pdivtbt_over_qar": VariableMetadata( + "p_div_bt_q_aspect_rmajor_mw": VariableMetadata( latex=r"$\frac{P_{\mathrm{sep}}B_T}{q_{95}AR_{\mathrm{maj}}}$ [$MWTm^{-1}$]", description="", units="MWTm^{-1}", diff --git a/process/models/physics/physics.py b/process/models/physics/physics.py index 098ad6663..0f8d27a08 100644 --- a/process/models/physics/physics.py +++ b/process/models/physics/physics.py @@ -2402,6 +2402,16 @@ def physics(self): ) ) + physics_variables.p_div_bt_q_aspect_rmajor_mw = ( + self.exhaust.calculate_eu_demo_re_attachment_metric( + p_plasma_separatrix_mw=physics_variables.p_plasma_separatrix_mw, + b_plasma_toroidal_on_axis=physics_variables.b_plasma_toroidal_on_axis, + q95=physics_variables.q95, + aspect=physics_variables.aspect, + rmajor=physics_variables.rmajor, + ) + ) + physics_variables.pflux_plasma_surface_neutron_avg_mw = ( physics_variables.p_neutron_total_mw / physics_variables.a_plasma_surface ) @@ -4963,18 +4973,8 @@ def outplas(self): po.ovarre( self.outfile, "Pdivt Bt / qAR ratio (MWT/m) (On peak divertor)", - "(pdivmaxbt/qar)", - ( - ( - physics_variables.p_div_separatrix_max_mw - * physics_variables.b_plasma_toroidal_on_axis - ) - / ( - physics_variables.q95 - * physics_variables.aspect - * physics_variables.rmajor - ) - ), + "(p_div_bt_q_aspect_rmajor_mw)", + physics_variables.p_div_bt_q_aspect_rmajor_mw, "OP ", ) else: @@ -4989,18 +4989,8 @@ def outplas(self): po.ovarre( self.outfile, "Psep Bt / qAR ratio (MWT/m)", - "(pdivtbt_over_qar)", - ( - ( - physics_variables.p_plasma_separatrix_mw - * physics_variables.b_plasma_toroidal_on_axis - ) - / ( - physics_variables.q95 - * physics_variables.aspect - * physics_variables.rmajor - ) - ), + "(p_div_bt_q_aspect_rmajor_mw)", + physics_variables.p_div_bt_q_aspect_rmajor_mw, "OP ", ) From 1bbcfc4dc5a1713b133e2c6b99e93748954c50fc Mon Sep 17 00:00:00 2001 From: mn3981 Date: Thu, 26 Feb 2026 14:41:24 +0000 Subject: [PATCH 10/15] Refactor docstrings in PlasmaExhaust class to use NumPy style formatting and add references for EU DEMO metric calculation --- process/models/physics/physics.py | 89 ++++++++++++++++++++----------- 1 file changed, 57 insertions(+), 32 deletions(-) diff --git a/process/models/physics/physics.py b/process/models/physics/physics.py index 0f8d27a08..9d7d9927e 100644 --- a/process/models/physics/physics.py +++ b/process/models/physics/physics.py @@ -9491,20 +9491,25 @@ def calculate_separatrix_power( """ Calculate the power crossing the separatrix (P_sep). - :param f_p_alpha_plasma_deposited: Fraction of alpha power deposited in plasma. - :type f_p_alpha_plasma_deposited: float - :param p_alpha_total_mw: Total alpha power produced (MW). - :type p_alpha_total_mw: float - :param p_non_alpha_charged_mw: Power from non-alpha charged particles (MW). - :type p_non_alpha_charged_mw: float - :param p_hcd_injected_total_mw: Total power injected by heating and current drive (MW). - :type p_hcd_injected_total_mw: float - :param p_plasma_ohmic_mw: Ohmic heating power (MW). - :type p_plasma_ohmic_mw: float - :param p_plasma_rad_mw: Radiated power from plasma (MW). - :type p_plasma_rad_mw: float - :return: Power crossing the separatrix (MW). - :rtype: float + Parameters + ---------- + f_p_alpha_plasma_deposited : float + Fraction of alpha power deposited in plasma. + p_alpha_total_mw : float + Total alpha power produced (MW). + p_non_alpha_charged_mw : float + Power from non-alpha charged particles (MW). + p_hcd_injected_total_mw : float + Total power injected by heating and current drive (MW). + p_plasma_ohmic_mw : float + Ohmic heating power (MW). + p_plasma_rad_mw : float + Radiated power from plasma (MW). + + Returns + ------- + float + Power crossing the separatrix (MW). """ return ( @@ -9522,13 +9527,17 @@ def calculate_psep_over_r_metric( """ Calculate the power crossing the separatrix per unit major radius (P_sep/R). - :param p_plasma_separatrix_mw: Power crossing the separatrix (MW). - :type p_plasma_separatrix_mw: float - :param rmajor: Plasma major radius (m). - :type rmajor: float - :return: Power crossing the separatrix per unit major radius (MW/m). - :rtype: float + Parameters + ---------- + p_plasma_separatrix_mw : float + Power crossing the separatrix (MW). + rmajor : float + Plasma major radius (m). + Returns + ------- + float + Power crossing the separatrix per unit major radius (MW/m). """ return p_plasma_separatrix_mw / rmajor @@ -9542,19 +9551,35 @@ def calculate_eu_demo_re_attachment_metric( ) -> float: """Calculate the EU DEMO divertor protection re-attachment metric for plasma exhaust. - :param p_plasma_separatrix_mw: Power crossing the separatrix (MW). - :type p_plasma_separatrix_mw: float - :param b_plasma_toroidal_on_axis: Toroidal magnetic field on axis (T). - :type b_plasma_toroidal_on_axis: float - :param q95: Safety factor at 95% flux surface. - :type q95: float - :param aspect: Aspect ratio of the plasma. - :type aspect: float - :param rmajor: Plasma major radius (m). - :type rmajor: float - :return: EU DEMO re-attachment metric (MW T /m). - :rtype: float + Parameters + ---------- + p_plasma_separatrix_mw : float + Power crossing the separatrix (MW). + b_plasma_toroidal_on_axis : float + Toroidal magnetic field on axis (T). + q95 : float + Safety factor at 95% flux surface. + aspect : float + Aspect ratio of the plasma. + rmajor : float + Plasma major radius (m). + Returns + ------- + float + EU DEMO re-attachment metric (MW T /m). + + References + ---------- + - M. Siccinio, G. Federici, R. Kembleton, H. Lux, F. Maviglia, and J. Morris, + "Figure of merit for divertor protection in the preliminary design of the EU-DEMO reactor," + Nuclear Fusion, vol. 59, no. 10, pp. 106026-106026, Jul. 2019, + doi: https://doi.org/10.1088/1741-4326/ab3153. + + - H. Zohm et al., + "A stepladder approach to a tokamak fusion power plant," + Nuclear Fusion, vol. 57, no. 8, pp. 086002-086002, May 2017, + doi: https://doi.org/10.1088/1741-4326/aa739e. """ return (p_plasma_separatrix_mw * b_plasma_toroidal_on_axis) / ( From 60a09624c3f5b0b3b12f5f18183a83c982ca78f7 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Thu, 26 Feb 2026 14:50:56 +0000 Subject: [PATCH 11/15] Create exhaust file --- process/main.py | 2 +- process/models/physics/exhaust.py | 120 ++++++++++++++++++++++++++++++ process/models/physics/physics.py | 115 ---------------------------- tests/unit/test_physics.py | 2 +- tests/unit/test_stellarator.py | 6 +- 5 files changed, 123 insertions(+), 122 deletions(-) create mode 100644 process/models/physics/exhaust.py diff --git a/process/main.py b/process/main.py index 1f4a9401b..97e2db0eb 100644 --- a/process/main.py +++ b/process/main.py @@ -93,12 +93,12 @@ NeutralBeam, ) from process.models.physics.density_limit import PlasmaDensityLimit +from process.models.physics.exhaust import PlasmaExhaust from process.models.physics.impurity_radiation import initialise_imprad from process.models.physics.physics import ( DetailedPhysics, Physics, PlasmaBeta, - PlasmaExhaust, PlasmaInductance, ) from process.models.physics.plasma_geometry import PlasmaGeom diff --git a/process/models/physics/exhaust.py b/process/models/physics/exhaust.py new file mode 100644 index 000000000..d57e9ab7f --- /dev/null +++ b/process/models/physics/exhaust.py @@ -0,0 +1,120 @@ +import logging + +from process import constants + +logger = logging.getLogger(__name__) + + +class PlasmaExhaust: + """Class to hold plasma exhaust calculations for plasma processing.""" + + def __init__(self): + self.outfile = constants.NOUT + self.mfile = constants.MFILE + + @staticmethod + def calculate_separatrix_power( + f_p_alpha_plasma_deposited: float, + p_alpha_total_mw: float, + p_non_alpha_charged_mw: float, + p_hcd_injected_total_mw: float, + p_plasma_ohmic_mw: float, + p_plasma_rad_mw: float, + ) -> float: + """ + Calculate the power crossing the separatrix (P_sep). + + Parameters + ---------- + f_p_alpha_plasma_deposited : float + Fraction of alpha power deposited in plasma. + p_alpha_total_mw : float + Total alpha power produced (MW). + p_non_alpha_charged_mw : float + Power from non-alpha charged particles (MW). + p_hcd_injected_total_mw : float + Total power injected by heating and current drive (MW). + p_plasma_ohmic_mw : float + Ohmic heating power (MW). + p_plasma_rad_mw : float + Radiated power from plasma (MW). + + Returns + ------- + float + Power crossing the separatrix (MW). + """ + + return ( + f_p_alpha_plasma_deposited * p_alpha_total_mw + + p_non_alpha_charged_mw + + p_hcd_injected_total_mw + + p_plasma_ohmic_mw + - p_plasma_rad_mw + ) + + @staticmethod + def calculate_psep_over_r_metric( + p_plasma_separatrix_mw: float, rmajor: float + ) -> float: + """ + Calculate the power crossing the separatrix per unit major radius (P_sep/R). + + Parameters + ---------- + p_plasma_separatrix_mw : float + Power crossing the separatrix (MW). + rmajor : float + Plasma major radius (m). + + Returns + ------- + float + Power crossing the separatrix per unit major radius (MW/m). + """ + return p_plasma_separatrix_mw / rmajor + + @staticmethod + def calculate_eu_demo_re_attachment_metric( + p_plasma_separatrix_mw: float, + b_plasma_toroidal_on_axis: float, + q95: float, + aspect: float, + rmajor: float, + ) -> float: + """Calculate the EU DEMO divertor protection re-attachment metric for plasma exhaust. + + Parameters + ---------- + p_plasma_separatrix_mw : float + Power crossing the separatrix (MW). + b_plasma_toroidal_on_axis : float + Toroidal magnetic field on axis (T). + q95 : float + Safety factor at 95% flux surface. + aspect : float + Aspect ratio of the plasma. + rmajor : float + Plasma major radius (m). + + Returns + ------- + float + EU DEMO re-attachment metric (MW T /m). + + References + ---------- + - M. Siccinio, G. Federici, R. Kembleton, H. Lux, F. Maviglia, and J. Morris, + "Figure of merit for divertor protection in the preliminary design of the EU-DEMO reactor," + Nuclear Fusion, vol. 59, no. 10, pp. 106026-106026, Jul. 2019, + doi: https://doi.org/10.1088/1741-4326/ab3153. + + - H. Zohm et al., + "A stepladder approach to a tokamak fusion power plant," + Nuclear Fusion, vol. 57, no. 8, pp. 086002-086002, May 2017, + doi: https://doi.org/10.1088/1741-4326/aa739e. + """ + + return (p_plasma_separatrix_mw * b_plasma_toroidal_on_axis) / ( + q95 * aspect * rmajor + ) diff --git a/process/models/physics/physics.py b/process/models/physics/physics.py index 9d7d9927e..954c6517d 100644 --- a/process/models/physics/physics.py +++ b/process/models/physics/physics.py @@ -9472,121 +9472,6 @@ def output_volt_second_information(self): po.oblnkl(self.outfile) -class PlasmaExhaust: - """Class to hold plasma exhaust calculations for plasma processing.""" - - def __init__(self): - self.outfile = constants.NOUT - self.mfile = constants.MFILE - - @staticmethod - def calculate_separatrix_power( - f_p_alpha_plasma_deposited: float, - p_alpha_total_mw: float, - p_non_alpha_charged_mw: float, - p_hcd_injected_total_mw: float, - p_plasma_ohmic_mw: float, - p_plasma_rad_mw: float, - ) -> float: - """ - Calculate the power crossing the separatrix (P_sep). - - Parameters - ---------- - f_p_alpha_plasma_deposited : float - Fraction of alpha power deposited in plasma. - p_alpha_total_mw : float - Total alpha power produced (MW). - p_non_alpha_charged_mw : float - Power from non-alpha charged particles (MW). - p_hcd_injected_total_mw : float - Total power injected by heating and current drive (MW). - p_plasma_ohmic_mw : float - Ohmic heating power (MW). - p_plasma_rad_mw : float - Radiated power from plasma (MW). - - Returns - ------- - float - Power crossing the separatrix (MW). - """ - - return ( - f_p_alpha_plasma_deposited * p_alpha_total_mw - + p_non_alpha_charged_mw - + p_hcd_injected_total_mw - + p_plasma_ohmic_mw - - p_plasma_rad_mw - ) - - @staticmethod - def calculate_psep_over_r_metric( - p_plasma_separatrix_mw: float, rmajor: float - ) -> float: - """ - Calculate the power crossing the separatrix per unit major radius (P_sep/R). - - Parameters - ---------- - p_plasma_separatrix_mw : float - Power crossing the separatrix (MW). - rmajor : float - Plasma major radius (m). - - Returns - ------- - float - Power crossing the separatrix per unit major radius (MW/m). - """ - return p_plasma_separatrix_mw / rmajor - - @staticmethod - def calculate_eu_demo_re_attachment_metric( - p_plasma_separatrix_mw: float, - b_plasma_toroidal_on_axis: float, - q95: float, - aspect: float, - rmajor: float, - ) -> float: - """Calculate the EU DEMO divertor protection re-attachment metric for plasma exhaust. - - Parameters - ---------- - p_plasma_separatrix_mw : float - Power crossing the separatrix (MW). - b_plasma_toroidal_on_axis : float - Toroidal magnetic field on axis (T). - q95 : float - Safety factor at 95% flux surface. - aspect : float - Aspect ratio of the plasma. - rmajor : float - Plasma major radius (m). - - Returns - ------- - float - EU DEMO re-attachment metric (MW T /m). - - References - ---------- - - M. Siccinio, G. Federici, R. Kembleton, H. Lux, F. Maviglia, and J. Morris, - "Figure of merit for divertor protection in the preliminary design of the EU-DEMO reactor," - Nuclear Fusion, vol. 59, no. 10, pp. 106026-106026, Jul. 2019, - doi: https://doi.org/10.1088/1741-4326/ab3153. - - - H. Zohm et al., - "A stepladder approach to a tokamak fusion power plant," - Nuclear Fusion, vol. 57, no. 8, pp. 086002-086002, May 2017, - doi: https://doi.org/10.1088/1741-4326/aa739e. - """ - - return (p_plasma_separatrix_mw * b_plasma_toroidal_on_axis) / ( - q95 * aspect * rmajor - ) - - class DetailedPhysics: """Class to hold detailed physics models for plasma processing.""" diff --git a/tests/unit/test_physics.py b/tests/unit/test_physics.py index 7a3933fe8..7722b2f47 100644 --- a/tests/unit/test_physics.py +++ b/tests/unit/test_physics.py @@ -20,12 +20,12 @@ NeutralBeam, ) from process.models.physics.density_limit import PlasmaDensityLimit +from process.models.physics.exhaust import PlasmaExhaust from process.models.physics.impurity_radiation import initialise_imprad from process.models.physics.physics import ( DetailedPhysics, Physics, PlasmaBeta, - PlasmaExhaust, PlasmaInductance, calculate_current_coefficient_hastie, calculate_plasma_current_peng, diff --git a/tests/unit/test_stellarator.py b/tests/unit/test_stellarator.py index dfc71de88..0fa5e0444 100644 --- a/tests/unit/test_stellarator.py +++ b/tests/unit/test_stellarator.py @@ -30,15 +30,11 @@ NeutralBeam, ) from process.models.physics.density_limit import PlasmaDensityLimit +from process.models.physics.exhaust import PlasmaExhaust from process.models.physics.physics import ( - ( Physics, - PlasmaBeta, - - PlasmaExhaust, PlasmaInductance, -), ) from process.models.physics.plasma_profiles import PlasmaProfile from process.models.power import Power From ed02c65b52f1c553a9bf7b7784ed819d68031884 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Mon, 2 Mar 2026 14:27:39 +0000 Subject: [PATCH 12/15] Fix import statement for constants in exhaust module --- process/models/physics/exhaust.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/process/models/physics/exhaust.py b/process/models/physics/exhaust.py index d57e9ab7f..eb0021fb8 100644 --- a/process/models/physics/exhaust.py +++ b/process/models/physics/exhaust.py @@ -1,6 +1,6 @@ import logging -from process import constants +from process.core import constants logger = logging.getLogger(__name__) From 9d363e69266cfc23307f6789682bc1a0470c1355 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Mon, 2 Mar 2026 14:33:07 +0000 Subject: [PATCH 13/15] Fix variable name in output for plasma separatrix pressure calculation --- process/models/physics/physics.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/process/models/physics/physics.py b/process/models/physics/physics.py index 954c6517d..7747d8d24 100644 --- a/process/models/physics/physics.py +++ b/process/models/physics/physics.py @@ -4966,8 +4966,8 @@ def outplas(self): po.ovarre( self.outfile, "Pdivt / R ratio (MW/m) (On peak divertor)", - "(p_div_separatrix_rmajor_mw)", - physics_variables.p_div_separatrix_rmajor_mw, + "(p_plasma_separatrix_rmajor_mw)", + physics_variables.p_plasma_separatrix_rmajor_mw, "OP ", ) po.ovarre( From a0da7f96cd204b5c2d99c51b317042da4fc2e205 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Wed, 4 Mar 2026 11:01:54 +0000 Subject: [PATCH 14/15] Post rebase conflcit fixes --- process/models/physics/physics.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/process/models/physics/physics.py b/process/models/physics/physics.py index 7747d8d24..5316dd361 100644 --- a/process/models/physics/physics.py +++ b/process/models/physics/physics.py @@ -1626,18 +1626,12 @@ def _trapped_particle_fraction_sauter( class Physics: def __init__( - self, - plasma_profile, - current_drive, - plasma_beta, - plasma_inductance, plasma_density_limit, - , plasma_exhaust, ): self.outfile = constants.NOUT From f2e09c81fd51ec95bdfa0886bfc5bb99d1ad9949 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Wed, 4 Mar 2026 13:17:37 +0000 Subject: [PATCH 15/15] Add new variable for plasma separatrix power in init_physics_variables function --- process/data_structure/physics_variables.py | 1 + 1 file changed, 1 insertion(+) diff --git a/process/data_structure/physics_variables.py b/process/data_structure/physics_variables.py index 1be58a06f..92c9d9bb9 100644 --- a/process/data_structure/physics_variables.py +++ b/process/data_structure/physics_variables.py @@ -1847,6 +1847,7 @@ def init_physics_variables(): p_dhe3_total_mw = 0.0 p_plasma_separatrix_mw = 0.0 p_plasma_separatrix_rmajor_mw = 0.0 + p_div_bt_q_aspect_rmajor_mw = 0.0 p_div_lower_separatrix_mw = 0.0 p_div_lower_separatrix_mw = 0.0 p_div_upper_separatrix_mw = 0.0