From 26c8c84628d1ecac075cbbd1b2259f14bd988a1d Mon Sep 17 00:00:00 2001 From: Clair Mould <86794332+clmould@users.noreply.github.com> Date: Wed, 20 May 2026 14:44:10 +0100 Subject: [PATCH 01/13] WIP phys dataclass --- documentation/source/development/add-vars.md | 4 +- .../RF/culham_electron_cyclotron.md | 2 +- .../RF/culham_lower_hybrid.md | 4 +- .../fusion_reactions/plasma_reactions.md | 2 +- process/core/caller.py | 2 +- process/core/init.py | 137 +- process/core/input.py | 275 +- process/core/io/plot/summary.py | 2 +- process/core/model.py | 2 + process/core/output.py | 2 +- process/core/scan.py | 23 +- process/core/solver/constraints.py | 336 +- process/core/solver/evaluators.py | 9 +- process/core/solver/iteration_variables.py | 62 +- process/core/solver/objectives.py | 19 +- process/data_structure/physics_variables.py | 2800 ++++++----------- process/main.py | 11 +- process/models/availability.py | 49 +- process/models/blankets/blanket_library.py | 61 +- process/models/blankets/dcll.py | 35 +- process/models/blankets/hcpb.py | 83 +- process/models/build.py | 99 +- process/models/buildings.py | 17 +- process/models/costs/costs.py | 39 +- process/models/costs/costs_2015.py | 15 +- process/models/divertor.py | 41 +- process/models/fw.py | 51 +- process/models/ife.py | 27 +- process/models/pfcoil.py | 99 +- process/models/physics/bootstrap_current.py | 251 +- process/models/physics/confinement_time.py | 222 +- process/models/physics/current_drive.py | 297 +- process/models/physics/density_limit.py | 93 +- process/models/physics/exhaust.py | 15 +- process/models/physics/fusion_reactions.py | 151 +- process/models/physics/l_h_transition.py | 113 +- process/models/physics/physics.py | 2308 +++++++------- process/models/physics/plasma_current.py | 121 +- process/models/physics/plasma_fields.py | 21 +- process/models/physics/plasma_geometry.py | 287 +- process/models/physics/plasma_profiles.py | 270 +- process/models/physics/profiles.py | 106 +- process/models/power.py | 25 +- process/models/pulse.py | 11 +- process/models/shield.py | 19 +- process/models/stellarator/build.py | 41 +- process/models/stellarator/coils/quench.py | 15 +- process/models/stellarator/denisty_limits.py | 84 +- process/models/stellarator/divertor.py | 11 +- process/models/stellarator/heating.py | 9 +- process/models/stellarator/initialization.py | 15 +- process/models/stellarator/neoclassics.py | 201 +- process/models/stellarator/stellarator.py | 588 ++-- process/models/structure.py | 11 +- process/models/tfcoil/base.py | 39 +- process/models/tfcoil/resistive.py | 29 +- process/models/tfcoil/superconducting.py | 13 +- process/models/vacuum.py | 38 +- .../models/blankets/test_blanket_library.py | 32 +- tests/unit/models/blankets/test_ccfe_hcpb.py | 25 +- .../unit/models/physics/test_current_drive.py | 85 +- .../models/physics/test_fusion_reactions.py | 18 +- .../models/physics/test_l_h_transition.py | 39 +- tests/unit/models/physics/test_physics.py | 319 +- .../models/physics/test_plasma_profiles.py | 131 +- .../models/stellarator/test_neoclassics.py | 36 +- .../models/stellarator/test_stellarator.py | 70 +- tests/unit/models/test_availability.py | 19 +- tests/unit/models/test_build.py | 12 +- tests/unit/models/test_buildings.py | 9 +- tests/unit/models/test_costs_1990.py | 35 +- tests/unit/models/test_costs_2015.py | 11 +- tests/unit/models/test_dcll.py | 12 +- tests/unit/models/test_ife.py | 6 +- tests/unit/models/test_pfcoil.py | 41 +- tests/unit/models/test_power.py | 31 +- tests/unit/models/test_pulse.py | 9 +- tests/unit/models/test_vacuum.py | 13 +- .../models/tfcoil/test_resistive_tf_coil.py | 7 +- tests/unit/models/tfcoil/test_sctfcoil.py | 3 +- 80 files changed, 4778 insertions(+), 5897 deletions(-) diff --git a/documentation/source/development/add-vars.md b/documentation/source/development/add-vars.md index 5e4f16160f..e62fcfa23c 100644 --- a/documentation/source/development/add-vars.md +++ b/documentation/source/development/add-vars.md @@ -71,7 +71,7 @@ Here is a code snippet showing how `rmajor` is defined in `iteration_variables.p ```python ITERATION_VARIABLES = { ... - 3: IterationVariable("rmajor", fortran.physics_variables, 0.1, 50.00), + 3: IterationVariable("rmajor", "physics", 0.1, 50.00), ``` ----------------- @@ -97,7 +97,7 @@ objective_function(): match figure_of_merit: ... case 1: - objective_metric = 0.2 * physics_variables.rmajor + objective_metric = 0.2 * data.physics.rmajor ``` ----------- diff --git a/documentation/source/eng-models/heating_and_current_drive/RF/culham_electron_cyclotron.md b/documentation/source/eng-models/heating_and_current_drive/RF/culham_electron_cyclotron.md index d96828bd92..9f7eb7c0ae 100644 --- a/documentation/source/eng-models/heating_and_current_drive/RF/culham_electron_cyclotron.md +++ b/documentation/source/eng-models/heating_and_current_drive/RF/culham_electron_cyclotron.md @@ -47,7 +47,7 @@ $$ \mathtt{ecgam} = 0.25(\mathtt{ecgam1} + \mathtt{ecgam2} +\mathtt{ecgam3} + \mathtt{ecgam4}) $$ -7. Calculate the current drive efficiency by dividing `ecgam` by `(dlocal * physics_variables.rmajor)`. +1. Calculate the current drive efficiency by dividing `ecgam` by `(dlocal * data.physics.rmajor)`. $$ \text{Current drive efficiency [A/W]} = \frac{\mathtt{ecgam}}{\mathtt{dlocal} \times R_0} diff --git a/documentation/source/eng-models/heating_and_current_drive/RF/culham_lower_hybrid.md b/documentation/source/eng-models/heating_and_current_drive/RF/culham_lower_hybrid.md index 3247ac1f7b..cf885906c2 100644 --- a/documentation/source/eng-models/heating_and_current_drive/RF/culham_lower_hybrid.md +++ b/documentation/source/eng-models/heating_and_current_drive/RF/culham_lower_hybrid.md @@ -15,9 +15,9 @@ AEA FUS 172: Physics Assessment for the European Reactor Study[^1] 6. Calculate the parallel refractive index, `nplacc`, which is needed for plasma access. It uses the local density `dlocal` and the local magnetic field `blocal` to calculate a fraction `frac`. `nplacc` is then obtained by adding `frac` to the square root of `1.0 + frac * frac`. 7. Calculate the local inverse aspect ratio, `epslh`, by dividing `rpenet` by `rmajor`. 8. Calculate the LH normalised efficiency, `x`, using the formula `24.0 / (nplacc * sqrt(tlocal))`. -9. Calculate several intermediate terms, `term01`, `term02`, `term03`, and `term04`, using different formulas involving `nplacc`, `physics_variables.zeff`, `tlocal`, `epslh`, and `x`. +9. Calculate several intermediate terms, `term01`, `term02`, `term03`, and `term04`, using different formulas involving `nplacc`, `data.physics.zeff`, `tlocal`, `epslh`, and `x`. 10. Calculate the current drive efficiency, `gamlh`, using the formula `term01 * term02 * (1.0e0 - term03 / term04)`. -11. Return the current drive efficiency normalised by the product of `0.1e0 * dlocal` and `physics_variables.rmajor`. +11. Return the current drive efficiency normalised by the product of `0.1e0 * dlocal` and `data.physics`. [^1]: T. C. Hender, M. K. Bevir, M. Cox, R. J. Hastie, P. J. Knight, C. N. Lashmore-Davies, B. Lloyd, G. P. Maddison, A. W. Morris, M. R. O'Brien, M.F. Turner abd H. R. Wilson, *"Physics Assessment for the European Reactor Study"*, AEA Fusion Report AEA FUS 172 (1992) diff --git a/documentation/source/physics-models/fusion_reactions/plasma_reactions.md b/documentation/source/physics-models/fusion_reactions/plasma_reactions.md index cb967370ed..f2ebb04db9 100644 --- a/documentation/source/physics-models/fusion_reactions/plasma_reactions.md +++ b/documentation/source/physics-models/fusion_reactions/plasma_reactions.md @@ -177,7 +177,7 @@ It updates the instance attributes for the cumulative power densities and reacti ### Set global physics variables | `set_physics_variables()` -This method sets the required physics variables in the `physics_variables` and `physics_module` modules. It updates the global physics variables and module variables with the current instance's fusion power densities and reaction rates. +This method sets the required physics variables in the `physics_variables` and `physics` module. It updates the global physics variables and module variables with the current instance's fusion power densities and reaction rates. #### Updates: - `physics_variables.pden_plasma_alpha_mw`: Updated with `self.alpha_power_density` diff --git a/process/core/caller.py b/process/core/caller.py index df87164244..4d842d29f9 100644 --- a/process/core/caller.py +++ b/process/core/caller.py @@ -361,7 +361,7 @@ def _call_models_once(self, xc: np.ndarray, data: DataStructure): # Tight aspect ratio machine model if ( - data_structure.physics_variables.itart == 1 + data.physics.itart == 1 and data_structure.tfcoil_variables.i_tf_sup != TFConductorModel.SUPERCONDUCTING ): diff --git a/process/core/init.py b/process/core/init.py index 1ecc36d607..731d3d7e6d 100644 --- a/process/core/init.py +++ b/process/core/init.py @@ -17,11 +17,7 @@ from process.core.solver import iteration_variables from process.core.solver.constraints import ConstraintManager from process.data_structure.impurity_radiation_variables import N_IMPURITIES -from process.data_structure.physics_variables import ( - DivertorNumberModels, - init_physics_module, - init_physics_variables, -) +from process.data_structure.physics_variables import DivertorNumberModels from process.data_structure.rebco_variables import init_rebco_variables from process.data_structure.scan_variables import init_scan_variables from process.data_structure.superconducting_tf_coil_variables import ( @@ -240,8 +236,6 @@ def init_all_module_vars(): logging_model_handler.clear_logs() data_structure.numerics.init_numerics() data_structure.global_variables.init_global_variables() - init_physics_module() - init_physics_variables() init_scan_variables() init_superconducting_tf_coil_variables() init_tfcoil_variables() @@ -334,22 +328,20 @@ def check_process(inputs, data): # noqa: ARG001 if ( abs( 1.0 - - data_structure.physics_variables.f_plasma_fuel_deuterium - - data_structure.physics_variables.f_plasma_fuel_tritium - - data_structure.physics_variables.f_plasma_fuel_helium3 + - data.physics.f_plasma_fuel_deuterium + - data.physics.f_plasma_fuel_tritium + - data.physics.f_plasma_fuel_helium3 ) > 1e-6 ): raise ProcessValidationError( "Fuel ion fractions do not sum to 1.0", - f_plasma_fuel_deuterium=data_structure.physics_variables.f_plasma_fuel_deuterium, - f_plasma_fuel_tritium=data_structure.physics_variables.f_plasma_fuel_tritium, - f_plasma_fuel_helium3=data_structure.physics_variables.f_plasma_fuel_helium3, + f_plasma_fuel_deuterium=data.physics.f_plasma_fuel_deuterium, + f_plasma_fuel_tritium=data.physics.f_plasma_fuel_tritium, + f_plasma_fuel_helium3=data.physics.f_plasma_fuel_helium3, ) - if ( - data_structure.physics_variables.f_plasma_fuel_tritium < 1.0e-3 - ): # tritium fraction is negligible + if data.physics.f_plasma_fuel_tritium < 1.0e-3: # tritium fraction is negligible data.buildings.triv = 0.0 data.heat_transport.p_tritium_plant_electric_mw = 0.0 @@ -374,32 +366,29 @@ def check_process(inputs, data): # noqa: ARG001 ) # Plasma profile consistency checks - if data.ife.ife != 1 and data_structure.physics_variables.i_plasma_pedestal == 1: + if data.ife.ife != 1 and data.physics.i_plasma_pedestal == 1: # Temperature checks if ( - data_structure.physics_variables.temp_plasma_pedestal_kev - < data_structure.physics_variables.temp_plasma_separatrix_kev + data.physics.temp_plasma_pedestal_kev + < data.physics.temp_plasma_separatrix_kev ): raise ProcessValidationError( "Pedestal temperature is lower than separatrix temperature", - temp_plasma_pedestal_kev=data_structure.physics_variables.temp_plasma_pedestal_kev, - temp_plasma_separatrix_kev=data_structure.physics_variables.temp_plasma_separatrix_kev, + temp_plasma_pedestal_kev=data.physics.temp_plasma_pedestal_kev, + temp_plasma_separatrix_kev=data.physics.temp_plasma_separatrix_kev, ) - if ( - abs(data_structure.physics_variables.radius_plasma_pedestal_temp_norm - 1.0) - <= 1e-7 - ) and ( + if (abs(data.physics.radius_plasma_pedestal_temp_norm - 1.0) <= 1e-7) and ( ( - data_structure.physics_variables.temp_plasma_pedestal_kev - - data_structure.physics_variables.temp_plasma_separatrix_kev + data.physics.temp_plasma_pedestal_kev + - data.physics.temp_plasma_separatrix_kev ) >= 1e-7 ): warn( f"Temperature pedestal is at plasma edge, but temp_plasma_pedestal_kev " - f"({data_structure.physics_variables.temp_plasma_pedestal_kev}) differs from temp_plasma_separatrix_kev " - f"({data_structure.physics_variables.temp_plasma_separatrix_kev})", + f"({data.physics.temp_plasma_pedestal_kev}) differs from temp_plasma_separatrix_kev " + f"({data.physics.temp_plasma_separatrix_kev})", stacklevel=2, ) @@ -409,31 +398,31 @@ def check_process(inputs, data): # noqa: ARG001 # temperature. Prevent this by adjusting te, and its lower bound # (which will only have an effect if this is an optimisation run) if ( - data_structure.physics_variables.temp_plasma_electron_vol_avg_kev - <= data_structure.physics_variables.temp_plasma_pedestal_kev + data.physics.temp_plasma_electron_vol_avg_kev + <= data.physics.temp_plasma_pedestal_kev ): warn( - f"Volume-averaged temperature ({data_structure.physics_variables.te}) has been " - f"forced to exceed input pedestal height ({data_structure.physics_variables.temp_plasma_pedestal_kev}). " + f"Volume-averaged temperature ({data.physics.te}) has been " + f"forced to exceed input pedestal height ({data.physics.temp_plasma_pedestal_kev}). " "Changing to te = temp_plasma_pedestal_kev*1.001", stacklevel=2, ) - data_structure.physics_variables.temp_plasma_electron_vol_avg_kev = ( - data_structure.physics_variables.temp_plasma_pedestal_kev * 1.001 + data.physics.temp_plasma_electron_vol_avg_kev = ( + data.physics.temp_plasma_pedestal_kev * 1.001 ) if ( data_structure.numerics.ioptimz >= 0 and (data_structure.numerics.ixc[: data_structure.numerics.nvar] == 4).any() and data_structure.numerics.boundl[3] - < data_structure.physics_variables.temp_plasma_pedestal_kev * 1.001 + < data.physics.temp_plasma_pedestal_kev * 1.001 ): warn( "Lower limit of volume averaged electron temperature (temp_plasma_electron_vol_avg_kev) has been raised to ensure temp_plasma_electron_vol_avg_kev > temp_plasma_pedestal_kev", stacklevel=2, ) data_structure.numerics.boundl[3] = ( - data_structure.physics_variables.temp_plasma_pedestal_kev * 1.001 + data.physics.temp_plasma_pedestal_kev * 1.001 ) data_structure.numerics.boundu[3] = max( data_structure.numerics.boundu[3], data_structure.numerics.boundl[3] @@ -442,41 +431,37 @@ def check_process(inputs, data): # noqa: ARG001 # Density checks # Case where pedestal density is set manually if ( - data_structure.physics_variables.f_nd_plasma_pedestal_greenwald < 0 + data.physics.f_nd_plasma_pedestal_greenwald < 0 or not ( data_structure.numerics.ixc[: data_structure.numerics.nvar] == 145 ).any() ): # Issue #589 Pedestal density is set manually using nd_plasma_pedestal_electron but it is less than nd_plasma_separatrix_electron. if ( - data_structure.physics_variables.nd_plasma_pedestal_electron - < data_structure.physics_variables.nd_plasma_separatrix_electron + data.physics.nd_plasma_pedestal_electron + < data.physics.nd_plasma_separatrix_electron ): raise ProcessValidationError( "Density pedestal is lower than separatrix density", - nd_plasma_pedestal_electron=data_structure.physics_variables.nd_plasma_pedestal_electron, - nd_plasma_separatrix_electron=data_structure.physics_variables.nd_plasma_separatrix_electron, + nd_plasma_pedestal_electron=data.physics.nd_plasma_pedestal_electron, + nd_plasma_separatrix_electron=data.physics.nd_plasma_separatrix_electron, ) # Issue #589 Pedestal density is set manually using nd_plasma_pedestal_electron, # but pedestal width = 0. if ( - abs( - data_structure.physics_variables.radius_plasma_pedestal_density_norm - - 1.0 - ) - <= 1e-7 + abs(data.physics.radius_plasma_pedestal_density_norm - 1.0) <= 1e-7 and ( - data_structure.physics_variables.nd_plasma_pedestal_electron - - data_structure.physics_variables.nd_plasma_separatrix_electron + data.physics.nd_plasma_pedestal_electron + - data.physics.nd_plasma_separatrix_electron ) >= 1e-7 ): warn( "Density pedestal is at plasma edge " - f"({data_structure.physics_variables.radius_plasma_pedestal_density_norm = }), but nd_plasma_pedestal_electron " - f"({data_structure.physics_variables.nd_plasma_pedestal_electron}) differs from " - f"nd_plasma_separatrix_electron ({data_structure.physics_variables.nd_plasma_separatrix_electron})", + f"({data.physics.radius_plasma_pedestal_density_norm = }), but nd_plasma_pedestal_electron " + f"({data.physics.nd_plasma_pedestal_electron}) differs from " + f"nd_plasma_separatrix_electron ({data.physics.nd_plasma_separatrix_electron})", stacklevel=2, ) @@ -525,11 +510,11 @@ def check_process(inputs, data): # noqa: ARG001 data_structure.numerics.ixc[: data_structure.numerics.nvar] == 145 ).any() and data_structure.numerics.boundl[ 144 - ] < data_structure.physics_variables.f_nd_plasma_separatrix_greenwald: + ] < data.physics.f_nd_plasma_separatrix_greenwald: raise ProcessValidationError( "Set lower bound of iteration variable 145, f_nd_plasma_pedestal_greenwald, to be greater than f_nd_plasma_separatrix_greenwald", boundl_145=data_structure.numerics.boundl[144], - f_nd_plasma_separatrix_greenwald=data_structure.physics_variables.f_nd_plasma_separatrix_greenwald, + f_nd_plasma_separatrix_greenwald=data.physics.f_nd_plasma_separatrix_greenwald, ) if ( @@ -548,20 +533,20 @@ def check_process(inputs, data): # noqa: ARG001 # If Reinke criterion is used need to enforce LH-threshold # using Martin scaling for consistency - if (data_structure.physics_variables.i_l_h_threshold != 6) or ( + if (data.physics.i_l_h_threshold != 6) or ( not ( data_structure.numerics.icc[ : data_structure.numerics.neqns + data_structure.numerics.nineqns ] == 15 ).any() - and data_structure.physics_variables.i_plasma_pedestal + and data.physics.i_plasma_pedestal ): warn( "REINKE IMPURITY MODEL: The Martin LH threshold scale is not being used and is recommended for the Reinke model", stacklevel=2, ) - i_single_null = DivertorNumberModels(data_structure.physics_variables.i_single_null) + i_single_null = DivertorNumberModels(data.physics.i_single_null) if i_single_null == DivertorNumberModels.DOUBLE_NULL: data.divertor.n_divertors = 2 data.build.dz_fw_plasma_gap = data.build.dz_xpoint_divertor @@ -572,7 +557,7 @@ def check_process(inputs, data): # noqa: ARG001 data.divertor.n_divertors = 1 # Tight aspect ratio options (ST) - if data_structure.physics_variables.itart == 1: + if data.physics.itart == 1: data_structure.global_variables.icase = "Tight aspect ratio tokamak model" # Disabled Forcing that no inboard breeding blanket is used @@ -581,7 +566,7 @@ def check_process(inputs, data): # noqa: ARG001 # Check if the choice of plasma current is addapted for ST # 2 : Peng Ip scaling (See STAR code documentation) # 9 : Fiesta Ip scaling - if data_structure.physics_variables.i_plasma_current not in {2, 9}: + if data.physics.i_plasma_current not in {2, 9}: warn( "Usual current scaling for TARTs (i_plasma_current=2 or 9) is not being used", stacklevel=2, @@ -591,7 +576,7 @@ def check_process(inputs, data): # noqa: ARG001 # Overwrite the location of the TF coils # 2 : PF coil on top of TF coil # 3 : PF coil outside of TF coil - if data_structure.physics_variables.itartpf == 0: + if data.physics.itartpf == 0: data.pf_coil.i_pf_location[0] = 2 data.pf_coil.i_pf_location[1] = 3 data.pf_coil.i_pf_location[2] = 3 @@ -667,14 +652,14 @@ def check_process(inputs, data): # noqa: ARG001 ) # Check if the boostrap current selection is addapted to ST - if data_structure.physics_variables.i_bootstrap_current == 1: + if data.physics.i_bootstrap_current == 1: raise ProcessValidationError( "Invalid boostrap current law for ST, do not use i_bootstrap_current = 1" ) # Check if a single null divertor is used in double null machine if i_single_null == DivertorNumberModels.DOUBLE_NULL and ( - data_structure.physics_variables.f_p_div_lower in {1.0, 0.0} + data.physics.f_p_div_lower in {1.0, 0.0} ): warn("Operating with a single null in a double null machine", stacklevel=2) @@ -693,7 +678,7 @@ def check_process(inputs, data): # noqa: ARG001 ] == 85 ).any() - and data_structure.physics_variables.itart == 1 + and data.physics.itart == 1 ): raise ProcessValidationError( "Al TF coil fluence not calculated properly for Al CP, do not use constraint 85" @@ -722,7 +707,7 @@ def check_process(inputs, data): # noqa: ARG001 # Conventionnal aspect ratios specific else: - if data_structure.physics_variables.i_plasma_current in {2, 9}: + if data.physics.i_plasma_current in {2, 9}: raise ProcessValidationError( "i_plasma_current=2,9 is not a valid option for a non-TART device" ) @@ -1054,10 +1039,7 @@ def check_process(inputs, data): # noqa: ARG001 "Can only have i_tf_turns_integer = 1 with i_tf_wp_geom = 0" ) - if ( - data_structure.physics_variables.i_bootstrap_current == 5 - and data_structure.physics_variables.i_diamagnetic_current != 0 - ): + if data.physics.i_bootstrap_current == 5 and data.physics.i_diamagnetic_current != 0: raise ProcessValidationError( "i_diamagnetic_current = 0 should be used with the Sakai plasma current scaling" ) @@ -1102,9 +1084,9 @@ def check_process(inputs, data): # noqa: ARG001 # If there is no NBI, then hot beam density should be zero if data.current_drive.i_hcd_calculations == 1: if data.current_drive.i_hcd_primary not in {5, 8}: - data_structure.physics_variables.f_nd_beam_electron = 0.0 + data.physics.f_nd_beam_electron = 0.0 else: - data_structure.physics_variables.f_nd_beam_electron = 0.0 + data.physics.f_nd_beam_electron = 0.0 # Set inboard blanket thickness to zero if no inboard blanket switch # used (Issue #732) @@ -1149,25 +1131,16 @@ def check_process(inputs, data): # noqa: ARG001 data_structure.tfcoil_variables.tmargmin ) - if ( - data_structure.physics_variables.tauee_in > 1e-10 - and data_structure.physics_variables.i_confinement_time != 48 - ): + if data.physics.tauee_in > 1e-10 and data.physics.i_confinement_time != 48: # Report error if confinement time is in the input # but the scaling to use it is not selected. warn("tauee_in is for use with i_confinement_time=48 only", stacklevel=2) - if ( - data_structure.physics_variables.aspect > 1.7 - and data_structure.physics_variables.i_confinement_time == 46 - ): + if data.physics.aspect > 1.7 and data.physics.i_confinement_time == 46: # NSTX scaling is for A<1.7 warn("NSTX scaling is for A<1.7", stacklevel=2) - if ( - data_structure.physics_variables.i_plasma_current == 2 - and data_structure.physics_variables.i_confinement_time == 42 - ): + if data.physics.i_plasma_current == 2 and data.physics.i_confinement_time == 42: raise ProcessValidationError( "Lang 2012 confinement scaling cannot be used for i_plasma_current=2 due to wrong q" ) diff --git a/process/core/input.py b/process/core/input.py index 679996af66..efd35b33ba 100644 --- a/process/core/input.py +++ b/process/core/input.py @@ -18,6 +18,7 @@ from process.core.solver.constraints import ConstraintManager from process.data_structure.impurity_radiation_variables import N_IMPURITIES from process.data_structure.pfcoil_variables import N_PF_GROUPS_MAX +from process.data_structure.physics_variables import N_CONFINEMENT_SCALINGS if TYPE_CHECKING: from collections.abc import Callable @@ -118,76 +119,44 @@ def __post_init__(self): "nineqns": InputVariable( data_structure.numerics, int, range=(0, ConstraintManager.num_constraints()) ), - "alphaj": InputVariable(data_structure.physics_variables, float, range=(0.0, 10.0)), - "alphan": InputVariable(data_structure.physics_variables, float, range=(0.0, 10.0)), - "alphat": InputVariable(data_structure.physics_variables, float, range=(0.0, 10.0)), - "aspect": InputVariable( - data_structure.physics_variables, float, range=(1.001, 40.0) - ), - "beamfus0": InputVariable( - data_structure.physics_variables, float, range=(0.01, 10.0) - ), - "beta_total_vol_avg": InputVariable( - data_structure.physics_variables, float, range=(0.0, 1.0) - ), - "beta_vol_avg_max": InputVariable( - data_structure.physics_variables, float, range=(0.0, 1.0) - ), - "beta_vol_avg_min": InputVariable( - data_structure.physics_variables, float, range=(0.0, 1.0) - ), - "betbm0": InputVariable(data_structure.physics_variables, float, range=(0.0, 10.0)), - "b_plasma_toroidal_on_axis": InputVariable( - data_structure.physics_variables, float, range=(0.0, 30.0) - ), - "burnup_in": InputVariable( - data_structure.physics_variables, float, range=(0.0, 1.0) - ), + "alphaj": InputVariable("physics", float, range=(0.0, 10.0)), + "alphan": InputVariable("physics", float, range=(0.0, 10.0)), + "alphat": InputVariable("physics", float, range=(0.0, 10.0)), + "aspect": InputVariable("physics", float, range=(1.001, 40.0)), + "beamfus0": InputVariable("physics", float, range=(0.01, 10.0)), + "beta_total_vol_avg": InputVariable("physics", float, range=(0.0, 1.0)), + "beta_vol_avg_max": InputVariable("physics", float, range=(0.0, 1.0)), + "beta_vol_avg_min": InputVariable("physics", float, range=(0.0, 1.0)), + "betbm0": InputVariable("physics", float, range=(0.0, 10.0)), + "b_plasma_toroidal_on_axis": InputVariable("physics", float, range=(0.0, 30.0)), + "burnup_in": InputVariable("physics", float, range=(0.0, 1.0)), "radius_plasma_core_norm": InputVariable( "impurity_radiation", float, range=(0.0, 1.0) ), "f_p_plasma_core_rad_reduction": InputVariable( "impurity_radiation", float, range=(0.0, 1.0) ), - "c_beta": InputVariable(data_structure.physics_variables, float, range=(0.0, 1.0)), - "csawth": InputVariable(data_structure.physics_variables, float, range=(0.0, 10.0)), - "f_vol_plasma": InputVariable( - data_structure.physics_variables, float, range=(0.001, 10.0) - ), - "f_r_conducting_wall": InputVariable( - data_structure.physics_variables, float, range=(1.0, 3.0) - ), + "c_beta": InputVariable("physics", float, range=(0.0, 1.0)), + "csawth": InputVariable("physics", float, range=(0.0, 10.0)), + "f_vol_plasma": InputVariable("physics", float, range=(0.001, 10.0)), + "f_r_conducting_wall": InputVariable("physics", float, range=(1.0, 3.0)), "nd_plasma_electrons_vol_avg": InputVariable( - data_structure.physics_variables, float, range=(1.0e18, 1.0e22) - ), - "beta_norm_max": InputVariable( - data_structure.physics_variables, float, range=(0.0, 20.0) - ), - "beta_poloidal_eps_max": InputVariable( - data_structure.physics_variables, float, range=(0.01, 10.0) - ), - "f_p_alpha_plasma_deposited": InputVariable( - data_structure.physics_variables, float, range=(0.0, 1.0) - ), - "f_p_div_lower": InputVariable( - data_structure.physics_variables, float, range=(0.0, 1.0) - ), - "f_plasma_fuel_deuterium": InputVariable( - data_structure.physics_variables, float, range=(0.0, 1.0) - ), - "ffwal": InputVariable(data_structure.physics_variables, float, range=(0.0, 10.0)), - "f_nd_plasma_pedestal_greenwald": InputVariable( - data_structure.physics_variables, float, range=(-1.0, 5.0) - ), + "physics", float, range=(1.0e18, 1.0e22) + ), + "beta_norm_max": InputVariable("physics", float, range=(0.0, 20.0)), + "beta_poloidal_eps_max": InputVariable("physics", float, range=(0.01, 10.0)), + "f_p_alpha_plasma_deposited": InputVariable("physics", float, range=(0.0, 1.0)), + "f_p_div_lower": InputVariable("physics", float, range=(0.0, 1.0)), + "f_plasma_fuel_deuterium": InputVariable("physics", float, range=(0.0, 1.0)), + "ffwal": InputVariable("physics", float, range=(0.0, 10.0)), + "f_nd_plasma_pedestal_greenwald": InputVariable("physics", float, range=(-1.0, 5.0)), "f_nd_plasma_separatrix_greenwald": InputVariable( - data_structure.physics_variables, float, range=(-1.0, 5.0) - ), - "f_plasma_fuel_helium3": InputVariable( - data_structure.physics_variables, float, range=(-1.0, 5.0) + "physics", float, range=(-1.0, 5.0) ), + "f_plasma_fuel_helium3": InputVariable("physics", float, range=(-1.0, 5.0)), # TODO: does f_nd_impurity_electrons require an additional range? "f_nd_impurity_electrons": InputVariable("impurity_radiation", float, array=True), - "fkzohm": InputVariable(data_structure.physics_variables, float, range=(0.5, 2.0)), + "fkzohm": InputVariable("physics", float, range=(0.5, 2.0)), "abktflnc": InputVariable("costs", float, range=(0.1, 100.0)), "adivflnc": InputVariable("costs", float, range=(0.1, 100.0)), "admv": InputVariable("buildings", float, range=(1.0e4, 1.0e6)), @@ -401,9 +370,7 @@ def __post_init__(self): "eff_tf_cryo": InputVariable( data_structure.tfcoil_variables, float, range=(0.0, 1.0) ), - "ejima_coeff": InputVariable( - data_structure.physics_variables, float, range=(0.1, 1.0) - ), + "ejima_coeff": InputVariable("physics", float, range=(0.1, 1.0)), "elecdist_h": InputVariable("buildings", float, range=(1.0, 100.0)), "elecdist_l": InputVariable("buildings", float, range=(10.0, 1000.0)), "elecdist_w": InputVariable("buildings", float, range=(10.0, 1000.0)), @@ -462,25 +429,15 @@ def __post_init__(self): "f_asym": InputVariable("stellarator", float, range=(0.9, 2.0)), "f_fw_peak": InputVariable("fwbs", float, range=(1.0, 100.0)), "f_fw_rad_max": InputVariable("constraints", float, range=(0.1, 10)), - "f_nd_alpha_electron": InputVariable( - data_structure.physics_variables, float, range=(1e-12, 1.0) - ), - "f_nd_beam_electron": InputVariable( - data_structure.physics_variables, float, range=(0.0, 1.0) - ), - "f_nd_protium_electrons": InputVariable( - data_structure.physics_variables, float, range=(0.0, 1.0) - ), + "f_nd_alpha_electron": InputVariable("physics", float, range=(1e-12, 1.0)), + "f_nd_beam_electron": InputVariable("physics", float, range=(0.0, 1.0)), + "f_nd_protium_electrons": InputVariable("physics", float, range=(0.0, 1.0)), "f_neut_shield": InputVariable("fwbs", float, range=(0.0, 1.0)), "f_nuc_pow_bz_struct": InputVariable("fwbs", float, range=(0.0, 1.0)), "f_r_cp": InputVariable("build", float, range=(1.0, 100.0)), "f_rad": InputVariable("stellarator", float, range=(0.0, 1.0)), - "f_sync_reflect": InputVariable( - data_structure.physics_variables, float, range=(0.0, 1.0) - ), - "f_plasma_fuel_tritium": InputVariable( - data_structure.physics_variables, float, range=(0.0, 1.0) - ), + "f_sync_reflect": InputVariable("physics", float, range=(0.0, 1.0)), + "f_plasma_fuel_tritium": InputVariable("physics", float, range=(0.0, 1.0)), "f_beam_tritium": InputVariable("current_drive", float, range=(0.0, 1.0)), "f_vforce_inboard": InputVariable( data_structure.tfcoil_variables, float, range=(0.0, 1.0) @@ -560,9 +517,7 @@ def __post_init__(self): "fvoldw": InputVariable("fwbs", float, range=(0.0, 10.0)), "fvolsi": InputVariable("fwbs", float, range=(0.0, 10.0)), "fvolso": InputVariable("fwbs", float, range=(0.0, 10.0)), - "f_c_plasma_non_inductive": InputVariable( - data_structure.physics_variables, float, range=(0.0, 1.0) - ), + "f_c_plasma_non_inductive": InputVariable("physics", float, range=(0.0, 1.0)), "fw_armour_thickness": InputVariable("fwbs", float, range=(0.0, 1.0)), "fw_th_conductivity": InputVariable("fwbs", float, range=(1.0, 100.0)), "fwbs_nref": InputVariable("costs", float, range=(1000.0, 100000000.0)), @@ -596,7 +551,7 @@ def __post_init__(self): "heat_sink_h": InputVariable("buildings", float, range=(1.0, 100.0)), "heat_sink_l": InputVariable("buildings", float, range=(10.0, 1000.0)), "heat_sink_w": InputVariable("buildings", float, range=(10.0, 1000.0)), - "hfact": InputVariable(data_structure.physics_variables, float, range=(0.01, 10.0)), + "hfact": InputVariable("physics", float, range=(0.01, 10.0)), "pflux_div_heat_load_mw": InputVariable("divertor", float, range=(0.0, 10.0)), "pflux_div_heat_load_max_mw": InputVariable("divertor", float, range=(0.1, 20.0)), "hot_sepdist": InputVariable("buildings", float, range=(0.0, 10.0)), @@ -619,9 +574,7 @@ def __post_init__(self): "ilw_storage_h": InputVariable("buildings", float, range=(1.0, 100.0)), "ilw_storage_l": InputVariable("buildings", float, range=(10.0, 1000.0)), "ilw_storage_w": InputVariable("buildings", float, range=(10.0, 1000.0)), - "ind_plasma_internal_norm": InputVariable( - data_structure.physics_variables, float, range=(0.0, 10.0) - ), + "ind_plasma_internal_norm": InputVariable("physics", float, range=(0.0, 10.0)), "pres_vv_chamber_dwell_start": InputVariable( "vacuum", float, range=(1e-06, 10000.0) ), @@ -631,8 +584,8 @@ def __post_init__(self): "j_tf_bus": InputVariable( data_structure.tfcoil_variables, float, range=(10000.0, 100000000.0) ), - "kappa": InputVariable(data_structure.physics_variables, float, range=(0.99, 5.0)), - "kappa95": InputVariable(data_structure.physics_variables, float, range=(0.99, 5.0)), + "kappa": InputVariable("physics", float, range=(0.99, 5.0)), + "kappa95": InputVariable("physics", float, range=(0.99, 5.0)), "layer_ins": InputVariable(data_structure.tfcoil_variables, float, range=(0.0, 0.1)), "f_dr_dz_cs_turn": InputVariable("pf_coil", float, range=(0.0, 5.0)), "len_fw_channel": InputVariable("fwbs", float, range=(0.001, 1000.0)), @@ -645,9 +598,7 @@ def __post_init__(self): "llw_storage_h": InputVariable("buildings", float, range=(1.0, 100.0)), "llw_storage_l": InputVariable("buildings", float, range=(10.0, 1000.0)), "llw_storage_w": InputVariable("buildings", float, range=(10.0, 1000.0)), - "m_s_limit": InputVariable( - data_structure.physics_variables, float, range=(0.0, 1.0) - ), + "m_s_limit": InputVariable("physics", float, range=(0.0, 1.0)), "magnet_pulse_h": InputVariable("buildings", float, range=(1.0, 100.0)), "magnet_pulse_l": InputVariable("buildings", float, range=(10.0, 1000.0)), "magnet_pulse_w": InputVariable("buildings", float, range=(10.0, 1000.0)), @@ -685,12 +636,8 @@ def __post_init__(self): "f_p_beam_shine_through_max": InputVariable( "constraints", float, range=(1e-20, 0.1) ), - "nd_plasma_pedestal_electron": InputVariable( - data_structure.physics_variables, float, range=(0.0, 1e21) - ), - "nd_plasma_separatrix_electron": InputVariable( - data_structure.physics_variables, float, range=(0.0, 1e21) - ), + "nd_plasma_pedestal_electron": InputVariable("physics", float, range=(0.0, 1e21)), + "nd_plasma_separatrix_electron": InputVariable("physics", float, range=(0.0, 1e21)), "nflutfmax": InputVariable("constraints", float, range=(0.0, 1e24)), "oacdcp": InputVariable( data_structure.tfcoil_variables, float, range=(10000.0, 1000000000.0) @@ -724,12 +671,8 @@ def __post_init__(self): "p_hcd_secondary_injected_mw": InputVariable( "current_drive", float, range=(0.0, 1000.0) ), - "plasma_res_factor": InputVariable( - data_structure.physics_variables, float, range=(0.0, 1.0) - ), - "plasma_square": InputVariable( - data_structure.physics_variables, float, range=(-5.0, 5.0) - ), + "plasma_res_factor": InputVariable("physics", float, range=(0.0, 1.0)), + "plasma_square": InputVariable("physics", float, range=(-5.0, 5.0)), "plleni": InputVariable("build", float, range=(0.1, 10.0)), "plleno": InputVariable("build", float, range=(0.1, 10.0)), "plsepi": InputVariable("build", float, range=(0.1, 10.0)), @@ -768,15 +711,13 @@ def __post_init__(self): "pflux_plant_floor_electric": InputVariable( "heat_transport", float, range=(0.0, 1000.0) ), - "q0": InputVariable(data_structure.physics_variables, float, range=(0.01, 20.0)), - "q95": InputVariable(data_structure.physics_variables, float, range=(1.0, 50.0)), + "q0": InputVariable("physics", float, range=(0.01, 20.0)), + "q95": InputVariable("physics", float, range=(1.0, 50.0)), "q95_fixed": InputVariable("constraints", float, range=(1.0, 50.0)), "qnty_sfty_fac": InputVariable("buildings", float, range=(0.0, 10.0)), "qnuc": InputVariable("fwbs", float, range=(0.0, 1000000.0)), "r_cp_top": InputVariable("build", float, range=(0.001, 10.0)), - "rad_fraction_sol": InputVariable( - data_structure.physics_variables, float, range=(0.0, 1.0) - ), + "rad_fraction_sol": InputVariable("physics", float, range=(0.0, 1.0)), "radius_fw_channel": InputVariable("fwbs", float, range=(0.001, 0.5)), "outgrat_fw": InputVariable("vacuum", float, range=(1e-10, 1e-06)), "rbrt": InputVariable("buildings", float, range=(0.0, 10.0)), @@ -817,17 +758,17 @@ def __post_init__(self): data_structure.tfcoil_variables, float, range=(0.0, 0.01) ), "radius_plasma_pedestal_density_norm": InputVariable( - data_structure.physics_variables, float, range=(0.01, 1.0) + "physics", float, range=(0.01, 1.0) ), "radius_plasma_pedestal_temp_norm": InputVariable( - data_structure.physics_variables, float, range=(0.01, 1.0) + "physics", float, range=(0.01, 1.0) ), "rhopfbus": InputVariable("pf_coil", float, range=(0.0, 1e-05)), "rinboard": InputVariable("build", float, range=(0.1, 10.0)), "ripple_b_tf_plasma_edge_max": InputVariable( data_structure.tfcoil_variables, float, range=(0.1, 100.0) ), - "rmajor": InputVariable(data_structure.physics_variables, float, range=(0.1, 50.0)), + "rmajor": InputVariable("physics", float, range=(0.1, 50.0)), "robotics_h": InputVariable("buildings", float, range=(1.0, 100.0)), "robotics_l": InputVariable("buildings", float, range=(10.0, 1000.0)), "robotics_w": InputVariable("buildings", float, range=(10.0, 1000.0)), @@ -923,19 +864,15 @@ def __post_init__(self): "dr_hts_tape": InputVariable( data_structure.rebco_variables, float, range=(0.0, 0.1) ), - "tauee_in": InputVariable( - data_structure.physics_variables, float, range=(0.0, 100.0) - ), + "tauee_in": InputVariable("physics", float, range=(0.0, 100.0)), "t_plasma_energy_confinement_max": InputVariable( - data_structure.physics_variables, float, range=(0.1, 100.0) - ), - "tauratio": InputVariable( - data_structure.physics_variables, float, range=(0.1, 100.0) + "physics", float, range=(0.1, 100.0) ), + "tauratio": InputVariable("physics", float, range=(0.1, 100.0)), "n_beam_decay_lengths_core_required": InputVariable( "current_drive", float, range=(0.0, 10.0) ), - "tbeta": InputVariable(data_structure.physics_variables, float, range=(0.0, 4.0)), + "tbeta": InputVariable("physics", float, range=(0.0, 4.0)), "t_blkt_replace_yrs": InputVariable("costs", float, range=(0.01, 2.0)), "tbrmin": InputVariable("constraints", float, range=(0.001, 2.0)), "tcomrepl": InputVariable("costs", float, range=(0.01, 2.0)), @@ -950,7 +887,7 @@ def __post_init__(self): data_structure.tfcoil_variables, float, range=(0.1, 100.0) ), "temp_plasma_electron_vol_avg_kev": InputVariable( - data_structure.physics_variables, float, range=(1.0, 200.0) + "physics", float, range=(1.0, 200.0) ), "te0_ecrh_achievable": InputVariable("stellarator", float, range=(1.0, 1000.0)), "temp_cp_average": InputVariable( @@ -959,12 +896,8 @@ def __post_init__(self): "temp_fw_coolant_in": InputVariable("fwbs", float, range=(300.0, 1500.0)), "temp_fw_coolant_out": InputVariable("fwbs", float, range=(300.0, 1500.0)), "temp_fw_max": InputVariable("fwbs", float, range=(500.0, 2000.0)), - "temp_plasma_pedestal_kev": InputVariable( - data_structure.physics_variables, float, range=(0.0, 20.0) - ), - "temp_plasma_separatrix_kev": InputVariable( - data_structure.physics_variables, float, range=(0.0, 20.0) - ), + "temp_plasma_pedestal_kev": InputVariable("physics", float, range=(0.0, 20.0)), + "temp_plasma_separatrix_kev": InputVariable("physics", float, range=(0.0, 20.0)), "tfcbv": InputVariable("buildings", float, range=(10000.0, 1000000.0)), "dx_tf_wp_insertion_gap": InputVariable( data_structure.tfcoil_variables, float, range=(1e-10, 0.1) @@ -991,9 +924,7 @@ def __post_init__(self): "dx_tf_turn_steel": InputVariable( data_structure.tfcoil_variables, float, range=(0.0, 0.1) ), - "temp_plasma_ion_vol_avg_kev": InputVariable( - data_structure.physics_variables, float, range=(5.0, 50.0) - ), + "temp_plasma_ion_vol_avg_kev": InputVariable("physics", float, range=(5.0, 50.0)), "dx_tf_wp_insulation": InputVariable( data_structure.tfcoil_variables, float, range=(0.0, 0.1) ), @@ -1018,12 +949,10 @@ def __post_init__(self): "temp_vv_chamber_gas_burn_end": InputVariable("vacuum", float, range=(1.0, 1000.0)), "i_t_current_ramp_up": InputVariable("times", int, choices=[0, 1]), "transp_clrnc": InputVariable("buildings", float, range=(0.0, 10.0)), - "f_temp_plasma_ion_electron": InputVariable( - data_structure.physics_variables, float, range=(0.0, 2.0) - ), + "f_temp_plasma_ion_electron": InputVariable("physics", float, range=(0.0, 2.0)), "trcl": InputVariable("buildings", float, range=(0.0, 10.0)), - "triang": InputVariable(data_structure.physics_variables, float, range=(-1.0, 1.0)), - "triang95": InputVariable(data_structure.physics_variables, float, range=(0.0, 1.0)), + "triang": InputVariable("physics", float, range=(-1.0, 1.0)), + "triang95": InputVariable("physics", float, range=(0.0, 1.0)), "p_tritium_plant_electric_mw": InputVariable( "heat_transport", float, range=(0.0, 100.0) ), @@ -1151,59 +1080,33 @@ def __post_init__(self): "i_fw_blkt_vv_shape": InputVariable("fwbs", int, range=(1, 2)), "hcdportsize": InputVariable("fwbs", int, range=(1, 2)), "i_blkt_liquid_breeder_type": InputVariable("fwbs", int, choices=[0, 1]), - "i_beta_component": InputVariable( - data_structure.physics_variables, int, range=(0, 3) - ), - "i_beta_fast_alpha": InputVariable( - data_structure.physics_variables, int, choices=[0, 1] - ), + "i_beta_component": InputVariable("physics", int, range=(0, 3)), + "i_beta_fast_alpha": InputVariable("physics", int, choices=[0, 1]), "i_blanket_type": InputVariable("fwbs", int, choices=[1, 5]), "i_bldgs_size": InputVariable("buildings", int, choices=[0, 1]), "i_bldgs_v": InputVariable("buildings", int, choices=[0, 1]), "i_blkt_inboard": InputVariable("fwbs", int, choices=[0, 1]), - "i_bootstrap_current": InputVariable( - data_structure.physics_variables, int, range=(0, 13) - ), + "i_bootstrap_current": InputVariable("physics", int, range=(0, 13)), "i_cp_joints": InputVariable(data_structure.tfcoil_variables, int, choices=[0, 1]), "i_cp_lifetime": InputVariable("costs", int, range=(0, 3)), "i_cs_precomp": InputVariable("build", int, choices=[0, 1]), "i_cs_stress": InputVariable("pf_coil", int, choices=[0, 1]), - "i_density_limit": InputVariable( - data_structure.physics_variables, int, range=(1, 8) - ), - "i_diamagnetic_current": InputVariable( - data_structure.physics_variables, int, choices=[0, 1, 2] - ), + "i_density_limit": InputVariable("physics", int, range=(1, 8)), + "i_diamagnetic_current": InputVariable("physics", int, choices=[0, 1, 2]), "i_div_heat_load": InputVariable("divertor", int, choices=[0, 1, 2]), - "i_l_h_threshold": InputVariable( - data_structure.physics_variables, int, range=(1, 21) - ), + "i_l_h_threshold": InputVariable("physics", int, range=(1, 21)), "i_pf_current": InputVariable("pf_coil", int, choices=[0, 1, 2]), - "i_pfirsch_schluter_current": InputVariable( - data_structure.physics_variables, int, choices=[0, 1] - ), - "i_plasma_current": InputVariable( - data_structure.physics_variables, int, range=(1, 9) - ), - "i_plasma_geometry": InputVariable( - data_structure.physics_variables, int, range=(0, 12) - ), - "i_plasma_shape": InputVariable( - data_structure.physics_variables, int, choices=[0, 1] - ), - "i_plasma_wall_gap": InputVariable( - data_structure.physics_variables, int, choices=[0, 1] - ), + "i_pfirsch_schluter_current": InputVariable("physics", int, choices=[0, 1]), + "i_plasma_current": InputVariable("physics", int, range=(1, 9)), + "i_plasma_geometry": InputVariable("physics", int, range=(0, 12)), + "i_plasma_shape": InputVariable("physics", int, choices=[0, 1]), + "i_plasma_wall_gap": InputVariable("physics", int, choices=[0, 1]), "i_pulsed_plant": InputVariable("pulse", int, choices=[0, 1]), "i_q95_fixed": InputVariable("constraints", int, choices=[0, 1]), "i_r_cp_top": InputVariable("build", int, choices=[0, 1, 2]), - "i_rad_loss": InputVariable( - data_structure.physics_variables, int, choices=[0, 1, 2] - ), + "i_rad_loss": InputVariable("physics", int, choices=[0, 1, 2]), "i_shield_mat": InputVariable("fwbs", int, choices=[0, 1]), - "i_single_null": InputVariable( - data_structure.physics_variables, int, choices=[0, 1] - ), + "i_single_null": InputVariable("physics", int, choices=[0, 1]), "i_str_wp": InputVariable(data_structure.tfcoil_variables, int, choices=[0, 1]), "i_r_pf_outside_tf_placement": InputVariable("pf_coil", int, choices=[0, 1]), "i_tf_bucking": InputVariable(data_structure.tfcoil_variables, int, range=(0, 3)), @@ -1239,26 +1142,18 @@ def __post_init__(self): "ifedrv": InputVariable("ife", int, range=(-1, 3)), "ifetyp": InputVariable("ife", int, range=(0, 4)), "ifueltyp": InputVariable("costs", int, choices=[0, 1, 2]), - "i_plasma_ignited": InputVariable( - data_structure.physics_variables, int, choices=[0, 1] - ), + "i_plasma_ignited": InputVariable("physics", int, choices=[0, 1]), "i_blkt_module_segmentation": InputVariable("fwbs", int, choices=[0, 1]), "inuclear": InputVariable("fwbs", int, choices=[0, 1]), "iohcl": InputVariable("build", int, choices=[0, 1]), - "i_plasma_pedestal": InputVariable( - data_structure.physics_variables, int, choices=[0, 1] - ), + "i_plasma_pedestal": InputVariable("physics", int, choices=[0, 1]), "i_pf_conductor": InputVariable("pf_coil", int, choices=[0, 1]), "ipnet": InputVariable("costs", int, choices=[0, 1]), "ipowerflow": InputVariable("heat_transport", int, choices=[0, 1]), "i_shld_primary_heat": InputVariable("heat_transport", int, choices=[0, 1]), - "i_beta_norm_max": InputVariable( - data_structure.physics_variables, int, range=(0, 5) - ), - "i_ind_plasma_internal_norm": InputVariable( - data_structure.physics_variables, int, range=(0, 2) - ), - "i_alphaj": InputVariable(data_structure.physics_variables, int, range=(0, 1)), + "i_beta_norm_max": InputVariable("physics", int, range=(0, 5)), + "i_ind_plasma_internal_norm": InputVariable("physics", int, range=(0, 2)), + "i_alphaj": InputVariable("physics", int, range=(0, 1)), "i_fw_blkt_shared_coolant": InputVariable("fwbs", int, choices=[0, 1, 2]), "ireactor": InputVariable("costs", int, choices=[0, 1]), "irefprop": InputVariable("fwbs", int, choices=[0, 1]), @@ -1269,12 +1164,10 @@ def __post_init__(self): "istore": InputVariable("pulse", int, range=(1, 3)), "i_cs_superconductor": InputVariable("pf_coil", int, range=(1, 9)), "i_pf_superconductor": InputVariable("pf_coil", int, range=(1, 9)), - "itart": InputVariable(data_structure.physics_variables, int, choices=[0, 1]), - "itartpf": InputVariable(data_structure.physics_variables, int, choices=[0, 1]), + "itart": InputVariable("physics", int, choices=[0, 1]), + "itartpf": InputVariable("physics", int, choices=[0, 1]), "itcycl": InputVariable("pulse", int, range=(1, 3)), - "i_pflux_fw_neutron": InputVariable( - data_structure.physics_variables, int, range=(1, 2) - ), + "i_pflux_fw_neutron": InputVariable("physics", int, range=(1, 2)), "lsa": InputVariable("costs", int, range=(1, 4)), "m_res": InputVariable("stellarator", int, range=(1, 10)), "n_tf_wp_layers": InputVariable( @@ -1317,9 +1210,9 @@ def __post_init__(self): "i_tf_inside_cs": InputVariable("build", int, choices=[0, 1]), "i_ecrh_wave_mode": InputVariable("current_drive", int, choices=[0, 1]), "i_confinement_time": InputVariable( - data_structure.physics_variables, + "physics", int, - choices=list(range(data_structure.physics_variables.N_CONFINEMENT_SCALINGS)), + choices=list(range(N_CONFINEMENT_SCALINGS)), ), "quench_model": InputVariable( data_structure.tfcoil_variables, str, choices=["exponential", "linear"] diff --git a/process/core/io/plot/summary.py b/process/core/io/plot/summary.py index a0180e00c4..e658fb6724 100644 --- a/process/core/io/plot/summary.py +++ b/process/core/io/plot/summary.py @@ -11912,7 +11912,7 @@ def plot_max_normalised_beta_comparison(axis: plt.Axes, mfile: MFile, scan: int) f"{BetaNormMaxModel.WESSON.full_name}": beta_norm_max_wesson, f"{BetaNormMaxModel.ORIGINAL_SCALING.full_name}": beta_norm_max_original_scaling, f"{BetaNormMaxModel.MENARD.full_name}": beta_norm_max_menard, - f"{BetaNormMaxModel.THLOREUS.full_name}": beta_norm_max_thloreus, + f"{BetaNormMaxModel.THOLERUS.full_name}": beta_norm_max_thloreus, f"{BetaNormMaxModel.STAMBAUGH.full_name}": beta_norm_max_stambaugh, } diff --git a/process/core/model.py b/process/core/model.py index 1277717e7d..84ea9b1baa 100644 --- a/process/core/model.py +++ b/process/core/model.py @@ -20,6 +20,7 @@ from process.data_structure.neoclassics_variables import NeoclassicsData from process.data_structure.pf_power_variables import PFPowerData from process.data_structure.pfcoil_variables import PFCoilData +from process.data_structure.physics_variables import PhysicsData from process.data_structure.power_variables import PowerData from process.data_structure.primary_pumping_variables import PrimaryPumpingData from process.data_structure.pulse_variables import PulseData @@ -65,6 +66,7 @@ class DataStructure: pf_power: PFPowerData = initialise_later neoclassics: NeoclassicsData = initialise_later impurity_radiation: ImpurityRadiationData = initialise_later + physics: PhysicsData = initialise_later def __post_init__(self): for f in fields(self): diff --git a/process/core/output.py b/process/core/output.py index 83435cca66..f9ca0d5e12 100644 --- a/process/core/output.py +++ b/process/core/output.py @@ -95,7 +95,7 @@ def write(models, data, _outfile): # Tight aspect ratio machine model if ( - data_structure.physics_variables.itart == 1 + data.physics.itart == 1 and data_structure.tfcoil_variables.i_tf_sup != TFConductorModel.SUPERCONDUCTING ): models.tfcoil.output() diff --git a/process/core/scan.py b/process/core/scan.py index 87cf5cff6e..1d08e034c1 100644 --- a/process/core/scan.py +++ b/process/core/scan.py @@ -18,7 +18,6 @@ from process.data_structure import ( global_variables, numerics, - physics_variables, rebco_variables, scan_variables, tfcoil_variables, @@ -1068,31 +1067,31 @@ def scan_1d_write_plot(self): def scan_select(self, nwp, swp, iscn): match nwp: case 1: - physics_variables.aspect = swp[iscn - 1] + self.data.physics.aspect = swp[iscn - 1] case 2: self.data.divertor.pflux_div_heat_load_max_mw = swp[iscn - 1] case 3: self.data.constraints.p_plant_electric_net_required_mw = swp[iscn - 1] case 4: - physics_variables.hfact = swp[iscn - 1] + self.data.physics.hfact = swp[iscn - 1] case 5: tfcoil_variables.oacdcp = swp[iscn - 1] case 6: self.data.constraints.pflux_fw_neutron_max_mw = swp[iscn - 1] case 7: - physics_variables.beamfus0 = swp[iscn - 1] + self.data.physics.beamfus0 = swp[iscn - 1] case 9: - physics_variables.temp_plasma_electron_vol_avg_kev = swp[iscn - 1] + self.data.physics.temp_plasma_electron_vol_avg_kev = swp[iscn - 1] case 10: numerics.boundu[14] = swp[iscn - 1] case 11: - physics_variables.beta_norm_max = swp[iscn - 1] + self.data.physics.beta_norm_max = swp[iscn - 1] case 12: self.data.current_drive.f_c_plasma_bootstrap_max = swp[iscn - 1] case 13: numerics.boundu[9] = swp[iscn - 1] case 16: - physics_variables.rmajor = swp[iscn - 1] + self.data.physics.rmajor = swp[iscn - 1] case 17: self.data.constraints.b_tf_inboard_max = swp[iscn - 1] case 18: @@ -1110,13 +1109,13 @@ def scan_select(self, nwp, swp, iscn): case 24: self.data.constraints.p_fusion_total_max_mw = swp[iscn - 1] case 25: - physics_variables.kappa = swp[iscn - 1] + self.data.physics.kappa = swp[iscn - 1] case 26: - physics_variables.triang = swp[iscn - 1] + self.data.physics.triang = swp[iscn - 1] case 27: self.data.constraints.tbrmin = swp[iscn - 1] case 28: - physics_variables.b_plasma_toroidal_on_axis = swp[iscn - 1] + self.data.physics.b_plasma_toroidal_on_axis = swp[iscn - 1] case 29: self.data.impurity_radiation.radius_plasma_core_norm = swp[iscn - 1] case 31: @@ -1152,9 +1151,9 @@ def scan_select(self, nwp, swp, iscn): self.data.impurity_radiation.f_nd_impurity_electrons[12] ) case 51: - physics_variables.f_p_div_lower = swp[iscn - 1] + self.data.physics.f_p_div_lower = swp[iscn - 1] case 52: - physics_variables.rad_fraction_sol = swp[iscn - 1] + self.data.physics.rad_fraction_sol = swp[iscn - 1] case 53: numerics.boundu[156] = swp[iscn - 1] case 54: diff --git a/process/core/solver/constraints.py b/process/core/solver/constraints.py index 624a1e64dc..086d4e3f37 100644 --- a/process/core/solver/constraints.py +++ b/process/core/solver/constraints.py @@ -192,7 +192,7 @@ def eq(value: float, bound: float, registration: ConstraintRegistration): @ConstraintManager.register_constraint(1, "", "=") -def constraint_equation_1(constraint_registration, _data): +def constraint_equation_1(constraint_registration, data): """Relationship between beta, temperature (keV) and density beta_total_vol_avg: total plasma beta @@ -207,20 +207,20 @@ def constraint_equation_1(constraint_registration, _data): return eq( # Density weighted temperature is used here as 〈nT〉 != 〈n〉_V * 〈T〉_V ( - data_structure.physics_variables.beta_fast_alpha - + data_structure.physics_variables.beta_beam + data.physics.beta_fast_alpha + + data.physics.beta_beam + 2.0e3 * constants.RMU0 * constants.ELECTRON_CHARGE * ( - data_structure.physics_variables.nd_plasma_electrons_vol_avg - * data_structure.physics_variables.temp_plasma_electron_density_weighted_kev - + data_structure.physics_variables.nd_plasma_ions_total_vol_avg - * data_structure.physics_variables.temp_plasma_ion_density_weighted_kev + data.physics.nd_plasma_electrons_vol_avg + * data.physics.temp_plasma_electron_density_weighted_kev + + data.physics.nd_plasma_ions_total_vol_avg + * data.physics.temp_plasma_ion_density_weighted_kev ) - / data_structure.physics_variables.b_plasma_total**2 + / data.physics.b_plasma_total**2 ), - data_structure.physics_variables.beta_total_vol_avg, + data.physics.beta_total_vol_avg, constraint_registration, ) @@ -253,34 +253,31 @@ def constraint_equation_2(constraint_registration, data): # pscaling: total transport power per volume (MW/m3) pscaling = ( - data_structure.physics_variables.pden_electron_transport_loss_mw - + data_structure.physics_variables.pden_ion_transport_loss_mw + data.physics.pden_electron_transport_loss_mw + + data.physics.pden_ion_transport_loss_mw ) # Total power lost is scaling power plus radiation: - if data_structure.physics_variables.i_rad_loss == 0: - pnumerator = pscaling + data_structure.physics_variables.pden_plasma_rad_mw - elif data_structure.physics_variables.i_rad_loss == 1: - pnumerator = pscaling + data_structure.physics_variables.pden_plasma_core_rad_mw + if data.physics.i_rad_loss == 0: + pnumerator = pscaling + data.physics.pden_plasma_rad_mw + elif data.physics.i_rad_loss == 1: + pnumerator = pscaling + data.physics.pden_plasma_core_rad_mw else: pnumerator = pscaling # if plasma not ignited include injected power - if data_structure.physics_variables.i_plasma_ignited == 0: + if data.physics.i_plasma_ignited == 0: pdenom = ( - data_structure.physics_variables.f_p_alpha_plasma_deposited - * data_structure.physics_variables.pden_alpha_total_mw - + data_structure.physics_variables.pden_non_alpha_charged_mw - + data_structure.physics_variables.pden_plasma_ohmic_mw - + data.current_drive.p_hcd_injected_total_mw - / data_structure.physics_variables.vol_plasma + data.physics.f_p_alpha_plasma_deposited * data.physics.pden_alpha_total_mw + + data.physics.pden_non_alpha_charged_mw + + data.physics.pden_plasma_ohmic_mw + + data.current_drive.p_hcd_injected_total_mw / data.physics.vol_plasma ) else: # if plasma ignited pdenom = ( - data_structure.physics_variables.f_p_alpha_plasma_deposited - * data_structure.physics_variables.pden_alpha_total_mw - + data_structure.physics_variables.pden_non_alpha_charged_mw - + data_structure.physics_variables.pden_plasma_ohmic_mw + data.physics.f_p_alpha_plasma_deposited * data.physics.pden_alpha_total_mw + + data.physics.pden_non_alpha_charged_mw + + data.physics.pden_plasma_ohmic_mw ) return eq(pnumerator, pdenom, constraint_registration) @@ -301,17 +298,16 @@ def constraint_equation_3(constraint_registration, data): vol_plasma: plasma volume (m3) """ # No assume plasma ignition: - if data_structure.physics_variables.i_plasma_ignited == 0: + if data.physics.i_plasma_ignited == 0: return eq( ( - data_structure.physics_variables.pden_ion_transport_loss_mw - + data_structure.physics_variables.pden_ion_electron_equilibration_mw + data.physics.pden_ion_transport_loss_mw + + data.physics.pden_ion_electron_equilibration_mw ), ( - data_structure.physics_variables.f_p_alpha_plasma_deposited - * data_structure.physics_variables.f_pden_alpha_ions_mw - + data.current_drive.p_hcd_injected_ions_mw - / data_structure.physics_variables.vol_plasma + data.physics.f_p_alpha_plasma_deposited + * data.physics.f_pden_alpha_ions_mw + + data.current_drive.p_hcd_injected_ions_mw / data.physics.vol_plasma ), constraint_registration, ) @@ -319,13 +315,10 @@ def constraint_equation_3(constraint_registration, data): # Plasma ignited return eq( ( - data_structure.physics_variables.pden_ion_transport_loss_mw - + data_structure.physics_variables.pden_ion_electron_equilibration_mw - ), - ( - data_structure.physics_variables.f_p_alpha_plasma_deposited - * data_structure.physics_variables.f_pden_alpha_ions_mw + data.physics.pden_ion_transport_loss_mw + + data.physics.pden_ion_electron_equilibration_mw ), + (data.physics.f_p_alpha_plasma_deposited * data.physics.f_pden_alpha_ions_mw), constraint_registration, ) @@ -355,30 +348,29 @@ def constraint_equation_4(constraint_registration, data): """ # pscaling: total transport power per volume (MW/m3) - pscaling = data_structure.physics_variables.pden_electron_transport_loss_mw + pscaling = data.physics.pden_electron_transport_loss_mw # Total power lost is scaling power plus radiation: - if data_structure.physics_variables.i_rad_loss == 0: - pnumerator = pscaling + data_structure.physics_variables.pden_plasma_rad_mw - elif data_structure.physics_variables.i_rad_loss == 1: - pnumerator = pscaling + data_structure.physics_variables.pden_plasma_core_rad_mw + if data.physics.i_rad_loss == 0: + pnumerator = pscaling + data.physics.pden_plasma_rad_mw + elif data.physics.i_rad_loss == 1: + pnumerator = pscaling + data.physics.pden_plasma_core_rad_mw else: pnumerator = pscaling # if plasma not ignited include injected power - if data_structure.physics_variables.i_plasma_ignited == 0: + if data.physics.i_plasma_ignited == 0: pdenom = ( - data_structure.physics_variables.f_p_alpha_plasma_deposited - * data_structure.physics_variables.f_pden_alpha_electron_mw - + data_structure.physics_variables.pden_ion_electron_equilibration_mw - + data.current_drive.p_hcd_injected_electrons_mw - / data_structure.physics_variables.vol_plasma + data.physics.f_p_alpha_plasma_deposited + * data.physics.f_pden_alpha_electron_mw + + data.physics.pden_ion_electron_equilibration_mw + + data.current_drive.p_hcd_injected_electrons_mw / data.physics.vol_plasma ) else: # if plasma ignited pdenom = ( - data_structure.physics_variables.f_p_alpha_plasma_deposited - * data_structure.physics_variables.f_pden_alpha_electron_mw - + data_structure.physics_variables.pden_ion_electron_equilibration_mw + data.physics.f_p_alpha_plasma_deposited + * data.physics.f_pden_alpha_electron_mw + + data.physics.pden_ion_electron_equilibration_mw ) return eq(pnumerator, pdenom, constraint_registration) @@ -407,28 +399,22 @@ def constraint_equation_5(constraint_registration, data): (Except when i_density_limit=7 when nd_plasma_electron_line is used, not nd_plasma_electrons_vol_avg) """ # Apply Greenwald limit to line-averaged density - if data_structure.physics_variables.i_density_limit == 7: + if data.physics.i_density_limit == 7: return leq( - data_structure.physics_variables.nd_plasma_electron_line, - ( - data_structure.physics_variables.nd_plasma_electrons_max - * data.constraints.fdene - ), + data.physics.nd_plasma_electron_line, + (data.physics.nd_plasma_electrons_max * data.constraints.fdene), constraint_registration, ) return leq( - data_structure.physics_variables.nd_plasma_electrons_vol_avg, - ( - data_structure.physics_variables.nd_plasma_electrons_max - * data.constraints.fdene - ), + data.physics.nd_plasma_electrons_vol_avg, + (data.physics.nd_plasma_electrons_max * data.constraints.fdene), constraint_registration, ) @ConstraintManager.register_constraint(6, "", "<=") -def constraint_equation_6(constraint_registration, _data): +def constraint_equation_6(constraint_registration, data): """Equation for epsilon beta-poloidal upper limit beta_poloidal_eps_max: maximum (eps*beta_poloidal) @@ -436,17 +422,14 @@ def constraint_equation_6(constraint_registration, _data): beta_poloidal: poloidal beta """ return leq( - ( - data_structure.physics_variables.eps - * data_structure.physics_variables.beta_poloidal_vol_avg - ), - data_structure.physics_variables.beta_poloidal_eps_max, + (data.physics.eps * data.physics.beta_poloidal_vol_avg), + data.physics.beta_poloidal_eps_max, constraint_registration, ) @ConstraintManager.register_constraint(7, "/m³", "=") -def constraint_equation_7(constraint_registration, _data): +def constraint_equation_7(constraint_registration, data): """Equation for hot beam ion density i_plasma_ignited: switch for ignition assumption: @@ -459,12 +442,12 @@ def constraint_equation_7(constraint_registration, _data): nd_beam_ions_out: hot beam ion density from calculation (/m³) nd_beam_ions: hot beam ion density, variable (/m³) """ - if data_structure.physics_variables.i_plasma_ignited == 1: + if data.physics.i_plasma_ignited == 1: raise ProcessValueError("Do not use constraint equation 7 if i_plasma_ignited=1") return eq( - data_structure.physics_variables.nd_beam_ions_out, - data_structure.physics_variables.nd_beam_ions, + data.physics.nd_beam_ions_out, + data.physics.nd_beam_ions, constraint_registration, ) @@ -477,7 +460,7 @@ def constraint_equation_8(constraint_registration, data): pflux_fw_neutron_mw: average neutron wall load (MW/m²) """ return leq( - data_structure.physics_variables.pflux_fw_neutron_mw, + data.physics.pflux_fw_neutron_mw, data.constraints.pflux_fw_neutron_max_mw, constraint_registration, ) @@ -491,7 +474,7 @@ def constraint_equation_9(constraint_registration, data): p_fusion_total_mw: fusion power (MW) """ return leq( - data_structure.physics_variables.p_fusion_total_mw, + data.physics.p_fusion_total_mw, data.constraints.p_fusion_total_max_mw, constraint_registration, ) @@ -506,7 +489,7 @@ def constraint_equation_11(constraint_registration, data): """ return eq( data.build.rbld, - data_structure.physics_variables.rmajor, + data.physics.rmajor, constraint_registration, ) @@ -522,7 +505,7 @@ def constraint_equation_12(constraint_registration, data): # vs_cs_pf_total_pulse is negative, requires sign change return geq( -data.pf_coil.vs_cs_pf_total_pulse, - data_structure.physics_variables.vs_plasma_total_required, + data.physics.vs_plasma_total_required, constraint_registration, ) @@ -570,11 +553,8 @@ def constraint_equation_15(constraint_registration, data): p_plasma_separatrix_mw is at least 1.2*p_l_h_threshold_mw (ie in H-mode). """ return geq( - data_structure.physics_variables.p_plasma_separatrix_mw, - ( - data_structure.physics_variables.p_l_h_threshold_mw - * data.constraints.f_h_mode_margin - ), + data.physics.p_plasma_separatrix_mw, + (data.physics.p_l_h_threshold_mw * data.constraints.f_h_mode_margin), constraint_registration, ) @@ -612,16 +592,14 @@ def constraint_equation_17(constraint_registration, data): """ # Maximum possible power/vol_plasma that can be radiated (local) pradmaxpv = ( - data.current_drive.p_hcd_injected_total_mw - / data_structure.physics_variables.vol_plasma - + data_structure.physics_variables.pden_alpha_total_mw - * data_structure.physics_variables.f_p_alpha_plasma_deposited - + data_structure.physics_variables.pden_non_alpha_charged_mw - + data_structure.physics_variables.pden_plasma_ohmic_mw + data.current_drive.p_hcd_injected_total_mw / data.physics.vol_plasma + + data.physics.pden_alpha_total_mw * data.physics.f_p_alpha_plasma_deposited + + data.physics.pden_non_alpha_charged_mw + + data.physics.pden_plasma_ohmic_mw ) return leq( - data_structure.physics_variables.pden_plasma_rad_mw / pradmaxpv, + data.physics.pden_plasma_rad_mw / pradmaxpv, data.constraints.fradpwr, constraint_registration, ) @@ -679,7 +657,7 @@ def constraint_equation_21(constraint_registration, data): aplasmin: minimum minor radius (m) """ return geq( - data_structure.physics_variables.rminor, + data.physics.rminor, data.build.aplasmin, constraint_registration, ) @@ -700,11 +678,8 @@ def constraint_equation_22(constraint_registration, data): p_l_h_threshold_mw is at least 1.2*p_plasma_separatrix_mw (ie in L-mode). """ return geq( - data_structure.physics_variables.p_l_h_threshold_mw, - ( - data.constraints.f_l_mode_margin - * data_structure.physics_variables.p_plasma_separatrix_mw - ), + data.physics.p_l_h_threshold_mw, + (data.constraints.f_l_mode_margin * data.physics.p_plasma_separatrix_mw), constraint_registration, ) @@ -721,17 +696,14 @@ def constraint_equation_23(constraint_registration, data): """ # conducting shell radius (m) rcw = ( - data_structure.physics_variables.rminor + data.physics.rminor + data.build.dr_fw_plasma_gap_outboard + data.build.dr_fw_outboard + data.build.dr_blkt_outboard ) return leq( rcw, - ( - data_structure.physics_variables.f_r_conducting_wall - * data_structure.physics_variables.rminor - ), + (data.physics.f_r_conducting_wall * data.physics.rminor), constraint_registration, ) @@ -757,44 +729,30 @@ def constraint_equation_24(constraint_registration, data): """ # Include all beta components: relevant for both tokamaks and stellarators if ( - data_structure.physics_variables.i_beta_component == BetaComponentLimits.TOTAL + data.physics.i_beta_component == BetaComponentLimits.TOTAL or data.stellarator.istell != 0 ): - value = data_structure.physics_variables.beta_total_vol_avg + value = data.physics.beta_total_vol_avg # Here, the beta limit applies to only the thermal component, not the fast alpha or neutral beam parts - elif ( - data_structure.physics_variables.i_beta_component == BetaComponentLimits.THERMAL - ): + elif data.physics.i_beta_component == BetaComponentLimits.THERMAL: value = ( - data_structure.physics_variables.beta_total_vol_avg - - data_structure.physics_variables.beta_fast_alpha - - data_structure.physics_variables.beta_beam + data.physics.beta_total_vol_avg + - data.physics.beta_fast_alpha + - data.physics.beta_beam ) # Beta limit applies to thermal + neutral beam: components of the total beta, i.e. excludes alphas - elif ( - data_structure.physics_variables.i_beta_component - == BetaComponentLimits.THERMAL_AND_BEAM - ): - value = ( - data_structure.physics_variables.beta_total_vol_avg - - data_structure.physics_variables.beta_fast_alpha - ) + elif data.physics.i_beta_component == BetaComponentLimits.THERMAL_AND_BEAM: + value = data.physics.beta_total_vol_avg - data.physics.beta_fast_alpha # Beta limit applies to toroidal beta - elif ( - data_structure.physics_variables.i_beta_component == BetaComponentLimits.TOROIDAL - ): + elif data.physics.i_beta_component == BetaComponentLimits.TOROIDAL: value = ( - data_structure.physics_variables.beta_total_vol_avg - * ( - data_structure.physics_variables.b_plasma_total - / data_structure.physics_variables.b_plasma_toroidal_on_axis - ) - ** 2 + data.physics.beta_total_vol_avg + * (data.physics.b_plasma_total / data.physics.b_plasma_toroidal_on_axis) ** 2 ) return leq( value, - data_structure.physics_variables.beta_vol_avg_max, + data.physics.beta_vol_avg_max, constraint_registration, ) @@ -857,7 +815,7 @@ def constraint_equation_28(constraint_registration, data): during plasma start-up, and is excluded from all steady-state power balance calculations. """ - if data_structure.physics_variables.i_plasma_ignited != 0: + if data.physics.i_plasma_ignited != 0: raise ProcessValueError("Do not use constraint 28 if i_plasma_ignited=1") return geq( @@ -876,10 +834,7 @@ def constraint_equation_29(constraint_registration, data): rinboard: plasma inboard radius (m) """ return eq( - ( - data_structure.physics_variables.rmajor - - data_structure.physics_variables.rminor - ), + (data.physics.rmajor - data.physics.rminor), data.build.rinboard, constraint_registration, ) @@ -1071,7 +1026,7 @@ def constraint_equation_42(constraint_registration, data): @ConstraintManager.register_constraint(43, "deg C", "=") -def constraint_equation_43(constraint_registration, _data): +def constraint_equation_43(constraint_registration, data): """Equation for average centrepost temperature: This is a consistency equation (TART) temp_cp_average: average temp of TF coil inboard leg conductor (C)e @@ -1080,7 +1035,7 @@ def constraint_equation_43(constraint_registration, _data): - 0 use conventional aspect ratio models; - 1 use spherical tokamak models """ - if data_structure.physics_variables.itart == 0: + if data.physics.itart == 0: raise ProcessValueError("Do not use constraint 43 if itart=0") if data_structure.tfcoil_variables.i_tf_sup == TFConductorModel.WATER_COOLED_COPPER: @@ -1094,7 +1049,7 @@ def constraint_equation_43(constraint_registration, _data): @ConstraintManager.register_constraint(44, "deg C", "<=") -def constraint_equation_44(constraint_registration, _data): +def constraint_equation_44(constraint_registration, data): """Equation for centrepost temperature upper limit (TART) temp_cp_max: maximum peak centrepost temperature (K) @@ -1103,7 +1058,7 @@ def constraint_equation_44(constraint_registration, _data): - 0: use conventional aspect ratio models; - 1: use spherical tokamak models """ - if data_structure.physics_variables.itart == 0: + if data.physics.itart == 0: raise ProcessValueError("Do not use constraint 44 if itart=0") if ( @@ -1119,7 +1074,7 @@ def constraint_equation_44(constraint_registration, _data): @ConstraintManager.register_constraint(45, "", ">=") -def constraint_manager_45(constraint_registration, _data): +def constraint_manager_45(constraint_registration, data): """Equation for edge safety factor lower limit (TART) q95 : safety factor 'near' plasma edge @@ -1129,18 +1084,18 @@ def constraint_manager_45(constraint_registration, _data): - 0 use conventional aspect ratio models; - 1 use spherical tokamak models """ - if data_structure.physics_variables.itart == 0: + if data.physics.itart == 0: raise ProcessValueError("Do not use constraint 45 if itart=0") return geq( - data_structure.physics_variables.q95, - data_structure.physics_variables.q95_min, + data.physics.q95, + data.physics.q95_min, constraint_registration, ) @ConstraintManager.register_constraint(46, "", "<=") -def constraint_equation_46(constraint_registration, _data): +def constraint_equation_46(constraint_registration, data): """Equation for Iₚ/I_rod upper limit (TART) eps: inverse aspect ratio @@ -1150,17 +1105,14 @@ def constraint_equation_46(constraint_registration, _data): - 0: use conventional aspect ratio models; - 1: use spherical tokamak models """ - if data_structure.physics_variables.itart == 0: + if data.physics.itart == 0: raise ProcessValueError("Do not use constraint 46 if itart=0") # maximum ratio of plasma current to centrepost current - cratmx = 1.0 + 4.91 * (data_structure.physics_variables.eps - 0.62) + cratmx = 1.0 + 4.91 * (data.physics.eps - 0.62) return leq( - ( - data_structure.physics_variables.plasma_current - / data_structure.tfcoil_variables.c_tf_total - ), + (data.physics.plasma_current / data_structure.tfcoil_variables.c_tf_total), cratmx, constraint_registration, ) @@ -1174,7 +1126,7 @@ def constraint_equation_48(constraint_registration, data): beta_poloidal: poloidal beta """ return leq( - data_structure.physics_variables.beta_poloidal_vol_avg, + data.physics.beta_poloidal_vol_avg, data.constraints.beta_poloidal_max, constraint_registration, ) @@ -1198,7 +1150,7 @@ def constraint_equation_51(constraint_registration, data): vs_cs_pf_total_ramp: total flux swing for startup (Wb) """ return eq( - abs(data_structure.physics_variables.vs_plasma_ramp_required), + abs(data.physics.vs_plasma_ramp_required), data.pf_coil.vs_cs_pf_total_ramp, constraint_registration, ) @@ -1262,10 +1214,7 @@ def constraint_equation_56(constraint_registration, data): rmajor: plasma major radius (m) """ return leq( - ( - data_structure.physics_variables.p_plasma_separatrix_mw - / data_structure.physics_variables.rmajor - ), + (data.physics.p_plasma_separatrix_mw / data.physics.rmajor), data.constraints.pseprmax, constraint_registration, ) @@ -1322,8 +1271,7 @@ def constraint_equation_62(constraint_registration, data): f_alpha_energy_confinement_min: Lower limit on f_alpha_energy_confinement the ratio of alpha particle to energy confinement times """ return geq( - data_structure.physics_variables.t_alpha_confinement - / data_structure.physics_variables.t_energy_confinement, + data.physics.t_alpha_confinement / data.physics.t_energy_confinement, data.constraints.f_alpha_energy_confinement_min, constraint_registration, ) @@ -1351,7 +1299,7 @@ def constraint_equation_64(constraint_registration, data): n_charge_plasma_effective_vol_avg: plasma effective charge """ return leq( - data_structure.physics_variables.n_charge_plasma_effective_vol_avg, + data.physics.n_charge_plasma_effective_vol_avg, data.constraints.zeff_max, constraint_registration, ) @@ -1416,13 +1364,13 @@ def constraint_equation_68(constraint_registration, data): return leq( ( ( - data_structure.physics_variables.p_plasma_separatrix_mw - * data_structure.physics_variables.b_plasma_toroidal_on_axis + data.physics.p_plasma_separatrix_mw + * data.physics.b_plasma_toroidal_on_axis ) / ( data.constraints.q95_fixed - * data_structure.physics_variables.aspect - * data_structure.physics_variables.rmajor + * data.physics.aspect + * data.physics.rmajor ) ), data.constraints.psepbqarmax, @@ -1432,14 +1380,10 @@ def constraint_equation_68(constraint_registration, data): return leq( ( ( - data_structure.physics_variables.p_plasma_separatrix_mw - * data_structure.physics_variables.b_plasma_toroidal_on_axis - ) - / ( - data_structure.physics_variables.q95 - * data_structure.physics_variables.aspect - * data_structure.physics_variables.rmajor + data.physics.p_plasma_separatrix_mw + * data.physics.b_plasma_toroidal_on_axis ) + / (data.physics.q95 * data.physics.aspect * data.physics.rmajor) ), data.constraints.psepbqarmax, constraint_registration, @@ -1497,11 +1441,8 @@ def constraint_equation_73(constraint_registration, data): p_hcd_injected_total_mw : inout real : total auxiliary injected power (MW) """ return geq( - data_structure.physics_variables.p_plasma_separatrix_mw, - ( - data_structure.physics_variables.p_l_h_threshold_mw - + data.current_drive.p_hcd_injected_total_mw - ), + data.physics.p_plasma_separatrix_mw, + (data.physics.p_l_h_threshold_mw + data.current_drive.p_hcd_injected_total_mw), constraint_registration, ) @@ -1537,7 +1478,7 @@ def constraint_equation_75(constraint_registration, _data): @ConstraintManager.register_constraint(76, "/m³", "<=") -def constraint_equation_76(constraint_registration, _data): +def constraint_equation_76(constraint_registration, data): """Upper limit for Eich critical separatrix density model: Added for issue 558 Eich critical separatrix density model @@ -1552,24 +1493,21 @@ def constraint_equation_76(constraint_registration, _data): nd_plasma_electron_max_array(7)array : density limit [/m³] as calculated using various models """ # TODO: why on earth are these variables being set here!? Should they be local? - data_structure.physics_variables.alpha_crit = ( - data_structure.physics_variables.kappa**1.2 - ) * (1.0 + 1.5 * data_structure.physics_variables.triang) - data_structure.physics_variables.nd_plasma_separatrix_electron_eich_max = ( + data.physics.alpha_crit = (data.physics.kappa**1.2) * ( + 1.0 + 1.5 * data.physics.triang + ) + data.physics.nd_plasma_separatrix_electron_eich_max = ( 5.9 - * data_structure.physics_variables.alpha_crit - * (data_structure.physics_variables.aspect ** (-2.0 / 7.0)) - * (((1.0 + (data_structure.physics_variables.kappa**2.0)) / 2.0) ** (-6.0 / 7.0)) - * ( - (data_structure.physics_variables.p_plasma_separatrix_mw * 1.0e6) - ** (-11.0 / 70.0) - ) - * data_structure.physics_variables.nd_plasma_electron_max_array[6] + * data.physics.alpha_crit + * (data.physics.aspect ** (-2.0 / 7.0)) + * (((1.0 + (data.physics.kappa**2.0)) / 2.0) ** (-6.0 / 7.0)) + * ((data.physics.p_plasma_separatrix_mw * 1.0e6) ** (-11.0 / 70.0)) + * data.physics.nd_plasma_electron_max_array[6] ) return leq( - data_structure.physics_variables.nd_plasma_separatrix_electron, - data_structure.physics_variables.nd_plasma_separatrix_electron_eich_max, + data.physics.nd_plasma_separatrix_electron, + data.physics.nd_plasma_separatrix_electron_eich_max, constraint_registration, ) @@ -1633,14 +1571,14 @@ def constraint_equation_80(constraint_registration, data): p_plasma_separatrix_mw : input : Power crossing separatrix [MW] """ return geq( - data_structure.physics_variables.p_plasma_separatrix_mw, + data.physics.p_plasma_separatrix_mw, data.constraints.p_plasma_separatrix_min_mw, constraint_registration, ) @ConstraintManager.register_constraint(81, "/m³", ">=") -def constraint_equation_81(constraint_registration, _data): +def constraint_equation_81(constraint_registration, data): """Lower limit to ensure central density is larger that the pedestal one args : output structure : residual error; constraint value; @@ -1651,8 +1589,8 @@ def constraint_equation_81(constraint_registration, _data): nd_plasma_pedestal_electron : input : Electron density at pedestal [/m³] """ return geq( - data_structure.physics_variables.nd_plasma_electron_on_axis, - data_structure.physics_variables.nd_plasma_pedestal_electron, + data.physics.nd_plasma_electron_on_axis, + data.physics.nd_plasma_pedestal_electron, constraint_registration, ) @@ -1686,15 +1624,15 @@ def constraint_equation_83(constraint_registration, data): @ConstraintManager.register_constraint(84, "", ">=") -def constraint_equation_84(constraint_registration, _data): +def constraint_equation_84(constraint_registration, data): """Equation for the lower limit of beta beta_vol_avg_min: Lower limit for beta beta: plasma beta """ return geq( - data_structure.physics_variables.beta_total_vol_avg, - data_structure.physics_variables.beta_vol_avg_min, + data.physics.beta_total_vol_avg, + data.physics.beta_vol_avg_min, constraint_registration, ) @@ -1815,7 +1753,7 @@ def constraint_equation_91(constraint_registration, data): te0_ecrh_achievable: Max. achievable electron temperature at ignition point """ # Achievable ECRH te needs to be larger than needed te for igntion - if data_structure.physics_variables.i_plasma_ignited == 0: + if data.physics.i_plasma_ignited == 0: value = ( data.stellarator.powerht_constraint + data.current_drive.p_hcd_primary_extra_heat_mw @@ -1831,7 +1769,7 @@ def constraint_equation_91(constraint_registration, data): @ConstraintManager.register_constraint(92, "", "=") -def constraint_equation_92(constraint_registration, _data): +def constraint_equation_92(constraint_registration, data): """Equation for checking is D/T ratio is consistent, and sums to 1. f_plasma_fuel_deuterium: fraction of deuterium ions @@ -1839,9 +1777,9 @@ def constraint_equation_92(constraint_registration, _data): f_plasma_fuel_helium3: fraction of helium-3 ions """ return eq( - data_structure.physics_variables.f_plasma_fuel_deuterium - + data_structure.physics_variables.f_plasma_fuel_tritium - + data_structure.physics_variables.f_plasma_fuel_helium3, + data.physics.f_plasma_fuel_deuterium + + data.physics.f_plasma_fuel_tritium + + data.physics.f_plasma_fuel_helium3, 1.0, constraint_registration, ) diff --git a/process/core/solver/evaluators.py b/process/core/solver/evaluators.py index 85e0fc1dba..d892bb6e61 100644 --- a/process/core/solver/evaluators.py +++ b/process/core/solver/evaluators.py @@ -7,7 +7,6 @@ from process.core.model import DataStructure from process.data_structure import global_variables as gv from process.data_structure import numerics -from process.data_structure import physics_variables as pv logger = logging.getLogger(__name__) @@ -75,11 +74,11 @@ def fcnvmc1(self, _n, m, xv, ifail): logger.debug(f"{numerics.nviter = }") logger.debug(f"{(1 - (ifail % 7)) - 1 = }") logger.debug(f"{(numerics.nviter % 2) - 1 = }") - logger.debug(f"{pv.temp_plasma_electron_vol_avg_kev = }") + logger.debug(f"{self.data.physics.temp_plasma_electron_vol_avg_kev = }") logger.debug(f"{self.data.costs.coe = }") - logger.debug(f"{pv.rmajor = }") - logger.debug(f"{pv.p_fusion_total_mw = }") - logger.debug(f"{pv.b_plasma_toroidal_on_axis = }") + logger.debug(f"{self.data.physics.rmajor = }") + logger.debug(f"{self.data.physics.p_fusion_total_mw = }") + logger.debug(f"{self.data.physics.b_plasma_toroidal_on_axis = }") logger.debug(f"{self.data.times.t_plant_pulse_burn = }") logger.debug("%s", sqsumconfsq) logger.debug("%s", xv) diff --git a/process/core/solver/iteration_variables.py b/process/core/solver/iteration_variables.py index 9a7169eb49..4cbbadfff9 100644 --- a/process/core/solver/iteration_variables.py +++ b/process/core/solver/iteration_variables.py @@ -33,24 +33,14 @@ class IterationVariable: ITERATION_VARIABLES = { - 1: IterationVariable("aspect", data_structure.physics_variables, 1.1, 10.00), - 2: IterationVariable( - "b_plasma_toroidal_on_axis", data_structure.physics_variables, 0.010, 30.00 - ), - 3: IterationVariable("rmajor", data_structure.physics_variables, 0.1, 50.00), - 4: IterationVariable( - "temp_plasma_electron_vol_avg_kev", data_structure.physics_variables, 5.0, 150.0 - ), - 5: IterationVariable( - "beta_total_vol_avg", data_structure.physics_variables, 0.001, 1.0 - ), - 6: IterationVariable( - "nd_plasma_electrons_vol_avg", data_structure.physics_variables, 2.0e19, 1.0e21 - ), - 7: IterationVariable( - "f_nd_beam_electron", data_structure.physics_variables, 1.0e-6, 1.0 - ), - 10: IterationVariable("hfact", data_structure.physics_variables, 0.1, 3.0), + 1: IterationVariable("aspect", "physics", 1.1, 10.00), + 2: IterationVariable("b_plasma_toroidal_on_axis", "physics", 0.010, 30.00), + 3: IterationVariable("rmajor", "physics", 0.1, 50.00), + 4: IterationVariable("temp_plasma_electron_vol_avg_kev", "physics", 5.0, 150.0), + 5: IterationVariable("beta_total_vol_avg", "physics", 0.001, 1.0), + 6: IterationVariable("nd_plasma_electrons_vol_avg", "physics", 2.0e19, 1.0e21), + 7: IterationVariable("f_nd_beam_electron", "physics", 1.0e-6, 1.0), + 10: IterationVariable("hfact", "physics", 0.1, 3.0), 11: IterationVariable( "p_hcd_primary_extra_heat_mw", "current_drive", @@ -61,7 +51,7 @@ class IterationVariable: 13: IterationVariable("dr_tf_inboard", "build", 0.1, 5.0), 16: IterationVariable("dr_cs", "build", 0.01, 10.00), 17: IterationVariable("t_plant_pulse_dwell", "times", 0.1, 1.0e8), - 18: IterationVariable("q95", data_structure.physics_variables, 2.0, 50.00), + 18: IterationVariable("q95", "physics", 2.0, 50.00), 19: IterationVariable("e_beam_kev", "current_drive", 1.0, 1.0e6), 20: IterationVariable( "temp_cp_average", data_structure.tfcoil_variables, 40.00, 573.0 @@ -72,9 +62,7 @@ class IterationVariable: 37: IterationVariable("j_cs_flat_top_end", "pf_coil", 1.0e5, 1.0e8), 41: IterationVariable("f_j_cs_start_pulse_end_flat_top", "pf_coil", 0.001, 1.0), 42: IterationVariable("dr_cs_tf_gap", "build", 0.001, 10.00), - 44: IterationVariable( - "f_c_plasma_non_inductive", data_structure.physics_variables, 0.001, 1.0 - ), + 44: IterationVariable("f_c_plasma_non_inductive", "physics", 0.001, 1.0), 47: IterationVariable("feffcd", "current_drive", 0.001, 1.0), 56: IterationVariable( "t_tf_superconductor_quench", data_structure.tfcoil_variables, 0.1, 100.0 @@ -115,13 +103,9 @@ class IterationVariable: 98: IterationVariable("f_blkt_li6_enrichment", "fwbs", 10.00, 100.0), 104: IterationVariable("fcwr", "constraints", 0.001, 1.0), 108: IterationVariable("breeder_f", "fwbs", 0.060, 1.0), - 109: IterationVariable( - "f_nd_alpha_electron", data_structure.physics_variables, 0.05, 0.15 - ), + 109: IterationVariable("f_nd_alpha_electron", "physics", 0.05, 0.15), 114: IterationVariable("len_fw_channel", "fwbs", 0.001, 1.0e3), - 119: IterationVariable( - "temp_plasma_separatrix_kev", data_structure.physics_variables, 0.0, 1.0e1 - ), + 119: IterationVariable("temp_plasma_separatrix_kev", "physics", 0.0, 1.0e1), 122: IterationVariable("f_a_cs_turn_steel", "pf_coil", 0.001, 0.950), 125: IterationVariable( "f_nd_impurity_electrons(03)", @@ -219,9 +203,7 @@ class IterationVariable: target_name="f_nd_impurity_electron_array", array_index=13, ), - 138: IterationVariable( - "dx_hts_tape_rebco", data_structure.physics_variables, 0.01e-6, 100.0e-6 - ), + 138: IterationVariable("dx_hts_tape_rebco", "physics", 0.01e-6, 100.0e-6), 139: IterationVariable( "dx_hts_tape_copper", data_structure.rebco_variables, 1.0e-6, 1.0e-3 ), @@ -230,16 +212,12 @@ class IterationVariable: ), 142: IterationVariable( "nd_plasma_separatrix_electron", - data_structure.physics_variables, + "physics", 1.0e17, 1.0e20, ), - 145: IterationVariable( - "f_nd_plasma_pedestal_greenwald", data_structure.physics_variables, 0.1, 0.9 - ), - 152: IterationVariable( - "f_nd_plasma_separatrix_greenwald", data_structure.physics_variables, 0.001, 0.5 - ), + 145: IterationVariable("f_nd_plasma_pedestal_greenwald", "physics", 0.1, 0.9), + 152: IterationVariable("f_nd_plasma_separatrix_greenwald", "physics", 0.001, 0.5), 155: IterationVariable("pfusife", "ife", 5.0e2, 3.0e3), 156: IterationVariable("rrin", "ife", 1.0, 1.0e1), 158: IterationVariable( @@ -254,11 +232,9 @@ class IterationVariable: 172: IterationVariable( "dx_tf_side_case_min", data_structure.tfcoil_variables, 0.001, 1.0 ), - 173: IterationVariable( - "f_plasma_fuel_tritium", data_structure.physics_variables, 0.000, 1.000 - ), - 174: IterationVariable("triang", data_structure.physics_variables, 0.00, 1.00), - 175: IterationVariable("kappa", data_structure.physics_variables, 0.00, 10.00), + 173: IterationVariable("f_plasma_fuel_tritium", "physics", 0.000, 1.000), + 174: IterationVariable("triang", "physics", 0.00, 1.00), + 175: IterationVariable("kappa", "physics", 0.00, 10.00), 176: IterationVariable("f_st_coil_aspect", "stellarator", 0.70, 1.30), } diff --git a/process/core/solver/objectives.py b/process/core/solver/objectives.py index 716607e444..852bbd86f9 100644 --- a/process/core/solver/objectives.py +++ b/process/core/solver/objectives.py @@ -2,10 +2,7 @@ from process.core.exceptions import ProcessValueError from process.core.model import DataStructure -from process.data_structure import ( - physics_variables, - tfcoil_variables, -) +from process.data_structure import tfcoil_variables OBJECTIVE_NAMES = { 1: "Plasma major radius", @@ -64,18 +61,18 @@ def objective_function(minmax: int, data: DataStructure) -> float: match figure_of_merit: case 1: - objective_metric = 0.2 * physics_variables.rmajor + objective_metric = 0.2 * data.physics.rmajor case 3: - objective_metric = physics_variables.pflux_fw_neutron_mw + objective_metric = data.physics.pflux_fw_neutron_mw case 4: objective_metric = ( tfcoil_variables.tfcmw + 1e-3 * data.pf_power.srcktpm ) / 10.0 case 5: - objective_metric = physics_variables.p_fusion_total_mw / ( + objective_metric = data.physics.p_fusion_total_mw / ( data.current_drive.p_hcd_injected_total_mw + data.current_drive.p_beam_orbit_loss_mw - + physics_variables.p_plasma_ohmic_mw + + data.physics.p_plasma_ohmic_mw ) case 6: objective_metric = data.costs.coe / 100.0 @@ -86,11 +83,11 @@ def objective_function(minmax: int, data: DataStructure) -> float: else data.costs.concost / 1.0e4 ) case 8: - objective_metric = physics_variables.aspect + objective_metric = data.physics.aspect case 9: objective_metric = data.divertor.pflux_div_heat_load_mw case 10: - objective_metric = physics_variables.b_plasma_toroidal_on_axis + objective_metric = data.physics.b_plasma_toroidal_on_axis case 11: objective_metric = data.current_drive.p_hcd_injected_total_mw case 14: @@ -100,7 +97,7 @@ def objective_function(minmax: int, data: DataStructure) -> float: raise ProcessValueError("minmax=15 requires i_plant_availability=1") objective_metric = data.costs.f_t_plant_available case 16: - objective_metric = 0.95 * (physics_variables.rmajor / 9.0) - 0.05 * ( + objective_metric = 0.95 * (data.physics.rmajor / 9.0) - 0.05 * ( data.times.t_plant_pulse_burn / 7200.0 ) case 17: diff --git a/process/data_structure/physics_variables.py b/process/data_structure/physics_variables.py index 6e12a4941e..3871591b1a 100644 --- a/process/data_structure/physics_variables.py +++ b/process/data_structure/physics_variables.py @@ -8,6 +8,7 @@ Module containing global variables relating to the plasma physics """ +from dataclasses import dataclass, field from enum import IntEnum import numpy as np @@ -20,2193 +21,1258 @@ class DivertorNumberModels(IntEnum): SINGLE_NULL = 1 -# From physics.f90: -iscz: int = None - - -err242: int = None - - -err243: int = None - - -f_p_plasma_separatrix_rad: float = None -"""Separatrix radiation fraction""" - - -e_plasma_beta: float = None -"""[J]""" - - -p_plasma_heating_total_mw: float = None -"""[W]""" - - -t_energy_confinement_beta: float = None -"""[s]""" - - -ptarmw: float = None - - -lambdaio: float = None - - -drsep: float = None - - -fio: float = None - - -fli: float = None - - -flo: float = None - - -fui: float = None - - -fuo: float = None - - -plimw: float = None - - -plomw: float = None - - -puimw: float = None - - -puomw: float = None - - -rho_star: float = None - -nu_star: float = None - -beta_mcdonald: float = None - -itart_r: float = None - -# Var in subroutine plasma_composition which requires re-initialisation on -# each new run: -first_call: int = None - - -# From physics_variables.f90: -N_CONFINEMENT_SCALINGS: int = 51 +N_CONFINEMENT_SCALINGS = 51 """number of energy confinement time scaling laws""" -m_beam_amu: float = None -"""beam ion mass (amu)""" - - -m_fuel_amu: float = None -"""average mass of fuel portion of ions (amu)""" - - -m_ions_total_amu: float = None -"""average mass of all ions (amu)""" - - -m_plasma_fuel_ions: float = None -"""Mass of the plasma fuel ions (kg)""" - - -m_plasma_ions_total: float = None -"""Mass of all ions in plasma (kg)""" - - -m_plasma_alpha: float = None -"""Mass of the alpha particles in the plasma (kg)""" - - -m_plasma_electron: float = None -"""Mass of the electrons in the plasma (kg)""" - - -m_plasma: float = None -"""Total mass of the plasma (kg)""" - - -alphaj: float = None -"""current profile index""" - - -alphaj_wesson: float = None -"""Wesson-like current profile index""" - - -alphan: float = None -"""density profile index""" - - -alphap: float = None -"""pressure profile index""" - - -fusden_alpha_total: float = None -"""Alpha particle production rate per unit volume, from plasma and beams [particles/m3/sec]""" - - -fusden_plasma_alpha: float = None -"""Alpha particle production rate per unit volume, just from plasma [particles/m3/sec]""" - - -alphat: float = None -"""temperature profile index""" - - -aspect: float = None -"""aspect ratio (`iteration variable 1`)""" - - -beamfus0: float = None -"""multiplier for beam-background fusion calculation""" - - -beta_total_vol_avg: float = None -"""Volume averaged total plasma beta (`iteration variable 5`) (calculated if stellarator)""" - +@dataclass +class PhysicsData: + iscz: int = 0 -beta_fast_alpha: float = None -"""fast alpha beta component""" + err242: int = 0 + err243: int = 0 -beta_vol_avg_max: float = None -"""Max allowable volume averaged beta""" + f_p_plasma_separatrix_rad: float = 0.0 + """Separatrix radiation fraction""" + e_plasma_beta: float = 0.0 + """[J]""" -beta_vol_avg_min: float = None -"""Minimum allowable volume averaged beta""" + p_plasma_heating_total_mw: float = 0.0 + """[W]""" + t_energy_confinement_beta: float = 0.0 + """[s]""" -beta_beam: float = None -"""neutral beam beta component""" + ptarmw: float = 0.0 + lambdaio: float = 0.0 -beta_poloidal_vol_avg: float = None -"""poloidal beta""" + drsep: float = 0.0 + fio: float = 0.0 -beta_poloidal_eps: float = None -"""Poloidal beta and inverse aspcet ratio product""" + fli: float = 0.0 + flo: float = 0.0 -beta_toroidal_vol_avg: float = None -"""Plasma volume averaged toroidal beta""" + fui: float = 0.0 -beta_thermal_toroidal_profile: list[float] = None -"""toroidal beta profile""" + fuo: float = 0.0 + plimw: float = 0.0 -beta_thermal_vol_avg: float = None -"""Plasma volume averaged thermal beta""" + plomw: float = 0.0 + puimw: float = 0.0 -beta_thermal_poloidal_vol_avg: float = None -"""Plasma volume averaged poloidal thermal beta""" + puomw: float = 0.0 + rho_star: float = 0.0 -beta_thermal_toroidal_vol_avg: float = None -"""Plasma volume averaged toloidal thermal beta""" + nu_star: float = 0.0 + beta_mcdonald: float = 0.0 -beta_norm_total: float = None -"""normaised total beta""" + itart_r: float = 0.0 + # Var in subroutine plasma_composition which requires re-initialisation on + # each new run: + first_call: int = 1 -beta_norm_thermal: float = None -"""normaised thermal beta""" + m_beam_amu: float = 0.0 + """beam ion mass (amu)""" + m_fuel_amu: float = 0.0 + """average mass of fuel portion of ions (amu)""" -beta_norm_toroidal: float = None -"""normaised toroidal beta""" + m_ions_total_amu: float = 0.0 + """average mass of all ions (amu)""" + m_plasma_fuel_ions: float = 0.0 + """Mass of the plasma fuel ions (kg)""" -beta_norm_poloidal: float = None -"""normaised poloidal beta""" + m_plasma_ions_total: float = 0.0 + """Mass of all ions in plasma (kg)""" + m_plasma_alpha: float = 0.0 + """Mass of the alpha particles in the plasma (kg)""" -e_plasma_beta_thermal: float = None -"""Plasma thermal energy derived from thermal beta""" + m_plasma_electron: float = 0.0 + """Mass of the electrons in the plasma (kg)""" + m_plasma: float = 0.0 + """Total mass of the plasma (kg)""" -betbm0: float = None -"""leading coefficient for NB beta fraction""" + alphaj: float = 1.0 + """current profile index""" + alphaj_wesson: float = None + """Wesson-like current profile index""" -b_plasma_surface_poloidal_average: float = None -"""Plasma surface average poloidal field (T)""" + alphan: float = 0.25 + """density profile index""" + alphap: float = 0.0 + """pressure profile index""" -b_plasma_toroidal_on_axis: float = None -"""Plasma toroidal field on axis (T) (`iteration variable 2`)""" + fusden_alpha_total: float = 0.0 + """Alpha particle production rate per unit volume, from plasma and beams [particles/m3/sec]""" -b_plasma_inboard_toroidal: float = None -"""Plasma inboard toroidal field (T)""" + fusden_plasma_alpha: float = 0.0 + """Alpha particle production rate per unit volume, just from plasma [particles/m3/sec]""" -b_plasma_outboard_toroidal: float = None -"""Plasma outboard toroidal field (T)""" + alphat: float = 0.5 + """temperature profile index""" -b_plasma_toroidal_profile: list[float] = None -"""toroidal field profile in plasma (T)""" + aspect: float = 2.907 + """aspect ratio (`iteration variable 1`)""" + beamfus0: float = 1.0 + """multiplier for beam-background fusion calculation""" -b_plasma_total: float = None -"""Sum of plasma total toroidal + poloidal field (T)""" + beta_total_vol_avg: float = 0.042 + """Volume averaged total plasma beta (`iteration variable 5`) (calculated if stellarator)""" -e_plasma_magnetic_stored: float = None -"""Plasma stored magnetic energy (J)""" + beta_fast_alpha: float = 0.0 + """fast alpha beta component""" + beta_vol_avg_max: float = 0.0 + """Max allowable volume averaged beta""" -burnup: float = None -"""fractional plasma burnup""" + beta_vol_avg_min: float = 0.0 + """Minimum allowable volume averaged beta""" + beta_beam: float = 0.0 + """neutral beam beta component""" -burnup_in: float = None -"""fractional plasma burnup user input""" + beta_poloidal_vol_avg: float = 0.0 + """poloidal beta""" + beta_poloidal_eps: float = 0.0 + """Poloidal beta and inverse aspcet ratio product""" -b_plasma_vertical_required: float = None -"""Vertical field needed for plasma equilibrium (T)""" + beta_toroidal_vol_avg: float = 0.0 + """Plasma volume averaged toroidal beta""" + beta_thermal_toroidal_profile: list[float] = field(default_factory=list) + """toroidal beta profile""" -c_beta: float = None -"""Destabalisation parameter for i_beta_norm_max=4 beta limit""" + beta_thermal_vol_avg: float = 0.0 + """Plasma volume averaged thermal beta""" + beta_thermal_poloidal_vol_avg: float = 0.0 + """Plasma volume averaged poloidal thermal beta""" -csawth: float = None -"""coeff. for sawteeth effects on burn V-s requirement""" + beta_thermal_toroidal_vol_avg: float = 0.0 + """Plasma volume averaged toloidal thermal beta""" + beta_norm_total: float = 0.0 + """normaised total beta""" -f_vol_plasma: float = None -"""multiplying factor for the plasma volume (normally=1)""" + beta_norm_thermal: float = 0.0 + """normaised thermal beta""" + beta_norm_toroidal: float = 0.0 + """normaised toroidal beta""" -f_r_conducting_wall: float = None -"""maximum ratio of conducting wall distance to plasma minor radius for -vertical stability (`constraint equation 23`) -""" - - -nd_plasma_electrons_vol_avg: float = None -"""Plasma volume averaged electron density (/m3) (`iteration variable 6`)""" - - -nd_plasma_fuel_ions_vol_avg: float = None -"""Plasma volume averaged fuel ion density (/m3)""" - - -dlamee: float = None -"""electron-electron coulomb logarithm""" - - -dlamie: float = None -"""ion-electron coulomb logarithm""" - - -nd_plasma_electron_max_array: list[float] = None -"""Array of plasma electron density upper limits values (/m3)""" - - -nd_plasma_alphas_vol_avg: float = None -"""Plasma volume averaged thermal alpha density (/m3)""" - - -nd_beam_ions: float = None -"""hot beam ion density, variable (/m3)""" - - -nd_beam_ions_out: float = None -"""hot beam ion density from calculation (/m3)""" - - -beta_norm_max: float = None -"""Troyon-like coefficient for beta scaling""" - + beta_norm_poloidal: float = 0.0 + """normaised poloidal beta""" -beta_norm_max_wesson: float = None -"""Wesson-like coefficient for beta scaling""" + e_plasma_beta_thermal: float = 0.0 + """Plasma thermal energy derived from thermal beta""" + betbm0: float = 1.5 + """leading coefficient for NB beta fraction""" -beta_norm_max_menard: float = None -"""Menard-like coefficient for beta scaling""" + b_plasma_surface_poloidal_average: float = 0.0 + """Plasma surface average poloidal field (T)""" + b_plasma_toroidal_on_axis: float = 5.68 + """Plasma toroidal field on axis (T) (`iteration variable 2`)""" -beta_norm_max_original_scaling: float = None -"""Original scaling coefficient for beta scaling""" + b_plasma_inboard_toroidal: float = 0.0 + """Plasma inboard toroidal field (T)""" + b_plasma_outboard_toroidal: float = 0.0 + """Plasma outboard toroidal field (T)""" -beta_norm_max_tholerus: float = None -"""Tholerus-like coefficient for beta scaling""" + b_plasma_toroidal_profile: list[float] = field(default_factory=list) + """toroidal field profile in plasma (T)""" + b_plasma_total: float = 0.0 + """Sum of plasma total toroidal + poloidal field (T)""" -beta_norm_max_stambaugh: float = None -"""Stambaugh-like coefficient for beta scaling""" + e_plasma_magnetic_stored: float = 0.0 + """Plasma stored magnetic energy (J)""" + burnup: float = 0.0 + """fractional plasma burnup""" -nd_plasma_electrons_max: float = None -"""Plasma electron max density limit (/m3)""" + burnup_in: float = 0.0 + """fractional plasma burnup user input""" + b_plasma_vertical_required: float = 0.0 + """Vertical field needed for plasma equilibrium (T)""" -nd_plasma_ions_total_vol_avg: float = None -"""Plasma volume averaged total ion density (/m3)""" + c_beta: float = 0.5 + """Destabalisation parameter for i_beta_norm_max=4 beta limit""" + csawth: float = 1.0 + """coeff. for sawteeth effects on burn V-s requirement""" -nd_plasma_electron_line: float = None -"""Plasma line averaged electron density (/m3)""" + f_vol_plasma: float = 1.0 + """multiplying factor for the plasma volume (normally=1)""" + f_r_conducting_wall: float = 1.35 + """maximum ratio of conducting wall distance to plasma minor radius for + vertical stability (`constraint equation 23`) + """ -nd_plasma_protons_vol_avg: float = None -"""Plasma volume averaged proton ash density (/m3)""" + nd_plasma_electrons_vol_avg: float = 9.8e19 + """Plasma volume averaged electron density (/m3) (`iteration variable 6`)""" + nd_plasma_fuel_ions_vol_avg: float = 0.0 + """Plasma volume averaged fuel ion density (/m3)""" -ntau: float = None -"""Fusion double product (s/m3)""" + dlamee: float = 0.0 + """electron-electron coulomb logarithm""" + dlamie: float = 0.0 + """ion-electron coulomb logarithm""" -nTtau: float = None -"""Lawson triple product [keV s / m3]""" + nd_plasma_electron_max_array: list[float] = field( + default_factory=lambda: np.zeros(8, dtype=np.float64) + ) + """Array of plasma electron density upper limits values (/m3)""" + nd_plasma_alphas_vol_avg: float = 0.0 + """Plasma volume averaged thermal alpha density (/m3)""" -nd_plasma_impurities_vol_avg: float = None -"""Plasma volume averaged impurity (Z > 2) ion density (/m3)""" + nd_beam_ions: float = 0.0 + """hot beam ion density, variable (/m3)""" + nd_beam_ions_out: float = 0.0 + """hot beam ion density from calculation (/m3)""" -gradient_length_ne: float = None -"""Max. normalised gradient length in el. density (i_plasma_pedestal==0 only)""" + beta_norm_max: float = 3.5 + """Troyon-like coefficient for beta scaling""" + beta_norm_max_wesson: float = 0.0 + """Wesson-like coefficient for beta scaling""" -gradient_length_te: float = None -"""Max. normalised gradient length in el. temperature (i_plasma_pedestal==0 only)""" + beta_norm_max_menard: float = 0.0 + """Menard-like coefficient for beta scaling""" + beta_norm_max_original_scaling: float = 0.0 + """Original scaling coefficient for beta scaling""" -beta_poloidal_eps_max: float = None -"""maximum (eps*beta_poloidal) (`constraint equation 6`). Note: revised issue #346 -"Operation at the tokamak equilibrium poloidal beta-limit in TFTR", 1992 Nucl. Fusion 32 1468 -""" - - -eps: float = None -"""inverse aspect ratio""" - - -f_c_plasma_auxiliary: float = None -"""fraction of plasma current produced by auxiliary current drive""" + beta_norm_max_tholerus: float = 0.0 + """Tholerus-like coefficient for beta scaling""" + beta_norm_max_stambaugh: float = 0.0 + """Stambaugh-like coefficient for beta scaling""" -f_c_plasma_inductive: float = None -"""fraction of plasma current produced inductively""" + nd_plasma_electrons_max: float = 0.0 + """Plasma electron max density limit (/m3)""" + nd_plasma_ions_total_vol_avg: float = 0.0 + """Plasma volume averaged total ion density (/m3)""" -f_alpha_electron: float = None -"""fraction of alpha energy to electrons""" + nd_plasma_electron_line: float = 0.0 + """Plasma line averaged electron density (/m3)""" + nd_plasma_protons_vol_avg: float = 0.0 + """Plasma volume averaged proton ash density (/m3)""" -f_p_alpha_plasma_deposited: float = None -"""Fraction of alpha power deposited in plasma. Default of 0.95 taken from https://doi.org/10.1088/0029-5515/39/12/305.""" + ntau: float = 0.0 + """Fusion double product (s/m3)""" + nTtau: float = 0.0 + """Lawson triple product [keV s / m3]""" -f_alpha_ion: float = None -"""fraction of alpha power to ions""" + nd_plasma_impurities_vol_avg: float = 0.0 + """Plasma volume averaged impurity (Z > 2) ion density (/m3)""" + gradient_length_ne: float = None + """Max. normalised gradient length in el. density (i_plasma_pedestal==0 only)""" -f_plasma_fuel_deuterium: float = None -"""Plasma deuterium fuel fraction""" + gradient_length_te: float = None + """Max. normalised gradient length in el. temperature (i_plasma_pedestal==0 only)""" + beta_poloidal_eps_max: float = 1.38 + """maximum (eps*beta_poloidal) (`constraint equation 6`). Note: revised issue #346 + "Operation at the tokamak equilibrium poloidal beta-limit in TFTR", 1992 Nucl. Fusion 32 1468 + """ -f_p_div_lower: float = None -"""fraction of power to the lower divertor in double null configuration -(`i_single_null = 0` only) (default assumes SN) -""" - + eps: float = 0.34399724802 + """inverse aspect ratio""" -ffwal: float = None -"""factor to convert plasma surface area to first wall area in neutron wall -load calculation (`i_pflux_fw_neutron=1`) -""" + f_c_plasma_auxiliary: float = 0.0 + """fraction of plasma current produced by auxiliary current drive""" + f_c_plasma_inductive: float = 0.0 + """fraction of plasma current produced inductively""" -f_nd_plasma_pedestal_greenwald: float = None -"""fraction of Greenwald density to set as pedestal-top density. If `<0`, pedestal-top -density set manually using nd_plasma_pedestal_electron (`i_plasma_pedestal==1`). -(`iteration variable 145`) -""" - + f_alpha_electron: float = 0.0 + """fraction of alpha energy to electrons""" -f_nd_plasma_separatrix_greenwald: float = None -"""fraction of Greenwald density to set as separatrix density. If `<0`, separatrix -density set manually using nd_plasma_separatrix_electron (`i_plasma_pedestal==1`). -(`iteration variable 152`) -""" + f_p_alpha_plasma_deposited: float = 0.95 + """Fraction of alpha power deposited in plasma. Default of 0.95 taken from https://doi.org/10.1088/0029-5515/39/12/305.""" + f_alpha_ion: float = 0.0 + """fraction of alpha power to ions""" -f_plasma_fuel_helium3: float = None -"""Plasma Helium-3 fuel fraction""" + f_plasma_fuel_deuterium: float = 0.5 + """Plasma deuterium fuel fraction""" + f_p_div_lower: float = 1.0 + """fraction of power to the lower divertor in double null configuration + (`i_single_null = 0` only) (default assumes SN) + """ -figmer: float = None -"""physics figure of merit (= plasma_current*aspect**sbar, where `sbar=1`)""" + ffwal: float = 0.92 + """factor to convert plasma surface area to first wall area in neutron wall + load calculation (`i_pflux_fw_neutron=1`) + """ + f_nd_plasma_pedestal_greenwald: float = 0.85 + """fraction of Greenwald density to set as pedestal-top density. If `<0`, pedestal-top + density set manually using nd_plasma_pedestal_electron (`i_plasma_pedestal==1`). + (`iteration variable 145`) + """ -fkzohm: float = None -"""Zohm elongation scaling adjustment factor (`i_plasma_geometry=2, 3`)""" + f_nd_plasma_separatrix_greenwald: float = 0.50 + """fraction of Greenwald density to set as separatrix density. If `<0`, separatrix + density set manually using nd_plasma_separatrix_electron (`i_plasma_pedestal==1`). + (`iteration variable 152`) + """ + f_plasma_fuel_helium3: float = 0.0 + """Plasma Helium-3 fuel fraction""" -f_plasma_fuel_tritium: float = None -"""Plasma tritium fuel fraction""" + figmer: float = 0.0 + """physics figure of merit (= plasma_current*aspect**sbar, where `sbar=1`)""" + fkzohm: float = 1.0 + """Zohm elongation scaling adjustment factor (`i_plasma_geometry=2, 3`)""" + + f_plasma_fuel_tritium: float = 0.5 + """Plasma tritium fuel fraction""" + + fusden_total: float = 0.0 + """fusion reaction rate density, from beams and plasma (reactions/m3/sec)""" + + fusrat_total: float = 0.0 + """fusion reaction rate, from beams and plasma (reactions/sec)""" + + fusrat_plasma_dt_profile: list[float] = field(default_factory=list) + """Profile of D-T fusion reaction rate in plasma, (reactions/sec)""" + + fusrat_plasma_dd_triton_profile: list[float] = field(default_factory=list) + """Profile of D-D fusion reaction rate (tritium branch) in plasma, (reactions/sec)""" + + fusrat_plasma_dd_helion_profile: list[float] = field(default_factory=list) + """Profile of D-D fusion reaction rate (helium branch) in plasma, (reactions/sec)""" + + fusrat_plasma_dhe3_profile: list[float] = field(default_factory=list) + """Profile of D-3He fusion reaction rate in plasma, (reactions/sec)""" + + fusden_plasma: float = 0.0 + """fusion reaction rate, just from plasma (reactions/m3/sec)""" + + f_c_plasma_non_inductive: float = 1.0 + """fraction of the plasma current produced by non-inductive means (`iteration variable 44`)""" + + ejima_coeff: float = 0.4 + """Ejima coefficient for resistive startup V-s formula""" + + f_beta_alpha_beam_thermal: float = 0.0 + """ratio of (fast alpha + neutral beam beta) to thermal beta""" + + hfac: list[float] = field( + default_factory=lambda: np.zeros(N_CONFINEMENT_SCALINGS, dtype=np.float64) + ) + """H factors for an ignited plasma for each energy confinement time scaling law""" + + hfact: float = 1.0 + """H factor on energy confinement times, radiation corrected (`iteration variable 10`).""" + + hstar: float = 1.0 + """H* non-radiation corrected H factor on energy confinement times""" + + t_plasma_energy_confinement_max: float = 10.0 + """Maximum allowed energy confinement time (s)""" + + i_bootstrap_current: int = 3 + """switch for bootstrap current scaling + - =1 ITER 1989 bootstrap scaling (high R/a only) + - =2 for Nevins et al general scaling + - =3 for Wilson et al numerical scaling + - =4 for Sauter et al scaling + - =5 for Sakai et al scaling + - =6 for ARIES scaling + - =7 for Andrade et al scaling + - =8 for Hoang et al scaling + - =9 for Wong et al scaling + - =10 for Gi-I et al scaling + - =11 for Gi-II et al scaling + - =12 for Sugiyama (L-mode) et al scaling + - =13 for Sugiyama (H-mode) et al scaling + """ + + i_beta_component: int = 0 + """switch for beta limit scaling (`constraint equation 24`) + - =0 apply limit to total beta + - =1 apply limit to thermal beta + - =2 apply limit to thermal + neutral beam beta + - =3 apply limit to toroidal beta + """ + + i_plasma_current: int = 4 + """switch for plasma current scaling to use + - =1 Peng analytic fit + - =2 Peng double null divertor scaling (ST) + - =3 simple ITER scaling (k = 2.2, d = 0.6) + - =4 later ITER scaling, a la Uckan + - =5 Todd empirical scaling I + - =6 Todd empirical scaling II + - =7 Connor-Hastie model + - =8 Sauter scaling allowing negative triangularity + - =9 FIESTA ST fit + """ + + i_diamagnetic_current: int = 0 + """switch for diamagnetic current scaling + - =0 Do not calculate + - =1 Use original TART scaling + - =2 Use SCENE scaling + """ + + i_density_limit: int = 8 + """switch for density limit to enforce (`constraint equation 5`) + - =1 old ASDEX + - =2 Borrass model for ITER (I) + - =3 Borrass model for ITER (II) + - =4 JET edge radiation + - =5 JET simplified + - =6 Hugill-Murakami Mq limit + - =7 Greenwald limit + - =8 ASDEX New + """ + + i_beta_fast_alpha: int = 1 + """switch for fast alpha pressure calculation + - =0 ITER physics rules (Uckan) fit + - =1 Modified fit (D. Ward) - better at high temperature + """ + + i_plasma_ignited: int = 0 + """switch for ignition assumption. Obviously, i_plasma_ignited must be zero if current drive + is required. If i_plasma_ignited is 1, any auxiliary power is assumed to be used only during + plasma start-up, and is excluded from all steady-state power balance calculations. + - =0 do not assume plasma ignition + - =1 assume ignited (but include auxiliary power in costs) T""" -t_plasma_energy_confinement_max: float = None -"""Maximum allowed energy confinement time (s)""" + pden_plasma_alpha_mw: float = 0.0 + """Alpha power per volume just from plasma [MW/m3]""" + pden_alpha_total_mw: float = 0.0 + """Alpha power per volume from plasma and beams [MW/m3]""" -i_bootstrap_current: int = None -"""switch for bootstrap current scaling -- =1 ITER 1989 bootstrap scaling (high R/a only) -- =2 for Nevins et al general scaling -- =3 for Wilson et al numerical scaling -- =4 for Sauter et al scaling -- =5 for Sakai et al scaling -- =6 for ARIES scaling -- =7 for Andrade et al scaling -- =8 for Hoang et al scaling -- =9 for Wong et al scaling -- =10 for Gi-I et al scaling -- =11 for Gi-II et al scaling -- =12 for Sugiyama (L-mode) et al scaling -- =13 for Sugiyama (H-mode) et al scaling -""" + f_pden_alpha_electron_mw: float = 0.0 + """Alpha power per volume to electrons [MW/m3]""" + p_fw_alpha_mw: float = 0.0 + """alpha power escaping plasma and reaching first wall (MW)""" -i_beta_component: int = None -"""switch for beta limit scaling (`constraint equation 24`) -- =0 apply limit to total beta -- =1 apply limit to thermal beta -- =2 apply limit to thermal + neutral beam beta -- =3 apply limit to toroidal beta -""" + f_pden_alpha_ions_mw: float = 0.0 + """alpha power per volume to ions (MW/m3)""" + p_plasma_alpha_mw: float = 0.0 + """Alpha power from only the plasma (MW)""" -i_plasma_current: int = None -"""switch for plasma current scaling to use -- =1 Peng analytic fit -- =2 Peng double null divertor scaling (ST) -- =3 simple ITER scaling (k = 2.2, d = 0.6) -- =4 later ITER scaling, a la Uckan -- =5 Todd empirical scaling I -- =6 Todd empirical scaling II -- =7 Connor-Hastie model -- =8 Sauter scaling allowing negative triangularity -- =9 FIESTA ST fit -""" + p_alpha_total_mw: float = 0.0 + """Total alpha power from plasma and beams (MW)""" + p_beam_alpha_mw: float = 0.0 + """alpha power from hot neutral beam ions (MW)""" -i_diamagnetic_current: int = None -"""switch for diamagnetic current scaling -- =0 Do not calculate -- =1 Use original TART scaling -- =2 Use SCENE scaling -""" + p_beam_neutron_mw: float = 0.0 + """neutron power from hot neutral beam ions (MW)""" + p_beam_dt_mw: float = 0.0 + """D-T fusion power from hot neutral beam ions (MW)""" -i_density_limit: int = None -"""switch for density limit to enforce (`constraint equation 5`) -- =1 old ASDEX -- =2 Borrass model for ITER (I) -- =3 Borrass model for ITER (II) -- =4 JET edge radiation -- =5 JET simplified -- =6 Hugill-Murakami Mq limit -- =7 Greenwald limit -- =8 ASDEX New -""" + p_non_alpha_charged_mw: float = 0.0 + """non-alpha charged particle fusion power (MW)""" + p_charged_particle_mw: float = 0.0 + """Total charged particle fusion power [MW]""" -i_beta_fast_alpha: int = None -"""switch for fast alpha pressure calculation -- =0 ITER physics rules (Uckan) fit -- =1 Modified fit (D. Ward) - better at high temperature -""" + pden_non_alpha_charged_mw: float = 0.0 + """Non-alpha charged particle fusion power per volume [MW/m3]""" + f_temp_plasma_electron_density_vol_avg: float = 0.0 + """Ratio of density weighted plasma electron tempertaurature to volume averaged (Profile Factor)""" -i_plasma_ignited: int = None -"""switch for ignition assumption. Obviously, i_plasma_ignited must be zero if current drive -is required. If i_plasma_ignited is 1, any auxiliary power is assumed to be used only during -plasma start-up, and is excluded from all steady-state power balance calculations. -- =0 do not assume plasma ignition -- =1 assume ignited (but include auxiliary power in costs) T""" + l_h_threshold_powers: list[float] = field( + default_factory=lambda: np.zeros(21, dtype=np.float64) + ) + """L-H power threshold for various scalings (MW) + - =1 ITER 1996 scaling: nominal + - =2 ITER 1996 scaling: upper bound + - =3 ITER 1996 scaling: lower bound + - =4 ITER 1997 scaling: excluding elongation + - =5 ITER 1997 scaling: including elongation + - =6 Martin 2008 scaling: nominal + - =7 Martin 2008 scaling: 95% upper bound + - =8 Martin 2008 scaling: 95% lower bound + - =9 Snipes 2000 scaling: nominal + - =10 Snipes 2000 scaling: upper bound + - =11 Snipes 2000 scaling: lower bound + - =12 Snipes 2000 scaling (closed divertor): nominal + - =13 Snipes 2000 scaling (closed divertor): upper bound + - =14 Snipes 2000 scaling (closed divertor): lower bound + - =15 Hubbard et al. 2012 L-I threshold scaling: nominal + - =16 Hubbard et al. 2012 L-I threshold scaling: lower bound + - =17 Hubbard et al. 2012 L-I threshold scaling: upper bound + - =18 Hubbard et al. 2017 L-I threshold scaling + - =19 Martin 2008 aspect ratio corrected scaling: nominal + - =20 Martin 2008 aspect ratio corrected scaling: 95% upper bound + - =21 Martin 2008 aspect ratio corrected scaling: 95% lower bound + """ + p_electron_transport_loss_mw: float = 0.0 + """electron transport power (MW)""" -pden_plasma_alpha_mw: float = None -"""Alpha power per volume just from plasma [MW/m3]""" + pden_electron_transport_loss_mw: float = 0.0 + """electron transport power per volume (MW/m3)""" + p_ion_transport_loss_mw: float = 0.0 + """ion transport power (MW)""" -pden_alpha_total_mw: float = None -"""Alpha power per volume from plasma and beams [MW/m3]""" + pscalingmw: float = 0.0 + """Total transport power from scaling law (MW)""" + pden_ion_transport_loss_mw: float = 0.0 + """ion transport power per volume (MW/m3)""" -f_pden_alpha_electron_mw: float = None -"""Alpha power per volume to electrons [MW/m3]""" + q0: float = 1.0 + """Safety factor on axis""" + q95: float = 0.0 + """Safety factor at 95% flux surface (iteration variable 18) (unless icurr=2 (ST current scaling), + in which case q95 = mean edge safety factor qbar) + """ -p_fw_alpha_mw: float = None -"""alpha power escaping plasma and reaching first wall (MW)""" + molflow_plasma_fuelling_required: float = 0.0 + """plasma fuelling rate (nucleus-pairs/s)""" + tauratio: float = 1.0 + """tauratio /1.0/ : ratio of He and pellet particle confinement times""" -f_pden_alpha_ions_mw: float = None -"""alpha power per volume to ions (MW/m3)""" + q95_min: float = 0.0 + """lower limit for edge safety factor""" + qstar: float = 0.0 + """cylindrical safety factor""" -p_plasma_alpha_mw: float = None -"""Alpha power from only the plasma (MW)""" + rad_fraction_sol: float = 0.8 + """SoL radiation fraction""" + rad_fraction_total: float = 0.0 + """Radiation fraction total = SoL + LCFS radiation / total power deposited in plasma""" -p_alpha_total_mw: float = None -"""Total alpha power from plasma and beams (MW)""" + f_nd_alpha_electron: float = 0.1 + """thermal alpha density/electron density (`iteration variable 109`)""" + f_nd_protium_electrons: float = 0.0 + """Seeded f_nd_protium_electrons density / electron density.""" -p_beam_alpha_mw: float = None -"""alpha power from hot neutral beam ions (MW)""" + ind_plasma_internal_norm: float = 0.9 + """Plasma normalised internal inductance""" + ind_plasma_internal_norm_iter_3: float = 0.0 + """Plasma normalised internal inductance (ITER type 3)""" -p_beam_neutron_mw: float = None -"""neutron power from hot neutral beam ions (MW)""" - - -p_beam_dt_mw: float = None -"""D-T fusion power from hot neutral beam ions (MW)""" - - -p_non_alpha_charged_mw: float = None -"""non-alpha charged particle fusion power (MW)""" - - -p_charged_particle_mw: float = None -"""Total charged particle fusion power [MW]""" - - -pden_non_alpha_charged_mw: float = None -"""Non-alpha charged particle fusion power per volume [MW/m3]""" - - -f_temp_plasma_electron_density_vol_avg: float = None -"""Ratio of density weighted plasma electron tempertaurature to volume averaged (Profile Factor)""" - - -p_plasma_inner_rad_mw: float = None -"""radiation power from inner zone (MW)""" - - -pden_plasma_core_rad_mw: float = None -"""total core radiation power per volume (MW/m3)""" - - -p_dd_total_mw: float = None -"""deuterium-deuterium fusion power (MW)""" - - -p_dhe3_total_mw: float = None -"""deuterium-helium3 fusion power (MW)""" - - -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_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)""" - - -p_div_upper_separatrix_mw: float = None -"""Separatrix power conducted to the upper divertor region (calculated if `i_single_null = 0`) (MW)""" - - -p_div_separatrix_max_mw: float = None -"""Separatrix power conducted to the divertor with most load (calculated if `i_single_null = 0`) (MW)""" - - -p_dt_total_mw: float = None -"""Total deuterium-tritium fusion power, from plasma and beams [MW]""" - - -p_plasma_dt_mw: float = None -"""Deuterium-tritium fusion power, just from plasma [MW]""" - - -p_plasma_outer_rad_mw: float = None -"""radiation power from outer zone (MW)""" - - -pden_plasma_outer_rad_mw: float = None -"""edge radiation power per volume (MW/m3)""" - - -vs_plasma_internal: float = None -"""internal plasma V-s""" - - -pflux_fw_rad_mw: float = None -"""Nominal mean radiation load on inside surface of reactor (MW/m2)""" - - -pden_ion_electron_equilibration_mw: float = None -"""ion/electron equilibration power per volume (MW/m3)""" - - -plasma_current: float = None -"""plasma current (A)""" - -c_plasma_peng_analytic: float = None -"""Peng analytic plasma current (A)""" - -c_plasma_peng_double_null: float = None -"""Peng double null divertor plasma current (A)""" - -c_plasma_cyclindrical: float = None -"""Cylindrical plasma current (A)""" - -c_plasma_ipdg89: float = None -"""ITER IPDG89 plasma current (A)""" - -c_plasma_todd_empirical_i: float = None -"""Todd empirical plasma current I (A)""" - -c_plasma_todd_empirical_ii: float = None -"""Todd empirical plasma current II (A)""" -c_plasma_connor_hastie: float = None -"""Connor-Hastie plasma current (A)""" - -c_plasma_sauter: float = None -"""Sauter plasma current (A)""" - -c_plasma_fiesta_st: float = None -"""FIESTA ST plasma current (A)""" - -p_plasma_neutron_mw: float = None -"""Neutron fusion power from just the plasma [MW]""" - - -p_neutron_total_mw: float = None -"""Total neutron fusion power from plasma and beams [MW]""" - - -pden_neutron_total_mw: float = None -"""neutron fusion power per volume from beams and plasma (MW/m3)""" - - -pden_plasma_neutron_mw: float = None -"""neutron fusion power per volume just from plasma (MW/m3)""" - - -p_plasma_ohmic_mw: float = None -"""ohmic heating power (MW)""" - - -pden_plasma_ohmic_mw: float = None -"""ohmic heating power per volume (MW/m3)""" - - -p_plasma_loss_mw: float = None -"""heating power (= transport loss power) (MW) used in confinement time calculation""" - - -p_fusion_total_mw: float = None -"""fusion power (MW)""" - - -len_plasma_poloidal: float = None -"""plasma poloidal perimeter (m)""" - - -p_plasma_rad_mw: float = None -"""total radiation power from inside LCFS (MW)""" - - -pden_plasma_rad_mw: float = None -"""total radiation power per volume (MW/m3)""" - - -pradsolmw: float = None -"""radiation power from SoL (MW)""" - - -proton_rate_density: float = None -"""Proton production rate [particles/m3/sec]""" - - -psolradmw: float = None -"""SOL radiation power (MW) (`stellarator only`)""" - - -pden_plasma_sync_mw: float = None -"""synchrotron radiation power per volume (MW/m3)""" - - -p_plasma_sync_mw: float = None -"""Total synchrotron radiation power from plasma (MW)""" - - -i_l_h_threshold: int = None -"""switch for L-H mode power threshold scaling to use (see l_h_threshold_powers for list)""" - - -p_l_h_threshold_mw: float = None -"""L-H mode power threshold (MW) (chosen via i_l_h_threshold, and enforced if -constraint equation 15 is on) -""" - - -l_h_threshold_powers: list[float] = None -"""L-H power threshold for various scalings (MW) -- =1 ITER 1996 scaling: nominal -- =2 ITER 1996 scaling: upper bound -- =3 ITER 1996 scaling: lower bound -- =4 ITER 1997 scaling: excluding elongation -- =5 ITER 1997 scaling: including elongation -- =6 Martin 2008 scaling: nominal -- =7 Martin 2008 scaling: 95% upper bound -- =8 Martin 2008 scaling: 95% lower bound -- =9 Snipes 2000 scaling: nominal -- =10 Snipes 2000 scaling: upper bound -- =11 Snipes 2000 scaling: lower bound -- =12 Snipes 2000 scaling (closed divertor): nominal -- =13 Snipes 2000 scaling (closed divertor): upper bound -- =14 Snipes 2000 scaling (closed divertor): lower bound -- =15 Hubbard et al. 2012 L-I threshold scaling: nominal -- =16 Hubbard et al. 2012 L-I threshold scaling: lower bound -- =17 Hubbard et al. 2012 L-I threshold scaling: upper bound -- =18 Hubbard et al. 2017 L-I threshold scaling -- =19 Martin 2008 aspect ratio corrected scaling: nominal -- =20 Martin 2008 aspect ratio corrected scaling: 95% upper bound -- =21 Martin 2008 aspect ratio corrected scaling: 95% lower bound -""" - - -p_electron_transport_loss_mw: float = None -"""electron transport power (MW)""" - - -pden_electron_transport_loss_mw: float = None -"""electron transport power per volume (MW/m3)""" - - -p_ion_transport_loss_mw: float = None -"""ion transport power (MW)""" - - -pscalingmw: float = None -"""Total transport power from scaling law (MW)""" - - -pden_ion_transport_loss_mw: float = None -"""ion transport power per volume (MW/m3)""" - - -q0: float = None -"""Safety factor on axis""" - - -q95: float = None -"""Safety factor at 95% flux surface (iteration variable 18) (unless icurr=2 (ST current scaling), -in which case q95 = mean edge safety factor qbar) -""" - - -molflow_plasma_fuelling_required: float = None -"""plasma fuelling rate (nucleus-pairs/s)""" - - -tauratio: float = None -"""tauratio /1.0/ : ratio of He and pellet particle confinement times""" - - -q95_min: float = None -"""lower limit for edge safety factor""" - - -qstar: float = None -"""cylindrical safety factor""" - - -rad_fraction_sol: float = None -"""SoL radiation fraction""" - - -rad_fraction_total: float = None -"""Radiation fraction total = SoL + LCFS radiation / total power deposited in plasma""" - - -f_nd_alpha_electron: float = None -"""thermal alpha density/electron density (`iteration variable 109`)""" - - -f_nd_protium_electrons: float = None -"""Seeded f_nd_protium_electrons density / electron density.""" - - -ind_plasma_internal_norm: float = None -"""Plasma normalised internal inductance""" - -ind_plasma_internal_norm_iter_3: float = None -"""Plasma normalised internal inductance (ITER type 3)""" - - -ind_plasma_internal_norm_wesson: float = None -"""Wesson-like plasma normalised internal inductance""" - - -ind_plasma_internal_menard: float = None -"""Menard-like plasma normalised internal inductance""" - - -ind_plasma: float = None -"""plasma inductance (H)""" - - -rmajor: float = None -"""plasma major radius (m) (`iteration variable 3`)""" - - -rminor: float = None -"""plasma minor radius (m)""" - - -f_nd_beam_electron: float = None -"""hot beam density / n_e (`iteration variable 7`)""" - - -f_nd_plasma_carbon_electron: float = None -"""n_carbon / n_e""" - - -rndfuel: float = None -"""fuel burnup rate (reactions/second)""" - - -f_nd_plasma_iron_argon_electron: float = None -"""n_highZ / n_e""" - - -f_nd_plasma_oxygen_electron: float = None -"""n_oxygen / n_e""" - - -f_res_plasma_neo: float = None -"""neo-classical correction factor to res_plasma""" - - -res_plasma: float = None -"""plasma resistance (ohm)""" - -t_plasma_res_diffusion: float = None -"""plasma current resistive diffusion time (s)""" - - -a_plasma_surface: float = None -"""plasma surface area""" - - -a_plasma_surface_outboard: float = None -"""outboard plasma surface area""" - - -i_single_null: int = None -"""switch for single null / double null plasma: -- =0 for double null -- =1 for single null (diverted side down) -""" + ind_plasma_internal_norm_wesson: float = 0.0 + """Wesson-like plasma normalised internal inductance""" + ind_plasma_internal_norm_menard: float = 0.0 + """Menard-like plasma normalised internal inductance""" -f_sync_reflect: float = None -"""synchrotron wall reflectivity factor""" + ind_plasma: float = 0.0 + """plasma inductance (H)""" + rmajor: float = 8.14 + """plasma major radius (m) (`iteration variable 3`)""" -t_electron_energy_confinement: float = None -"""electron energy confinement time (sec)""" + rminor: float = 0.0 + """plasma minor radius (m)""" + f_nd_beam_electron: float = 0.005 + """hot beam density / n_e (`iteration variable 7`)""" -tauee_in: float = None -"""Input electron energy confinement time (sec) (`i_confinement_time=48 only`)""" + f_nd_plasma_carbon_electron: float = 0.0 + """n_carbon / n_e""" + rndfuel: float = 0.0 + """fuel burnup rate (reactions/second)""" -t_energy_confinement: float = None -"""global thermal energy confinement time (sec)""" + f_nd_plasma_iron_argon_electron: float = 0.0 + """n_highZ / n_e""" + f_nd_plasma_oxygen_electron: float = 0.0 + """n_oxygen / n_e""" -t_ion_energy_confinement: float = None -"""ion energy confinement time (sec)""" + f_res_plasma_neo: float = 0.0 + """neo-classical correction factor to res_plasma""" + res_plasma: float = 0.0 + """plasma resistance (ohm)""" -t_alpha_confinement: float = None -"""alpha particle confinement time (sec)""" + t_plasma_res_diffusion: float = 0.0 + """plasma current resistive diffusion time (s)""" + a_plasma_surface: float = 0.0 + """plasma surface area""" -f_alpha_energy_confinement: float = None -"""alpha particle to energy confinement time ratio""" + a_plasma_surface_outboard: float = 0.0 + """outboard plasma surface area""" + i_single_null: int = 1 + """switch for single null / double null plasma: + - =0 for double null + - =1 for single null (diverted side down) + """ -temp_plasma_electron_vol_avg_kev: float = None -"""volume averaged electron temperature (keV) (`iteration variable 4`)""" + f_sync_reflect: float = 0.6 + """synchrotron wall reflectivity factor""" + t_electron_energy_confinement: float = 0.0 + """electron energy confinement time (sec)""" -temp_plasma_electron_on_axis_kev: float = None -"""central electron temperature (keV)""" + tauee_in: float = 0.0 + """Input electron energy confinement time (sec) (`i_confinement_time=48 only`)""" + t_energy_confinement: float = 0.0 + """global thermal energy confinement time (sec)""" -temp_plasma_electron_density_weighted_kev: float = None -"""density weighted average electron temperature (keV)""" + t_ion_energy_confinement: float = 0.0 + """ion energy confinement time (sec)""" + t_alpha_confinement: float = 0.0 + """alpha particle confinement time (sec)""" -temp_plasma_ion_vol_avg_kev: float = None -"""volume averaged ion temperature (keV). N.B. calculated from temp_plasma_electron_vol_avg_kev if `f_temp_plasma_ion_electron > 0.0`""" + f_alpha_energy_confinement: float = 0.0 + """alpha particle to energy confinement time ratio""" + temp_plasma_electron_vol_avg_kev: float = 12.9 + """volume averaged electron temperature (keV) (`iteration variable 4`)""" -temp_plasma_ion_on_axis_kev: float = None -"""central ion temperature (keV)""" + temp_plasma_electron_on_axis_kev: float = 0.0 + """central electron temperature (keV)""" + temp_plasma_electron_density_weighted_kev: float = 0.0 + """density weighted average electron temperature (keV)""" -temp_plasma_ion_density_weighted_kev: float = None -"""density weighted average ion temperature (keV)""" + temp_plasma_ion_vol_avg_kev: float = 12.9 + """volume averaged ion temperature (keV). N.B. calculated from temp_plasma_electron_vol_avg_kev if `f_temp_plasma_ion_electron > 0.0`""" + temp_plasma_ion_on_axis_kev: float = 0.0 + """central ion temperature (keV)""" -f_temp_plasma_ion_electron: float = None -"""ion temperature / electron temperature(used to calculate temp_plasma_ion_vol_avg_kev if `f_temp_plasma_ion_electron > 0.0`""" + temp_plasma_ion_density_weighted_kev: float = 0.0 + """density weighted average ion temperature (keV)""" + f_temp_plasma_ion_electron: float = 1.0 + """ion temperature / electron temperature(used to calculate temp_plasma_ion_vol_avg_kev if `f_temp_plasma_ion_electron > 0.0`""" -triang: float = None -"""plasma separatrix triangularity (calculated if `i_plasma_geometry = 1, 3-5 or 7`)""" + triang: float = 0.36 + """plasma separatrix triangularity (calculated if `i_plasma_geometry = 1, 3-5 or 7`)""" + triang95: float = 0.24 + """plasma triangularity at 95% surface (calculated if `i_plasma_geometry = 0-2, 6, 8 or 9`)""" -triang95: float = None -"""plasma triangularity at 95% surface (calculated if `i_plasma_geometry = 0-2, 6, 8 or 9`)""" + vol_plasma: float = 0.0 + """plasma volume (m3)""" + vs_plasma_burn_required: float = 0.0 + """V-s needed during flat-top (heat + burn times) (Wb)""" -vol_plasma: float = None -"""plasma volume (m3)""" + vs_plasma_ramp_required: float = 0.0 + """V-s needed during ramp-up (Wb)""" + v_plasma_loop_burn: float = 0.0 + """Plasma loop voltage during flat-top (V)""" -vs_plasma_burn_required: float = None -"""V-s needed during flat-top (heat + burn times) (Wb)""" + vs_plasma_ind_ramp: float = 0.0 + """Total plasma inductive flux consumption for plasma current ramp-up (Vs)(Wb)""" + vs_plasma_res_ramp: float = 0.0 + """Plasma resistive flux consumption for plasma current ramp-up (Vs)(Wb)""" -vs_plasma_ramp_required: float = None -"""V-s needed during ramp-up (Wb)""" + vs_plasma_total_required: float = 0.0 + """total V-s needed (Wb)""" + pflux_fw_neutron_mw: float = 0.0 + """average neutron wall load (MW/m2)""" -v_plasma_loop_burn: float = None -"""Plasma loop voltage during flat-top (V)""" + pflux_plasma_surface_neutron_avg_mw: float = 0.0 + """Average neutron flux at plasma surface (MW/m2)""" + wtgpd: float = 0.0 + """mass of fuel used per day (g)""" -vs_plasma_ind_ramp: float = None -"""Total plasma inductive flux consumption for plasma current ramp-up (Vs)(Wb)""" + a_plasma_poloidal: float = 0.0 + """plasma poloidal cross-sectional area [m^2]""" + n_charge_plasma_effective_vol_avg: float = 0.0 + """Volume averaged plasma effective charge""" -vs_plasma_res_ramp: float = None -"""Plasma resistive flux consumption for plasma current ramp-up (Vs)(Wb)""" + n_charge_plasma_effective_profile: list[float] = field(default_factory=list) + """Profile of plasma effective charge""" + n_charge_plasma_effective_mass_weighted_vol_avg: float = 0.0 + """Plasma mass-weighted volume averaged plasma effective charge""" -vs_plasma_total_required: float = None -"""total V-s needed (Wb)""" + len_plasma_debye_electron_profile: list[float] = field(default_factory=list) + """Profile of electron Debye length in plasma (m)""" + radius_plasma_deuteron_toroidal_larmor_isotropic_profile: list[float] = field( + default_factory=list + ) + """Profile of deuteron toroidal Larmor radius in plasma, assuming equal speeds in all directions (m)""" -pflux_fw_neutron_mw: float = None -"""average neutron wall load (MW/m2)""" + radius_plasma_deuteron_toroidal_larmor_isotropic_vol_avg: float = 0.0 + """Volume averaged deuteron toroidal Larmor radius in plasma, assuming equal speeds in all directions (m)""" -pflux_plasma_surface_neutron_avg_mw: float = None -"""Average neutron flux at plasma surface (MW/m2)""" + radius_plasma_triton_toroidal_larmor_isotropic_profile: list[float] = field( + default_factory=list + ) + """Profile of triton toroidal Larmor radius in plasma, assuming equal speeds in all directions (m)""" + radius_plasma_triton_toroidal_larmor_isotropic_vol_avg: float = 0.0 + """Volume averaged triton toroidal Larmor radius in plasma, assuming equal speeds in all directions (m)""" -wtgpd: float = None -"""mass of fuel used per day (g)""" + len_plasma_debye_electron_vol_avg: float = 0.0 + """Volume averaged electron Debye length in plasma (m)""" + vel_plasma_electron_profile: list[float] = field(default_factory=list) + """Profile of electron thermal velocity in plasma (m/s)""" -a_plasma_poloidal: float = None -"""plasma poloidal cross-sectional area [m^2]""" + vel_plasma_deuteron_vol_avg: float = 0.0 + """Volume averaged deuteron thermal velocity in plasma (m/s)""" + vel_plasma_electron_vol_avg: float = 0.0 + """Volume averaged electron thermal velocity in plasma (m/s)""" -n_charge_plasma_effective_vol_avg: float = None -"""Volume averaged plasma effective charge""" + vel_plasma_deuteron_profile: list[float] = field(default_factory=list) + """Profile of deuteron thermal velocity in plasma (m/s)""" -n_charge_plasma_effective_profile: list[float] = None -"""Profile of plasma effective charge""" + vel_plasma_triton_profile: list[float] = field(default_factory=list) + """Profile of triton thermal velocity in plasma (m/s)""" + vel_plasma_triton_vol_avg: float = 0.0 + """Volume averaged triton thermal velocity in plasma (m/s)""" -n_charge_plasma_effective_mass_weighted_vol_avg: float = None -"""Plasma mass-weighted volume averaged plasma effective charge""" + vel_plasma_alpha_thermal_profile: list[float] = field(default_factory=list) + """Profile of thermal alpha particle velocity in plasma (m/s)""" -len_plasma_debye_electron_profile: list[float] = None -"""Profile of electron Debye length in plasma (m)""" + vel_plasma_alpha_thermal_vol_avg: float = 0.0 + """Volume averaged thermal alpha particle velocity in plasma (m/s)""" -radius_plasma_deuteron_toroidal_larmor_isotropic_profile: list[float] = None -"""Profile of deuteron toroidal Larmor radius in plasma, assuming equal speeds in all directions (m)""" + vel_plasma_alpha_birth: float = 0.0 + """Birth velocity of alpha particles in plasma (m/s)""" -radius_plasma_deuteron_toroidal_larmor_isotropic_vol_avg: float = None -"""Volume averaged deuteron toroidal Larmor radius in plasma, assuming equal speeds in all directions (m)""" + plasma_coulomb_log_electron_electron_profile: list[float] = field( + default_factory=list + ) + """Profile of electron-electron Coulomb logarithm in plasma""" -radius_plasma_triton_toroidal_larmor_isotropic_profile: list[float] = None -"""Profile of triton toroidal Larmor radius in plasma, assuming equal speeds in all directions (m)""" + plasma_coulomb_log_electron_electron_vol_avg: float = 0.0 + """Volume averaged electron-electron Coulomb logarithm in plasma""" -radius_plasma_triton_toroidal_larmor_isotropic_vol_avg: float = None -"""Volume averaged triton toroidal Larmor radius in plasma, assuming equal speeds in all directions (m)""" + plasma_coulomb_log_electron_deuteron_profile: list[float] = field( + default_factory=list + ) + """Profile of electron-deuteron Coulomb logarithm in plasma""" -len_plasma_debye_electron_vol_avg: float = None -"""Volume averaged electron Debye length in plasma (m)""" + plasma_coulomb_log_electron_deuteron_vol_avg: float = 0.0 + """Volume averaged electron-deuteron Coulomb logarithm in plasma""" -vel_plasma_electron_profile: list[float] = None -"""Profile of electron thermal velocity in plasma (m/s)""" + plasma_coulomb_log_electron_triton_profile: list[float] = field(default_factory=list) + """Profile of electron-triton Coulomb logarithm in plasma""" -vel_plasma_deuteron_vol_avg: float = None -"""Volume averaged deuteron thermal velocity in plasma (m/s)""" + plasma_coulomb_log_electron_triton_vol_avg: float = 0.0 + """Volume averaged electron-triton Coulomb logarithm in plasma""" -vel_plasma_electron_vol_avg: float = None -"""Volume averaged electron thermal velocity in plasma (m/s)""" + plasma_coulomb_log_deuteron_triton_profile: list[float] = field(default_factory=list) + """Profile of deuteron-triton Coulomb logarithm in plasma""" -vel_plasma_deuteron_profile: list[float] = None -"""Profile of deuteron thermal velocity in plasma (m/s)""" + plasma_coulomb_log_deuteron_triton_vol_avg: float = 0.0 + """Volume averaged deuteron-triton Coulomb logarithm in plasma""" -vel_plasma_triton_profile: list[float] = None -"""Profile of triton thermal velocity in plasma (m/s)""" + plasma_coulomb_log_electron_alpha_thermal_profile: list[float] = field( + default_factory=list + ) + """Profile of electron-alpha Coulomb logarithm in plasma""" -vel_plasma_triton_vol_avg: float = None -"""Volume averaged triton thermal velocity in plasma (m/s)""" + plasma_coulomb_log_electron_alpha_thermal_vol_avg: float = 0.0 + """Volume averaged electron-alpha Coulomb logarithm in plasma""" -vel_plasma_alpha_thermal_profile: list[float] = None -"""Profile of thermal alpha particle velocity in plasma (m/s)""" + t_plasma_electron_alpha_spitzer_slow_profile: list[float] = field( + default_factory=list + ) + """Profile of electron-alpha Spitzer slowing down time in plasma (s)""" -vel_plasma_alpha_thermal_vol_avg: float = None -"""Volume averaged thermal alpha particle velocity in plasma (m/s)""" + t_plasma_electron_alpha_spitzer_slow_vol_avg: float = 0.0 + """Volume averaged electron-alpha Spitzer slowing down time in plasma (s)""" -vel_plasma_alpha_birth: float = None -"""Birth velocity of alpha particles in plasma (m/s)""" + freq_plasma_electron_profile: list[float] = field(default_factory=list) + """Electron plasma frequency profile (Hz)""" -plasma_coulomb_log_electron_electron_profile: list[float] = None -"""Profile of electron-electron Coulomb logarithm in plasma""" + freq_plasma_electron_vol_avg: float = 0.0 + """Volume averaged electron plasma frequency (Hz)""" -plasma_coulomb_log_electron_electron_vol_avg: float = None -"""Volume averaged electron-electron Coulomb logarithm in plasma""" + freq_plasma_deuteron_profile: list[float] = field(default_factory=list) + """Deuteron plasma frequency profile (Hz)""" -plasma_coulomb_log_electron_deuteron_profile: list[float] = None -"""Profile of electron-deuteron Coulomb logarithm in plasma""" + freq_plasma_larmor_toroidal_electron_profile: list[float] = field( + default_factory=list + ) + """Profile of electron Larmor frequency in plasma due to toroidal magnetic field (Hz)""" -plasma_coulomb_log_electron_deuteron_vol_avg: float = None -"""Volume averaged electron-deuteron Coulomb logarithm in plasma""" + freq_plasma_larmor_toroidal_electron_vol_avg: float = None + """Volume averaged electron Larmor frequency in plasma due to toroidal magnetic field (Hz)""" -plasma_coulomb_log_electron_triton_profile: list[float] = None -"""Profile of electron-triton Coulomb logarithm in plasma""" + freq_plasma_larmor_toroidal_deuteron_profile: list[float] = field( + default_factory=list + ) + """Profile of deuteron Larmor frequency in plasma due to toroidal magnetic field (Hz)""" -plasma_coulomb_log_electron_triton_vol_avg: float = None -"""Volume averaged electron-triton Coulomb logarithm in plasma""" + freq_plasma_larmor_toroidal_deuteron_vol_avg: float = None + """Volume averaged deuteron Larmor frequency in plasma due to toroidal magnetic field (Hz)""" -plasma_coulomb_log_deuteron_triton_profile: list[float] = None -"""Profile of deuteron-triton Coulomb logarithm in plasma""" + freq_plasma_larmor_toroidal_triton_profile: list[float] = field(default_factory=list) + """Profile of triton Larmor frequency in plasma due to toroidal magnetic field (Hz)""" -plasma_coulomb_log_deuteron_triton_vol_avg: float = None -"""Volume averaged deuteron-triton Coulomb logarithm in plasma""" + freq_plasma_larmor_toroidal_triton_vol_avg: float = None + """Volume averaged triton Larmor frequency in plasma due to toroidal magnetic field (Hz)""" -plasma_coulomb_log_electron_alpha_thermal_profile: list[float] = None -"""Profile of electron-alpha Coulomb logarithm in plasma""" + freq_plasma_upper_hybrid_profile: list[float] = field(default_factory=list) + """Profile of upper hybrid frequency in plasma (Hz)""" -plasma_coulomb_log_electron_alpha_thermal_vol_avg: float = None -"""Volume averaged electron-alpha Coulomb logarithm in plasma""" + freq_plasma_upper_hybrid_vol_avg: float = 0.0 + """Volume averaged upper hybrid frequency in plasma (Hz)""" -t_plasma_electron_alpha_spitzer_slow_profile: list[float] = None -"""Profile of electron-alpha Spitzer slowing down time in plasma (s)""" + t_plasma_electron_electron_collision_profile: list[float] = field( + default_factory=list + ) + """Profile of electron-electron collision time in plasma (s)""" -t_plasma_electron_alpha_spitzer_slow_vol_avg: float = None -"""Volume averaged electron-alpha Spitzer slowing down time in plasma (s)""" + t_plasma_electron_electron_collision_vol_avg: float = 0.0 + """Volume averaged electron-electron collision time in plasma (s)""" -freq_plasma_electron_profile: list[float] = None -"""Electron plasma frequency profile (Hz)""" + t_plasma_electron_deuteron_collision_profile: list[float] = field( + default_factory=list + ) + """Profile of electron-deuteron collision time in plasma (s)""" -freq_plasma_electron_vol_avg: float = None -"""Volume averaged electron plasma frequency (Hz)""" + t_plasma_electron_deuteron_collision_vol_avg: float = 0.0 + """Volume averaged electron-deuteron collision time in plasma (s)""" -freq_plasma_deuteron_profile: list[float] = None -"""Deuteron plasma frequency profile (Hz)""" + t_plasma_electron_triton_collision_profile: list[float] = field(default_factory=list) + """Profile of electron-triton collision time in plasma (s)""" -freq_plasma_larmor_toroidal_electron_profile: list[float] = None -"""Profile of electron Larmor frequency in plasma due to toroidal magnetic field (Hz)""" + t_plasma_electron_triton_collision_vol_avg: float = 0.0 + """Volume averaged electron-triton collision time in plasma (s)""" -freq_plasma_larmor_toroidal_electron_vol_avg: float = None -"""Volume averaged electron Larmor frequency in plasma due to toroidal magnetic field (Hz)""" + t_plasma_electron_alpha_thermal_collision_profile: list[float] = field( + default_factory=list + ) + """Profile of electron-alpha collision time in plasma (s)""" -freq_plasma_larmor_toroidal_deuteron_profile: list[float] = None -"""Profile of deuteron Larmor frequency in plasma due to toroidal magnetic field (Hz)""" + t_plasma_electron_alpha_thermal_collision_vol_avg: float = 0.0 + """Volume averaged electron-alpha collision time in plasma (s)""" -freq_plasma_larmor_toroidal_deuteron_vol_avg: float = None -"""Volume averaged deuteron Larmor frequency in plasma due to toroidal magnetic field (Hz)""" + freq_plasma_electron_electron_collision_profile: list[float] = field( + default_factory=list + ) + """Profile of electron-electron collision frequency in plasma (Hz)""" -freq_plasma_larmor_toroidal_triton_profile: list[float] = None -"""Profile of triton Larmor frequency in plasma due to toroidal magnetic field (Hz)""" + freq_plasma_electron_electron_collision_vol_avg: float = 0.0 + """Volume averaged electron-electron collision frequency in plasma (Hz)""" -freq_plasma_larmor_toroidal_triton_vol_avg: float = None -"""Volume averaged triton Larmor frequency in plasma due to toroidal magnetic field (Hz)""" + freq_plasma_electron_deuteron_collision_profile: list[float] = field( + default_factory=list + ) + """Profile of electron-deuteron collision frequency in plasma (Hz)""" -freq_plasma_upper_hybrid_profile: list[float] = None -"""Profile of upper hybrid frequency in plasma (Hz)""" + freq_plasma_electron_deuteron_collision_vol_avg: float = 0.0 + """Volume averaged electron-deuteron collision frequency in plasma (Hz)""" -freq_plasma_upper_hybrid_vol_avg: float = None -"""Volume averaged upper hybrid frequency in plasma (Hz)""" + freq_plasma_electron_triton_collision_profile: list[float] = field( + default_factory=list + ) + """Profile of electron-triton collision frequency in plasma (Hz)""" -t_plasma_electron_electron_collision_profile: list[float] = None -"""Profile of electron-electron collision time in plasma (s)""" + freq_plasma_electron_triton_collision_vol_avg: float = 0.0 + """Volume averaged electron-triton collision frequency in plasma (Hz)""" -t_plasma_electron_electron_collision_vol_avg: float = None -"""Volume averaged electron-electron collision time in plasma (s)""" + freq_plasma_electron_alpha_thermal_collision_profile: list[float] = field( + default_factory=list + ) + """Profile of electron-alpha collision frequency in plasma (Hz)""" -t_plasma_electron_deuteron_collision_profile: list[float] = None -"""Profile of electron-deuteron collision time in plasma (s)""" + freq_plasma_electron_alpha_thermal_collision_vol_avg: float = 0.0 + """Volume averaged electron-alpha collision frequency in plasma (Hz)""" -t_plasma_electron_deuteron_collision_vol_avg: float = None -"""Volume averaged electron-deuteron collision time in plasma (s)""" + len_plasma_electron_electron_mean_free_path_profile: list[float] = field( + default_factory=list + ) + """Profile of electron-electron mean free path in plasma (m)""" -t_plasma_electron_triton_collision_profile: list[float] = None -"""Profile of electron-triton collision time in plasma (s)""" + len_plasma_electron_electron_mean_free_path_vol_avg: float = 0.0 + """Volume averaged electron-electron mean free path in plasma (m)""" -t_plasma_electron_triton_collision_vol_avg: float = None -"""Volume averaged electron-triton collision time in plasma (s)""" + len_plasma_electron_deuteron_mean_free_path_profile: list[float] = field( + default_factory=list + ) + """Profile of electron-deuteron mean free path in plasma (m)""" -t_plasma_electron_alpha_thermal_collision_profile: list[float] = None -"""Profile of electron-alpha collision time in plasma (s)""" + len_plasma_electron_deuteron_mean_free_path_vol_avg: float = 0.0 + """Volume averaged electron-deuteron mean free path in plasma (m)""" -t_plasma_electron_alpha_thermal_collision_vol_avg: float = None -"""Volume averaged electron-alpha collision time in plasma (s)""" + len_plasma_electron_triton_mean_free_path_profile: list[float] = field( + default_factory=list + ) + """Profile of electron-triton mean free path in plasma (m)""" -freq_plasma_electron_electron_collision_profile: list[float] = None -"""Profile of electron-electron collision frequency in plasma (Hz)""" + len_plasma_electron_triton_mean_free_path_vol_avg: float = 0.0 + """Volume averaged electron-triton mean free path in plasma (m)""" -freq_plasma_electron_electron_collision_vol_avg: float = None -"""Volume averaged electron-electron collision frequency in plasma (Hz)""" + len_plasma_electron_alpha_thermal_mean_free_path_profile: list[float] = field( + default_factory=list + ) + """Profile of electron-alpha mean free path in plasma (m)""" -freq_plasma_electron_deuteron_collision_profile: list[float] = None -"""Profile of electron-deuteron collision frequency in plasma (Hz)""" + len_plasma_electron_alpha_thermal_mean_free_path_vol_avg: float = 0.0 + """Volume averaged electron-alpha mean free path in plasma (m)""" -freq_plasma_electron_deuteron_collision_vol_avg: float = None -"""Volume averaged electron-deuteron collision frequency in plasma (Hz)""" + res_plasma_fuel_spitzer_profile: list[float] = field(default_factory=list) + """Profile of plasma Spitzer resistivity due to fuel ions (ohm m)""" -freq_plasma_electron_triton_collision_profile: list[float] = None -"""Profile of electron-triton collision frequency in plasma (Hz)""" + res_plasma_fuel_spitzer_vol_avg: float = 0.0 + """Volume averaged plasma Spitzer resistivity due to fuel ions (ohm m)""" -freq_plasma_electron_triton_collision_vol_avg: float = None -"""Volume averaged electron-triton collision frequency in plasma (Hz)""" -freq_plasma_electron_alpha_thermal_collision_profile: list[float] = None -"""Profile of electron-alpha collision frequency in plasma (Hz)""" - -freq_plasma_electron_alpha_thermal_collision_vol_avg: float = None -"""Volume averaged electron-alpha collision frequency in plasma (Hz)""" - -len_plasma_electron_electron_mean_free_path_profile: list[float] = None -"""Profile of electron-electron mean free path in plasma (m)""" - -len_plasma_electron_electron_mean_free_path_vol_avg: float = None -"""Volume averaged electron-electron mean free path in plasma (m)""" - -len_plasma_electron_deuteron_mean_free_path_profile: list[float] = None -"""Profile of electron-deuteron mean free path in plasma (m)""" - -len_plasma_electron_deuteron_mean_free_path_vol_avg: float = None -"""Volume averaged electron-deuteron mean free path in plasma (m)""" - -len_plasma_electron_triton_mean_free_path_profile: list[float] = None -"""Profile of electron-triton mean free path in plasma (m)""" - -len_plasma_electron_triton_mean_free_path_vol_avg: float = None -"""Volume averaged electron-triton mean free path in plasma (m)""" - -len_plasma_electron_alpha_thermal_mean_free_path_profile: list[float] = None -"""Profile of electron-alpha mean free path in plasma (m)""" - -len_plasma_electron_alpha_thermal_mean_free_path_vol_avg: float = None -"""Volume averaged electron-alpha mean free path in plasma (m)""" - -res_plasma_fuel_spitzer_profile: list[float] = None -"""Profile of plasma Spitzer resistivity due to fuel ions (ohm m)""" - -res_plasma_fuel_spitzer_vol_avg: float = None -"""Volume averaged plasma Spitzer resistivity due to fuel ions (ohm m)""" - - -def init_physics_module(): - """Initialise the physics module""" - global \ - first_call, \ - iscz, \ - err242, \ - err243, \ - f_p_plasma_separatrix_rad, \ - e_plasma_beta, \ - p_plasma_heating_total_mw, \ - t_energy_confinement_beta, \ - ptarmw, \ - lambdaio, \ - drsep, \ - fio, \ - fli, \ - flo, \ - fui, \ - fuo, \ - plimw, \ - plomw, \ - puimw, \ - puomw, \ - rho_star, \ - rho_ne_max, \ - rho_te_max, \ - nu_star, \ - beta_mcdonald, \ - itart_r - - first_call = 1 - iscz = 0 - err242 = 0 - err243 = 0 - f_p_plasma_separatrix_rad = 0.0 - e_plasma_beta = 0.0 - p_plasma_heating_total_mw = 0.0 - t_energy_confinement_beta = 0.0 - ptarmw = 0.0 - lambdaio = 0.0 - drsep = 0.0 - fio = 0.0 - fli = 0.0 - flo = 0.0 - fui = 0.0 - fuo = 0.0 - plimw = 0.0 - plomw = 0.0 - puimw = 0.0 - puomw = 0.0 - rho_ne_max = 0.0 - rho_te_max = 0.0 - rho_star = 0.0 - nu_star = 0.0 - beta_mcdonald = 0.0 - itart_r = 0.0 - - -def init_physics_variables(): - global \ - m_beam_amu, \ - m_fuel_amu, \ - m_ions_total_amu, \ - m_plasma_fuel_ions, \ - m_plasma_ions_total, \ - m_plasma_alpha, \ - m_plasma_electron, \ - m_plasma, \ - alphaj, \ - i_alphaj, \ - alphan, \ - alphap, \ - fusden_alpha_total, \ - fusden_plasma_alpha, \ - alphat, \ - aspect, \ - beamfus0, \ - beta_total_vol_avg, \ - beta_fast_alpha, \ - beta_vol_avg_max, \ - beta_vol_avg_min, \ - beta_beam, \ - beta_poloidal_vol_avg, \ - beta_poloidal_eps, \ - beta_toroidal_vol_avg, \ - beta_thermal_toroidal_profile, \ - beta_thermal_vol_avg, \ - beta_thermal_poloidal_vol_avg, \ - beta_thermal_toroidal_vol_avg, \ - beta_norm_total, \ - beta_norm_thermal, \ - beta_norm_poloidal, \ - e_plasma_beta_thermal, \ - beta_norm_toroidal, \ - betbm0, \ - b_plasma_surface_poloidal_average, \ - b_plasma_toroidal_on_axis, \ - b_plasma_toroidal_inboard, \ - b_plasma_toroidal_outboard, \ - b_plasma_toroidal_profile, \ - b_plasma_total, \ - e_plasma_magnetic_stored, \ - burnup, \ - burnup_in, \ - b_plasma_vertical_required, \ - c_beta, \ - csawth, \ - f_vol_plasma, \ - f_r_conducting_wall, \ - nd_plasma_electrons_vol_avg, \ - nd_plasma_fuel_ions_vol_avg, \ - dlamee, \ - dlamie, \ - nd_plasma_electron_max_array, \ - nd_plasma_alphas_vol_avg, \ - nd_beam_ions, \ - nd_beam_ions_out, \ - beta_norm_max, \ - beta_norm_max_wesson, \ - beta_norm_max_menard, \ - beta_norm_max_original_scaling, \ - beta_norm_max_tholerus, \ - beta_norm_max_stambaugh, \ - nd_plasma_electrons_max, \ - nd_plasma_ions_total_vol_avg, \ - nd_plasma_electron_line, \ - nd_plasma_protons_vol_avg, \ - ntau, \ - nTtau, \ - nd_plasma_impurities_vol_avg, \ - beta_poloidal_eps_max, \ - eps, \ - f_c_plasma_auxiliary, \ - f_c_plasma_inductive, \ - f_alpha_electron, \ - f_p_alpha_plasma_deposited, \ - f_alpha_ion, \ - f_plasma_fuel_deuterium, \ - f_p_div_lower, \ - ffwal, \ - f_nd_plasma_pedestal_greenwald, \ - f_nd_plasma_separatrix_greenwald, \ - f_plasma_fuel_helium3, \ - figmer, \ - fkzohm, \ - f_plasma_fuel_tritium, \ - fusden_total, \ - fusrat_total, \ - fusrat_plasma_dt_profile, \ - fusrat_plasma_dd_triton_profile, \ - fusrat_plasma_dd_helion_profile, \ - fusrat_plasma_dhe3_profile, \ - fusden_plasma, \ - f_c_plasma_non_inductive, \ - ejima_coeff, \ - f_beta_alpha_beam_thermal, \ - hfac, \ - hfact, \ - hstar, \ - t_plasma_energy_confinement_max, \ - i_bootstrap_current, \ - i_beta_component, \ - i_plasma_current, \ - i_diamagnetic_current, \ - i_density_limit, \ - i_beta_fast_alpha, \ - i_plasma_ignited, \ - i_plasma_pedestal, \ - i_pfirsch_schluter_current, \ - nd_plasma_pedestal_electron, \ - nd_plasma_separatrix_electron, \ - alpha_crit, \ - nd_plasma_separatrix_electron_eich_max, \ - plasma_res_factor, \ - radius_plasma_pedestal_density_norm, \ - radius_plasma_pedestal_temp_norm, \ - tbeta, \ - temp_plasma_pedestal_kev, \ - temp_plasma_separatrix_kev, \ - i_beta_norm_max, \ - i_rad_loss, \ - i_confinement_time, \ - i_plasma_wall_gap, \ - i_plasma_geometry, \ - i_plasma_shape, \ - itart, \ - itartpf, \ - i_pflux_fw_neutron, \ - plasma_square, \ - kappa, \ - kappa95, \ - kappa_ipb, \ - nd_plasma_electron_on_axis, \ - nd_plasma_ions_on_axis, \ - m_s_limit, \ - pres_plasma_thermal_on_axis, \ - pres_plasma_thermal_total_profile, \ - pres_plasma_electron_profile, \ - pres_plasma_ion_total_profile, \ - pres_plasma_fuel_profile, \ - j_plasma_on_axis, \ - n_plasma_profile_elements, \ - f_dd_branching_trit, \ - pden_plasma_alpha_mw, \ - pden_alpha_total_mw, \ - f_pden_alpha_electron_mw, \ - p_fw_alpha_mw, \ - f_pden_alpha_ions_mw, \ - p_alpha_total_mw, \ - p_plasma_alpha_mw, \ - p_beam_alpha_mw, \ - p_beam_neutron_mw, \ - p_beam_dt_mw, \ - p_non_alpha_charged_mw, \ - pden_non_alpha_charged_mw, \ - f_temp_plasma_electron_density_vol_avg, \ - p_plasma_inner_rad_mw, \ - pden_plasma_core_rad_mw, \ - p_dd_total_mw, \ - 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, \ - p_dt_total_mw, \ - p_plasma_dt_mw, \ - p_plasma_outer_rad_mw, \ - pden_plasma_outer_rad_mw, \ - p_charged_particle_mw, \ - vs_plasma_internal, \ - pflux_fw_rad_mw, \ - pden_ion_electron_equilibration_mw, \ - plasma_current, \ - c_plasma_peng_analytic, \ - c_plasma_peng_double_null, \ - c_plasma_cyclindrical, \ - c_plasma_ipdg89, \ - c_plasma_todd_empirical_i, \ - c_plasma_todd_empirical_ii, \ - c_plasma_connor_hastie, \ - c_plasma_sauter, \ - c_plasma_fiesta_st, \ - p_plasma_neutron_mw, \ - p_neutron_total_mw, \ - pden_neutron_total_mw, \ - pden_plasma_neutron_mw, \ - p_plasma_ohmic_mw, \ - pden_plasma_ohmic_mw, \ - p_plasma_loss_mw, \ - p_fusion_total_mw, \ - len_plasma_poloidal, \ - p_plasma_rad_mw, \ - pden_plasma_rad_mw, \ - pradsolmw, \ - proton_rate_density, \ - psolradmw, \ - pden_plasma_sync_mw, \ - p_plasma_sync_mw, \ - i_l_h_threshold, \ - p_l_h_threshold_mw, \ - l_h_threshold_powers, \ - p_electron_transport_loss_mw, \ - pden_electron_transport_loss_mw, \ - p_ion_transport_loss_mw, \ - pscalingmw, \ - pden_ion_transport_loss_mw, \ - q0, \ - q95, \ - molflow_plasma_fuelling_required, \ - tauratio, \ - q95_min, \ - qstar, \ - rad_fraction_sol, \ - rad_fraction_total, \ - f_nd_alpha_electron, \ - f_nd_protium_electrons, \ - ind_plasma_internal_norm, \ - ind_plasma_internal_norm_wesson, \ - ind_plasma_internal_norm_menard, \ - ind_plasma_internal_norm_iter_3, \ - i_ind_plasma_internal_norm, \ - ind_plasma, \ - rmajor, \ - rminor, \ - f_nd_beam_electron, \ - f_nd_plasma_carbon_electron, \ - rndfuel, \ - f_nd_plasma_iron_argon_electron, \ - f_nd_plasma_oxygen_electron, \ - f_res_plasma_neo, \ - res_plasma, \ - rho_plasma_spitzer_classical_profile, \ - t_plasma_res_diffusion, \ - a_plasma_surface, \ - a_plasma_surface_outboard, \ - i_single_null, \ - f_sync_reflect, \ - t_electron_energy_confinement, \ - tauee_in, \ - t_energy_confinement, \ - t_ion_energy_confinement, \ - t_alpha_confinement, \ - f_alpha_energy_confinement, \ - temp_plasma_electron_vol_avg_kev, \ - temp_plasma_electron_on_axis_kev, \ - temp_plasma_electron_density_weighted_kev, \ - temp_plasma_ion_vol_avg_kev, \ - temp_plasma_ion_on_axis_kev, \ - temp_plasma_ion_density_weighted_kev, \ - f_temp_plasma_ion_electron, \ - triang, \ - triang95, \ - vol_plasma, \ - vs_plasma_burn_required, \ - vs_plasma_ramp_required, \ - v_plasma_loop_burn, \ - vs_plasma_ind_ramp, \ - vs_plasma_res_ramp, \ - vs_plasma_total_required, \ - pflux_fw_neutron_mw, \ - pflux_plasma_surface_neutron_avg_mw, \ - wtgpd, \ - a_plasma_poloidal, \ - n_charge_plasma_effective_vol_avg, \ - n_charge_plasma_effective_profile, \ - n_charge_plasma_effective_mass_weighted_vol_avg, \ - j_plasma_bootstrap_sauter_profile, \ - len_plasma_debye_electron_profile, \ - radius_plasma_deuteron_toroidal_larmor_isotropic_profile, \ - radius_plasma_deuteron_toroidal_larmor_isotropic_vol_avg, \ - radius_plasma_triton_toroidal_larmor_isotropic_profile, \ - radius_plasma_triton_toroidal_larmor_isotropic_vol_avg, \ - len_plasma_debye_electron_vol_avg, \ - vel_plasma_electron_profile, \ - vel_plasma_deuteron_vol_avg, \ - vel_plasma_electron_vol_avg, \ - vel_plasma_deuteron_profile, \ - vel_plasma_triton_profile, \ - vel_plasma_triton_vol_avg, \ - vel_plasma_alpha_thermal_profile, \ - vel_plasma_alpha_thermal_vol_avg, \ - vel_plasma_alpha_birth, \ - plasma_coulomb_log_electron_electron_profile, \ - plasma_coulomb_log_electron_electron_vol_avg, \ - plasma_coulomb_log_electron_deuteron_profile, \ - plasma_coulomb_log_electron_deuteron_vol_avg, \ - plasma_coulomb_log_electron_triton_profile, \ - plasma_coulomb_log_electron_triton_vol_avg, \ - plasma_coulomb_log_deuteron_triton_profile, \ - plasma_coulomb_log_deuteron_triton_vol_avg, \ - plasma_coulomb_log_electron_alpha_thermal_profile, \ - plasma_coulomb_log_electron_alpha_thermal_vol_avg, \ - t_plasma_electron_alpha_spitzer_slow_profile, \ - t_plasma_electron_alpha_spitzer_slow_vol_avg, \ - freq_plasma_electron_profile, \ - freq_plasma_electron_vol_avg, \ - freq_plasma_deuteron_profile, \ - freq_plasma_larmor_toroidal_electron_profile, \ - freq_plasma_larmor_toroidal_deuteron_profile, \ - freq_plasma_larmor_toroidal_triton_profile, \ - freq_plasma_upper_hybrid_profile, \ - freq_plasma_upper_hybrid_vol_avg, \ - t_plasma_electron_electron_collision_profile, \ - t_plasma_electron_electron_collision_vol_avg, \ - t_plasma_electron_deuteron_collision_profile, \ - t_plasma_electron_deuteron_collision_vol_avg, \ - t_plasma_electron_triton_collision_profile, \ - t_plasma_electron_triton_collision_vol_avg, \ - t_plasma_electron_alpha_thermal_collision_profile, \ - t_plasma_electron_alpha_thermal_collision_vol_avg, \ - freq_plasma_electron_electron_collision_profile, \ - freq_plasma_electron_electron_collision_vol_avg, \ - freq_plasma_electron_deuteron_collision_profile, \ - freq_plasma_electron_deuteron_collision_vol_avg, \ - freq_plasma_electron_triton_collision_profile, \ - freq_plasma_electron_triton_collision_vol_avg, \ - freq_plasma_electron_alpha_thermal_collision_profile, \ - freq_plasma_electron_alpha_thermal_collision_vol_avg, \ - len_plasma_electron_electron_mean_free_path_profile, \ - len_plasma_electron_electron_mean_free_path_vol_avg, \ - len_plasma_electron_deuteron_mean_free_path_profile, \ - len_plasma_electron_deuteron_mean_free_path_vol_avg, \ - len_plasma_electron_triton_mean_free_path_profile, \ - len_plasma_electron_triton_mean_free_path_vol_avg, \ - len_plasma_electron_alpha_thermal_mean_free_path_profile, \ - len_plasma_electron_alpha_thermal_mean_free_path_vol_avg, \ - res_plasma_fuel_spitzer_profile, \ - res_plasma_fuel_spitzer_vol_avg - - m_beam_amu = 0.0 - m_fuel_amu = 0.0 - m_ions_total_amu = 0.0 - m_plasma_fuel_ions = 0.0 - m_plasma_ions_total = 0.0 - m_plasma_alpha = 0.0 - m_plasma_electron = 0.0 - m_plasma = 0.0 - alphaj = 1.0 - i_alphaj = 0 - alphan = 0.25 - alphap = 0.0 - fusden_alpha_total = 0.0 - fusden_plasma_alpha = 0.0 - alphat = 0.5 - aspect = 2.907 - beamfus0 = 1.0 - beta_total_vol_avg = 0.042 - beta_fast_alpha = 0.0 - beta_vol_avg_max = 0.0 - beta_vol_avg_min = 0.0 - beta_beam = 0.0 - beta_poloidal_vol_avg = 0.0 - beta_poloidal_eps = 0.0 - beta_toroidal_vol_avg = 0.0 - beta_thermal_toroidal_profile = [] - beta_thermal_vol_avg = 0.0 - beta_thermal_poloidal_vol_avg = 0.0 - beta_thermal_toroidal_vol_avg = 0.0 - beta_norm_total = 0.0 - beta_norm_thermal = 0.0 - beta_norm_poloidal = 0.0 - e_plasma_beta_thermal = 0.0 - beta_norm_toroidal = 0.0 - betbm0 = 1.5 - b_plasma_surface_poloidal_average = 0.0 - b_plasma_toroidal_on_axis = 5.68 - b_plasma_toroidal_inboard = 0.0 - b_plasma_toroidal_outboard = 0.0 - b_plasma_toroidal_profile = [] - b_plasma_total = 0.0 - e_plasma_magnetic_stored = 0.0 - burnup = 0.0 - burnup_in = 0.0 - b_plasma_vertical_required = 0.0 - c_beta = 0.5 - csawth = 1.0 - f_vol_plasma = 1.0 - f_r_conducting_wall = 1.35 - nd_plasma_electrons_vol_avg = 9.8e19 - nd_plasma_fuel_ions_vol_avg = 0.0 - dlamee = 0.0 - dlamie = 0.0 - nd_plasma_electron_max_array = np.zeros(8, dtype=np.float64) - nd_plasma_alphas_vol_avg = 0.0 - nd_beam_ions = 0.0 - nd_beam_ions_out = 0.0 - beta_norm_max = 3.5 - beta_norm_max_wesson = 0.0 - beta_norm_max_menard = 0.0 - beta_norm_max_original_scaling = 0.0 - beta_norm_max_tholerus = 0.0 - beta_norm_max_stambaugh = 0.0 - nd_plasma_electrons_max = 0.0 - nd_plasma_ions_total_vol_avg = 0.0 - nd_plasma_electron_line = 0.0 - nd_plasma_protons_vol_avg = 0.0 - ntau = 0.0 - nTtau = 0.0 - nd_plasma_impurities_vol_avg = 0.0 - beta_poloidal_eps_max = 1.38 - eps = 0.34399724802 - f_c_plasma_auxiliary = 0.0 - f_c_plasma_inductive = 0.0 - f_alpha_electron = 0.0 - f_p_alpha_plasma_deposited = 0.95 - f_alpha_ion = 0.0 - f_plasma_fuel_deuterium = 0.5 - f_p_div_lower = 1.0 - ffwal = 0.92 - f_nd_plasma_pedestal_greenwald = 0.85 - f_nd_plasma_separatrix_greenwald = 0.50 - f_plasma_fuel_helium3 = 0.0 - figmer = 0.0 - fkzohm = 1.0 - f_plasma_fuel_tritium = 0.5 - fusden_total = 0.0 - fusrat_total = 0.0 - fusrat_plasma_dt_profile = [] - fusrat_plasma_dd_triton_profile = [] - fusrat_plasma_dd_helion_profile = [] - fusrat_plasma_dhe3_profile = [] - fusden_plasma = 0.0 - f_c_plasma_non_inductive = 1.0 - ejima_coeff = 0.4 - f_beta_alpha_beam_thermal = 0.0 - hfac = np.zeros(N_CONFINEMENT_SCALINGS, dtype=np.float64) - hfact = 1.0 - hstar = 1.0 - t_plasma_energy_confinement_max = 10.0 - i_bootstrap_current = 3 - i_beta_component = 0 - i_plasma_current = 4 - i_diamagnetic_current = 0 - i_density_limit = 8 - i_beta_fast_alpha = 1 - i_plasma_ignited = 0 - i_plasma_pedestal = 1 - i_pfirsch_schluter_current = 0 - nd_plasma_pedestal_electron = 4.0e19 - nd_plasma_separatrix_electron = 3.0e19 - alpha_crit = 0.0 - nd_plasma_separatrix_electron_eich_max = 0.0 - plasma_res_factor = 1.0 - radius_plasma_pedestal_density_norm = 1.0 - radius_plasma_pedestal_temp_norm = 1.0 - tbeta = 2.0 - temp_plasma_pedestal_kev = 1.0 - temp_plasma_separatrix_kev = 0.1 - i_beta_norm_max = 1 - i_rad_loss = 1 - i_confinement_time = 34 - i_plasma_wall_gap = 1 - i_plasma_geometry = 0 - i_plasma_shape = 0 - itart = 0 - itartpf = 0 - i_pflux_fw_neutron = 1 - plasma_square = 0.0 - kappa = 1.792 - kappa95 = 1.6 - kappa_ipb = 0.0 - nd_plasma_electron_on_axis = 0.0 - nd_plasma_ions_on_axis = 0.0 - m_s_limit = 0.3 - pres_plasma_thermal_on_axis = 0.0 - pres_plasma_thermal_total_profile = [] - pres_plasma_electron_profile = [] - pres_plasma_ion_total_profile = [] - pres_plasma_fuel_profile = [] - j_plasma_on_axis = 0.0 - j_plasma_bootstrap_sauter_profile = [] - n_plasma_profile_elements = 500 - f_dd_branching_trit = 0.0 - pden_plasma_alpha_mw = 0.0 - pden_alpha_total_mw = 0.0 - f_pden_alpha_electron_mw = 0.0 - p_fw_alpha_mw = 0.0 - f_pden_alpha_ions_mw = 0.0 - p_alpha_total_mw = 0.0 - p_plasma_alpha_mw = 0.0 - p_beam_alpha_mw = 0.0 - p_beam_neutron_mw = 0.0 - p_beam_dt_mw = 0.0 - p_non_alpha_charged_mw = 0.0 - pden_non_alpha_charged_mw = 0.0 - f_temp_plasma_electron_density_vol_avg = 0.0 - p_plasma_inner_rad_mw = 0.0 - pden_plasma_core_rad_mw = 0.0 - 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_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 - p_div_separatrix_max_mw = 0.0 - p_dt_total_mw = 0.0 - p_plasma_dt_mw = 0.0 - p_plasma_outer_rad_mw = 0.0 - pden_plasma_outer_rad_mw = 0.0 - p_charged_particle_mw = 0.0 - vs_plasma_internal = 0.0 - pflux_fw_rad_mw = 0.0 - pden_ion_electron_equilibration_mw = 0.0 - plasma_current = 0.0 - c_plasma_peng_analytic = 0.0 - c_plasma_peng_double_null = 0.0 - c_plasma_cyclindrical = 0.0 - c_plasma_ipdg89 = 0.0 - c_plasma_todd_empirical_i = 0.0 - c_plasma_todd_empirical_ii = 0.0 - c_plasma_connor_hastie = 0.0 - c_plasma_sauter = 0.0 - c_plasma_fiesta_st = 0.0 - p_plasma_neutron_mw = 0.0 - p_neutron_total_mw = 0.0 - pden_neutron_total_mw = 0.0 - pden_plasma_neutron_mw = 0.0 - p_plasma_ohmic_mw = 0.0 - pden_plasma_ohmic_mw = 0.0 - p_plasma_loss_mw = 0.0 - p_fusion_total_mw = 0.0 - len_plasma_poloidal = 0.0 - p_plasma_rad_mw = 0.0 - pden_plasma_rad_mw = 0.0 - pradsolmw = 0.0 - proton_rate_density = 0.0 - psolradmw = 0.0 - pden_plasma_sync_mw = 0.0 - p_plasma_sync_mw = 0.0 - i_l_h_threshold = 19 - p_l_h_threshold_mw = 0.0 - l_h_threshold_powers = np.zeros(21, dtype=np.float64) - p_electron_transport_loss_mw = 0.0 - pden_electron_transport_loss_mw = 0.0 - p_ion_transport_loss_mw = 0.0 - pscalingmw = 0.0 - pden_ion_transport_loss_mw = 0.0 - q0 = 1.0 - q95 = 0.0 - molflow_plasma_fuelling_required = 0.0 - tauratio = 1.0 - q95_min = 0.0 - qstar = 0.0 - rad_fraction_sol = 0.8 - rad_fraction_total = 0.0 - f_nd_alpha_electron = 0.1 - f_nd_protium_electrons = 0.0 - ind_plasma_internal_norm = 0.9 - ind_plasma_internal_norm_wesson = 0.0 - ind_plasma_internal_norm_menard = 0.0 - ind_plasma_internal_norm_iter_3 = 0.0 - i_ind_plasma_internal_norm = 0 - ind_plasma = 0.0 - rmajor = 8.14 - rminor = 0.0 - f_nd_beam_electron = 0.005 - f_nd_plasma_carbon_electron = 0.0 - rndfuel = 0.0 - f_nd_plasma_iron_argon_electron = 0.0 - f_nd_plasma_oxygen_electron = 0.0 - f_res_plasma_neo = 0.0 - res_plasma = 0.0 - rho_plasma_spitzer_classical_profile = [] - t_plasma_res_diffusion = 0.0 - a_plasma_surface = 0.0 - a_plasma_surface_outboard = 0.0 - i_single_null = 1 - f_sync_reflect = 0.6 - t_electron_energy_confinement = 0.0 - tauee_in = 0.0 - t_energy_confinement = 0.0 - t_ion_energy_confinement = 0.0 - t_alpha_confinement = 0.0 - f_alpha_energy_confinement = 0.0 - temp_plasma_electron_vol_avg_kev = 12.9 - temp_plasma_electron_on_axis_kev = 0.0 - temp_plasma_electron_density_weighted_kev = 0.0 - temp_plasma_ion_vol_avg_kev = 12.9 - temp_plasma_ion_on_axis_kev = 0.0 - temp_plasma_ion_density_weighted_kev = 0.0 - f_temp_plasma_ion_electron = 1.0 - triang = 0.36 - triang95 = 0.24 - vol_plasma = 0.0 - vs_plasma_burn_required = 0.0 - vs_plasma_ramp_required = 0.0 - v_plasma_loop_burn = 0.0 - vs_plasma_ind_ramp = 0.0 - vs_plasma_res_ramp = 0.0 - vs_plasma_total_required = 0.0 - pflux_fw_neutron_mw = 0.0 - pflux_plasma_surface_neutron_avg_mw = 0.0 - wtgpd = 0.0 - a_plasma_poloidal = 0.0 - n_charge_plasma_effective_vol_avg = 0.0 - n_charge_plasma_effective_profile = [] - n_charge_plasma_effective_mass_weighted_vol_avg = 0.0 - len_plasma_debye_electron_profile = [] - radius_plasma_deuteron_toroidal_larmor_isotropic_profile = [] - radius_plasma_deuteron_toroidal_larmor_isotropic_vol_avg = 0.0 - radius_plasma_triton_toroidal_larmor_isotropic_profile = [] - radius_plasma_triton_toroidal_larmor_isotropic_vol_avg = 0.0 - len_plasma_debye_electron_vol_avg = 0.0 - vel_plasma_electron_profile = [] - vel_plasma_electron_vol_avg = 0.0 - vel_plasma_deuteron_profile = [] - vel_plasma_deuteron_vol_avg = 0.0 - vel_plasma_triton_profile = [] - vel_plasma_triton_vol_avg = 0.0 - vel_plasma_alpha_thermal_profile = [] - vel_plasma_alpha_thermal_vol_avg = 0.0 - vel_plasma_alpha_birth = 0.0 - plasma_coulomb_log_electron_electron_profile = [] - plasma_coulomb_log_electron_electron_vol_avg = 0.0 - plasma_coulomb_log_electron_deuteron_profile = [] - plasma_coulomb_log_electron_deuteron_vol_avg = 0.0 - plasma_coulomb_log_electron_triton_profile = [] - plasma_coulomb_log_electron_triton_vol_avg = 0.0 - plasma_coulomb_log_deuteron_triton_profile = [] - plasma_coulomb_log_deuteron_triton_vol_avg = 0.0 - plasma_coulomb_log_electron_alpha_thermal_profile = [] - plasma_coulomb_log_electron_alpha_thermal_vol_avg = 0.0 - freq_plasma_electron_profile = [] - freq_plasma_electron_vol_avg = 0.0 - freq_plasma_deuteron_profile = [] - freq_plasma_larmor_toroidal_electron_profile = [] - freq_plasma_larmor_toroidal_deuteron_profile = [] - freq_plasma_larmor_toroidal_triton_profile = [] - freq_plasma_upper_hybrid_profile = [] - freq_plasma_upper_hybrid_vol_avg = 0.0 - t_plasma_electron_electron_collision_profile = [] - t_plasma_electron_electron_collision_vol_avg = 0.0 - t_plasma_electron_deuteron_collision_profile = [] - t_plasma_electron_deuteron_collision_vol_avg = 0.0 - t_plasma_electron_triton_collision_profile = [] - t_plasma_electron_triton_collision_vol_avg = 0.0 - t_plasma_electron_alpha_thermal_collision_profile = [] - t_plasma_electron_alpha_thermal_collision_vol_avg = 0.0 - t_plasma_electron_alpha_spitzer_slow_profile = [] - t_plasma_electron_alpha_spitzer_slow_vol_avg = 0.0 - freq_plasma_electron_electron_collision_profile = [] - freq_plasma_electron_electron_collision_vol_avg = 0.0 - freq_plasma_electron_deuteron_collision_profile = [] - freq_plasma_electron_deuteron_collision_vol_avg = 0.0 - freq_plasma_electron_triton_collision_profile = [] - freq_plasma_electron_triton_collision_vol_avg = 0.0 - freq_plasma_electron_alpha_thermal_collision_profile = [] - freq_plasma_electron_alpha_thermal_collision_vol_avg = 0.0 - len_plasma_electron_electron_mean_free_path_profile = [] - len_plasma_electron_electron_mean_free_path_vol_avg = 0.0 - len_plasma_electron_deuteron_mean_free_path_profile = [] - len_plasma_electron_deuteron_mean_free_path_vol_avg = 0.0 - len_plasma_electron_triton_mean_free_path_profile = [] - len_plasma_electron_triton_mean_free_path_vol_avg = 0.0 - len_plasma_electron_alpha_thermal_mean_free_path_profile = [] - len_plasma_electron_alpha_thermal_mean_free_path_vol_avg = 0.0 - res_plasma_fuel_spitzer_profile = [] - res_plasma_fuel_spitzer_vol_avg = 0.0 +CREATE_DICTS_FROM_DATACLASS = PhysicsData diff --git a/process/main.py b/process/main.py index 22244f0cd3..f20e4b1d24 100644 --- a/process/main.py +++ b/process/main.py @@ -82,6 +82,7 @@ ) from process.models.physics.density_limit import PlasmaDensityLimit from process.models.physics.exhaust import PlasmaExhaust +from process.models.physics.fusion_reactions import FusionReactionRate from process.models.physics.impurity_radiation import initialise_imprad from process.models.physics.l_h_transition import PlasmaConfinementTransition from process.models.physics.physics import ( @@ -94,6 +95,7 @@ from process.models.physics.plasma_fields import PlasmaFields from process.models.physics.plasma_geometry import PlasmaGeom from process.models.physics.plasma_profiles import PlasmaProfile +from process.models.physics.profiles import NeProfile, TeProfile from process.models.power import Power from process.models.pulse import Pulse from process.models.shield import Shield @@ -614,7 +616,9 @@ def __init__(self, data: DataStructure): self.pulse = Pulse() self.shield = Shield() self.ife = IFE(availability=self.availability, costs=self.costs) - self.plasma_profile = PlasmaProfile() + self.ne_profile = NeProfile() + self.te_profile = TeProfile() + self.plasma_profile = PlasmaProfile(self.ne_profile, self.te_profile) self.fw = FirstWall() self.blanket_library = BlanketLibrary(fw=self.fw) self.ccfe_hcpb = CCFE_HCPB(fw=self.fw) @@ -674,6 +678,9 @@ def __init__(self, data: DataStructure): ) self.dcll = DCLL(fw=self.fw) + self.fusion_reaction_rate = FusionReactionRate( + plasma_profile=self.plasma_profile + ) self.setup_data_structure() @@ -745,6 +752,8 @@ def models(self) -> tuple[Model, ...]: self.stellarator, self.plasma_current, self.neoclassics, + self.plasma_inductance, + self.fusion_reaction_rate, ) def setup_data_structure(self): diff --git a/process/models/availability.py b/process/models/availability.py index 83a1e65d7a..655df5bcab 100644 --- a/process/models/availability.py +++ b/process/models/availability.py @@ -7,7 +7,6 @@ from process.core import process_output as po from process.core.exceptions import ProcessValueError from process.core.model import Model -from process.data_structure import physics_variables as pv from process.data_structure import tfcoil_variables as tfv from process.models.tfcoil.base import TFConductorModel @@ -61,7 +60,7 @@ def run(self, output: bool = False): indicate whether output should be written to the output file, or not (default = False) """ if self.data.costs.i_plant_availability == 3: - if pv.itart != 1: + if self.data.physics.itart != 1: raise ProcessValueError( f"{self.data.costs.i_plant_availability=} is for a Spherical Tokamak. Please set itart=1 to use this model." ) @@ -96,7 +95,7 @@ def avail(self, output: bool): # - all of the above and more leading to the dpa/fpy in EUROfer at the FW OMP # About a relatively "constant" reference point, we can reasonably assume they all equal to 1.0. ref_fusion_power = 2.0e3 # (MW) fusion power for EU-DEMO - f_scale = pv.p_fusion_total_mw / ref_fusion_power + f_scale = self.data.physics.p_fusion_total_mw / ref_fusion_power ref_dpa_fpy = ( 10.0e0 # dpa per fpy from T. Franke 2020 states up to 10 dpa/FPY ) @@ -111,9 +110,12 @@ def avail(self, output: bool): if self.data.costs.ibkt_life == 0: self.data.fwbs.life_blkt_fpy = ( self.data.costs.life_plant - if pv.pflux_fw_neutron_mw == 0.0 # noqa: RUF069 + if self.data.physics.pflux_fw_neutron_mw == 0.0 # noqa: RUF069 else min( - (self.data.costs.abktflnc / pv.pflux_fw_neutron_mw), + ( + self.data.costs.abktflnc + / self.data.physics.pflux_fw_neutron_mw + ), self.data.costs.life_plant, ) ) @@ -124,7 +126,7 @@ def avail(self, output: bool): elif self.data.costs.ibkt_life == 0: self.data.fwbs.life_blkt_fpy = min( self.data.fwbs.life_fw_fpy, - self.data.costs.abktflnc / pv.pflux_fw_neutron_mw, + self.data.costs.abktflnc / self.data.physics.pflux_fw_neutron_mw, self.data.costs.life_plant, ) else: @@ -144,7 +146,7 @@ def avail(self, output: bool): self.data.costs.life_div_fpy = self.divertor_lifetime() # Centrepost lifetime (years) (ST machines only) - if pv.itart == 1: + if self.data.physics.itart == 1: self.data.costs.cplife = self.cp_lifetime() # Plant Availability (i_plant_availability=0,1) @@ -215,7 +217,10 @@ def avail(self, output: bool): ) # Centrepost - if pv.itart == 1 and self.data.costs.cplife < self.data.costs.life_plant: + if ( + self.data.physics.itart == 1 + and self.data.costs.cplife < self.data.costs.life_plant + ): self.data.costs.cplife = min( self.data.costs.cplife / self.data.costs.f_t_plant_available, self.data.costs.life_plant, @@ -256,7 +261,7 @@ def avail(self, output: bool): "OP ", ) - if pv.itart == 1: + if self.data.physics.itart == 1: po.ovarre( self.outfile, "Centrepost lifetime (years)", @@ -425,7 +430,10 @@ def avail_2(self, output: bool): ) # Centrepost - if pv.itart == 1 and self.data.costs.cplife < self.data.costs.life_plant: + if ( + self.data.physics.itart == 1 + and self.data.costs.cplife < self.data.costs.life_plant + ): self.data.costs.cplife = min( self.data.costs.cplife / self.data.costs.f_t_plant_available, self.data.costs.life_plant, @@ -452,7 +460,7 @@ def avail_2(self, output: bool): self.data.costs.life_div_fpy, "OP ", ) - if pv.itart == 1: + if self.data.physics.itart == 1: po.ovarre( self.outfile, "Centrepost lifetime (FPY)", @@ -537,7 +545,7 @@ def calc_u_planned(self, output: bool) -> float: # - all of the above and more leading to the dpa/fpy in EUROfer at the FW OMP # About a relatively "constant" reference point, we can reasonably assume they all equal to 1.0. ref_fusion_power = 2.0e3 # (MW) fusion power for EU-DEMO - f_scale = pv.p_fusion_total_mw / ref_fusion_power + f_scale = self.data.physics.p_fusion_total_mw / ref_fusion_power ref_dpa_fpy = 10.0e0 # dpa per fpy from T. Franke 2020 states up to 10 dpa/FPY dpa_fpy = f_scale * ref_dpa_fpy @@ -546,7 +554,7 @@ def calc_u_planned(self, output: bool) -> float: # or DEMO fusion power model (ibkt_life=1) if self.data.costs.ibkt_life == 0: self.data.fwbs.life_blkt_fpy = min( - self.data.costs.abktflnc / pv.pflux_fw_neutron_mw, + self.data.costs.abktflnc / self.data.physics.pflux_fw_neutron_mw, self.data.costs.life_plant, ) else: @@ -558,7 +566,7 @@ def calc_u_planned(self, output: bool) -> float: self.data.costs.life_div_fpy = self.divertor_lifetime() # Centrepost lifetime (years) (ST only) - if pv.itart == 1: + if self.data.physics.itart == 1: self.data.costs.cplife = self.cp_lifetime() # Current drive lifetime (assumed equal to first wall and blanket lifetime) @@ -1173,13 +1181,13 @@ def avail_st(self, output: bool): https://www.sciencedirect.com/science/article/pii/S0920379620301952#bib0075 """ ref_powfmw = 2.0e3 # (MW) fusion power for EU-DEMO - f_scale = pv.p_fusion_total_mw / ref_powfmw + f_scale = self.data.physics.p_fusion_total_mw / ref_powfmw ref_dpa_fpy = 10.0e0 # dpa per fpy from T. Franke 2020 states up to 10 dpa/FPY dpa_fpy = f_scale * ref_dpa_fpy if self.data.costs.ibkt_life == 0: self.data.fwbs.life_blkt_fpy = min( - self.data.costs.abktflnc / pv.pflux_fw_neutron_mw, + self.data.costs.abktflnc / self.data.physics.pflux_fw_neutron_mw, self.data.costs.life_plant, ) else: @@ -1286,7 +1294,10 @@ def avail_st(self, output: bool): ) # Centrepost - if pv.itart == 1 and self.data.costs.cplife < self.data.costs.life_plant: + if ( + self.data.physics.itart == 1 + and self.data.costs.cplife < self.data.costs.life_plant + ): self.data.costs.cplife = min( self.data.costs.cplife / self.data.costs.f_t_plant_available, self.data.costs.life_plant, @@ -1353,7 +1364,7 @@ def avail_st(self, output: bool): self.outfile, "Average neutron wall load (MW/m2)", "(pflux_fw_neutron_mw)", - pv.pflux_fw_neutron_mw, + self.data.physics.pflux_fw_neutron_mw, "OP ", ) po.ovarre( @@ -1466,7 +1477,7 @@ def cp_lifetime(self): # For now, we keep the original def, developed for GLIDCOP magnets ... else: cplife = min( - self.data.costs.cpstflnc / pv.pflux_fw_neutron_mw, + self.data.costs.cpstflnc / self.data.physics.pflux_fw_neutron_mw, self.data.costs.life_plant, ) diff --git a/process/models/blankets/blanket_library.py b/process/models/blankets/blanket_library.py index 98c5c41094..3327a6829b 100644 --- a/process/models/blankets/blanket_library.py +++ b/process/models/blankets/blanket_library.py @@ -10,9 +10,6 @@ from process.core.coolprop_interface import FluidProperties from process.core.exceptions import ProcessValueError from process.core.model import Model -from process.data_structure import ( - physics_variables, -) from process.models.build import FwBlktVVShape from process.models.engineering.ivc_functions import ( calculate_pipe_bend_radius, @@ -85,7 +82,7 @@ def component_volumes(self): # D-shaped blanket and shield if ( - physics_variables.itart == 1 + self.data.physics.itart == 1 or self.data.fwbs.i_fw_blkt_vv_shape == FwBlktVVShape.D_SHAPED ): ( @@ -98,7 +95,7 @@ def component_volumes(self): dr_blkt_inboard=self.data.build.dr_blkt_inboard, dr_fw_inboard=self.data.build.dr_fw_inboard, dr_fw_plasma_gap_inboard=self.data.build.dr_fw_plasma_gap_inboard, - rminor=physics_variables.rminor, + rminor=self.data.physics.rminor, dr_fw_plasma_gap_outboard=self.data.build.dr_fw_plasma_gap_outboard, dr_fw_outboard=self.data.build.dr_fw_outboard, dz_blkt_half=self.data.blanket.dz_blkt_half, @@ -114,7 +111,7 @@ def component_volumes(self): dr_blkt_inboard=self.data.build.dr_blkt_inboard, dr_fw_inboard=self.data.build.dr_fw_inboard, dr_fw_plasma_gap_inboard=self.data.build.dr_fw_plasma_gap_inboard, - rminor=physics_variables.rminor, + rminor=self.data.physics.rminor, dr_fw_plasma_gap_outboard=self.data.build.dr_fw_plasma_gap_outboard, dr_fw_outboard=self.data.build.dr_fw_outboard, dz_blkt_half=self.data.blanket.dz_blkt_half, @@ -129,9 +126,9 @@ def component_volumes(self): self.data.build.a_blkt_outboard_surface_full_coverage, self.data.build.a_blkt_total_surface_full_coverage, ) = self.calculate_elliptical_blkt_areas( - rmajor=physics_variables.rmajor, - rminor=physics_variables.rminor, - triang=physics_variables.triang, + rmajor=self.data.physics.rmajor, + rminor=self.data.physics.rminor, + triang=self.data.physics.triang, r_shld_inboard_inner=self.data.build.r_shld_inboard_inner, dr_shld_inboard=self.data.build.dr_shld_inboard, dr_blkt_inboard=self.data.build.dr_blkt_inboard, @@ -146,9 +143,9 @@ def component_volumes(self): self.data.fwbs.vol_blkt_outboard_full_coverage, self.data.fwbs.vol_blkt_total_full_coverage, ) = self.calculate_elliptical_blkt_volumes( - rmajor=physics_variables.rmajor, - rminor=physics_variables.rminor, - triang=physics_variables.triang, + rmajor=self.data.physics.rmajor, + rminor=self.data.physics.rminor, + triang=self.data.physics.triang, r_shld_inboard_inner=self.data.build.r_shld_inboard_inner, dr_shld_inboard=self.data.build.dr_shld_inboard, dr_blkt_inboard=self.data.build.dr_blkt_inboard, @@ -914,7 +911,7 @@ def set_blanket_module_geometry(self): self.data.fwbs.n_blkt_outboard_modules_poloidal = 1 if ( - physics_variables.itart == 1 + self.data.physics.itart == 1 or self.data.fwbs.i_fw_blkt_vv_shape == FwBlktVVShape.D_SHAPED ): self.data.blanket.len_blkt_inboard_segment_poloidal = self.calculate_dshaped_inboard_blkt_segment_poloidal( @@ -925,7 +922,7 @@ def set_blanket_module_geometry(self): self.data.blanket.len_blkt_outboard_segment_poloidal = self.calculate_dshaped_outboard_blkt_segment_poloidal( n_blkt_outboard_modules_poloidal=self.data.fwbs.n_blkt_outboard_modules_poloidal, dr_fw_plasma_gap_inboard=self.data.build.dr_fw_plasma_gap_inboard, - rminor=physics_variables.rminor, + rminor=self.data.physics.rminor, dr_fw_plasma_gap_outboard=self.data.build.dr_fw_plasma_gap_outboard, dz_blkt_half=self.data.blanket.dz_blkt_half, n_divertors=self.data.divertor.n_divertors, @@ -933,9 +930,9 @@ def set_blanket_module_geometry(self): ) else: self.data.blanket.len_blkt_inboard_segment_poloidal = self.calculate_elliptical_inboard_blkt_segment_poloidal( - rmajor=physics_variables.rmajor, - rminor=physics_variables.rminor, - triang=physics_variables.triang, + rmajor=self.data.physics.rmajor, + rminor=self.data.physics.rminor, + triang=self.data.physics.triang, dr_fw_plasma_gap_inboard=self.data.build.dr_fw_plasma_gap_inboard, dz_blkt_half=self.data.blanket.dz_blkt_half, n_blkt_inboard_modules_poloidal=self.data.fwbs.n_blkt_inboard_modules_poloidal, @@ -944,9 +941,9 @@ def set_blanket_module_geometry(self): ) self.data.blanket.len_blkt_outboard_segment_poloidal = self.calculate_elliptical_outboard_blkt_segment_poloidal( - rmajor=physics_variables.rmajor, - rminor=physics_variables.rminor, - triang=physics_variables.triang, + rmajor=self.data.physics.rmajor, + rminor=self.data.physics.rminor, + triang=self.data.physics.triang, dz_blkt_half=self.data.blanket.dz_blkt_half, dr_fw_plasma_gap_outboard=self.data.build.dr_fw_plasma_gap_outboard, n_blkt_outboard_modules_poloidal=self.data.fwbs.n_blkt_outboard_modules_poloidal, @@ -1829,31 +1826,31 @@ def liquid_breeder_properties(self, output: bool = False): # IB if self.data.fwbs.i_blkt_inboard == 1: self.data.fwbs.b_mag_blkt[0] = ( - physics_variables.b_plasma_toroidal_on_axis - * physics_variables.rmajor + self.data.physics.b_plasma_toroidal_on_axis + * self.data.physics.rmajor / ( - physics_variables.rmajor - - (physics_variables.rmajor / physics_variables.aspect) + self.data.physics.rmajor + - (self.data.physics.rmajor / self.data.physics.aspect) - (self.data.build.dr_blkt_inboard / 2) ) ) # We do not use this if there is no IB blanket, but will use edge as fill value if self.data.fwbs.i_blkt_inboard == 0: self.data.fwbs.b_mag_blkt[0] = ( - physics_variables.b_plasma_toroidal_on_axis - * physics_variables.rmajor + self.data.physics.b_plasma_toroidal_on_axis + * self.data.physics.rmajor / ( - physics_variables.rmajor - - (physics_variables.rmajor / physics_variables.aspect) + self.data.physics.rmajor + - (self.data.physics.rmajor / self.data.physics.aspect) ) ) # OB self.data.fwbs.b_mag_blkt[1] = ( - physics_variables.b_plasma_toroidal_on_axis - * physics_variables.rmajor + self.data.physics.b_plasma_toroidal_on_axis + * self.data.physics.rmajor / ( - physics_variables.rmajor - + (physics_variables.rmajor / physics_variables.aspect) + self.data.physics.rmajor + + (self.data.physics.rmajor / self.data.physics.aspect) + (self.data.build.dr_blkt_outboard / 2) ) ) diff --git a/process/models/blankets/dcll.py b/process/models/blankets/dcll.py index 521bb5c70c..5fc1ebb0d6 100644 --- a/process/models/blankets/dcll.py +++ b/process/models/blankets/dcll.py @@ -2,9 +2,6 @@ from process.core import ( process_output as po, ) -from process.data_structure import ( - physics_variables, -) from process.models.blankets.blanket_library import InboardBlanket, OutboardBlanket from process.models.engineering.ivc_functions import ( calculate_pipe_bend_radius, @@ -105,14 +102,14 @@ def run(self, output: bool = False): self.data.blanket.len_blkt_inboard_segment_toroidal = self.calculate_blanket_inboard_module_geometry( n_blkt_inboard_modules_toroidal=self.data.fwbs.n_blkt_inboard_modules_toroidal, - rmajor=physics_variables.rmajor, - rminor=physics_variables.rminor, + rmajor=self.data.physics.rmajor, + rminor=self.data.physics.rminor, dr_fw_plasma_gap_inboard=self.data.build.dr_fw_plasma_gap_inboard, ) self.data.blanket.len_blkt_outboard_segment_toroidal = self.calculate_blanket_outboard_module_geometry( n_blkt_outboard_modules_toroidal=self.data.fwbs.n_blkt_outboard_modules_toroidal, - rmajor=physics_variables.rmajor, - rminor=physics_variables.rminor, + rmajor=self.data.physics.rmajor, + rminor=self.data.physics.rminor, dr_fw_plasma_gap_outboard=self.data.build.dr_fw_plasma_gap_outboard, ) @@ -158,7 +155,7 @@ def dcll_neutronics_and_power(self, output: bool): # Nuclear heating in the first wall (MW) self.data.fwbs.p_fw_nuclear_heat_total_mw = ( - physics_variables.p_neutron_total_mw + self.data.physics.p_neutron_total_mw * self.data.fwbs.pnuc_fw_ratio_dcll * covf ) @@ -166,7 +163,7 @@ def dcll_neutronics_and_power(self, output: bool): # Nuclear heating in the blanket with energy multiplication (MW) self.data.fwbs.pnuc_blkt_ratio_dcll = 1 - self.data.fwbs.pnuc_fw_ratio_dcll self.data.fwbs.p_blkt_nuclear_heat_total_mw = ( - physics_variables.p_neutron_total_mw + self.data.physics.p_neutron_total_mw * self.data.fwbs.pnuc_blkt_ratio_dcll * self.data.fwbs.f_p_blkt_multiplication * covf @@ -174,7 +171,7 @@ def dcll_neutronics_and_power(self, output: bool): # Energy multiplication energy (MW) self.data.fwbs.p_blkt_multiplication_mw = ( - (physics_variables.p_neutron_total_mw * self.data.fwbs.pnuc_blkt_ratio_dcll) + (self.data.physics.p_neutron_total_mw * self.data.fwbs.pnuc_blkt_ratio_dcll) * (self.data.fwbs.f_p_blkt_multiplication - 1) * covf ) @@ -185,14 +182,14 @@ def dcll_neutronics_and_power(self, output: bool): self.data.fwbs.p_fw_hcd_nuclear_heat_mw = 0 # Radiation power incident on HCD apparatus (MW) self.data.fwbs.p_fw_hcd_rad_total_mw = ( - physics_variables.p_plasma_rad_mw * self.data.fwbs.f_a_fw_outboard_hcd + self.data.physics.p_plasma_rad_mw * self.data.fwbs.f_a_fw_outboard_hcd ) # FW # Radiation power incident on first wall (MW) self.data.fwbs.p_fw_rad_total_mw = ( - physics_variables.p_plasma_rad_mw + self.data.physics.p_plasma_rad_mw - self.data.fwbs.p_div_rad_total_mw - self.data.fwbs.p_fw_hcd_rad_total_mw ) @@ -204,7 +201,7 @@ def dcll_neutronics_and_power(self, output: bool): * self.data.first_wall.a_fw_outboard / self.data.first_wall.a_fw_total + self.data.current_drive.p_beam_orbit_loss_mw - + physics_variables.p_fw_alpha_mw + + self.data.physics.p_fw_alpha_mw ) self.data.fwbs.psurffwi = self.data.fwbs.p_fw_rad_total_mw * ( 1 - self.data.first_wall.a_fw_outboard / self.data.first_wall.a_fw_total @@ -322,7 +319,7 @@ def dcll_power_and_heating(self, output: bool): p_blkt_nuclear_heat_total_mw=self.data.fwbs.p_blkt_nuclear_heat_total_mw, p_shld_nuclear_heat_mw=self.data.fwbs.p_shld_nuclear_heat_mw, p_cp_shield_nuclear_heat_mw=self.data.fwbs.p_cp_shield_nuclear_heat_mw, - p_plasma_separatrix_mw=physics_variables.p_plasma_separatrix_mw, + p_plasma_separatrix_mw=self.data.physics.p_plasma_separatrix_mw, p_div_nuclear_heat_total_mw=self.data.fwbs.p_div_nuclear_heat_total_mw, p_div_rad_total_mw=self.data.fwbs.p_div_rad_total_mw, ) @@ -337,7 +334,7 @@ def dcll_power_and_heating(self, output: bool): self.data.heat_transport.p_div_coolant_pump_mw = ( self.data.heat_transport.f_p_div_coolant_pump_total_heat * ( - physics_variables.p_plasma_separatrix_mw + self.data.physics.p_plasma_separatrix_mw + self.data.fwbs.p_div_nuclear_heat_total_mw + self.data.fwbs.p_div_rad_total_mw ) @@ -721,7 +718,7 @@ def dcll_masses(self, output: bool): ) # First wall armour volume (m^3) self.data.fwbs.fw_armour_vol = ( - physics_variables.a_plasma_surface * self.data.fwbs.fw_armour_thickness + self.data.physics.a_plasma_surface * self.data.fwbs.fw_armour_thickness ) # First wall armour mass (kg) self.data.fwbs.fw_armour_mass = ( @@ -762,8 +759,8 @@ def dcll_masses(self, output: bool): + self.data.fwbs.fw_armour_mass * ( ( - physics_variables.a_plasma_surface - - physics_variables.a_plasma_surface_outboard + self.data.physics.a_plasma_surface + - self.data.physics.a_plasma_surface_outboard ) * self.data.fwbs.fw_armour_thickness / self.data.fwbs.fw_armour_vol @@ -781,7 +778,7 @@ def dcll_masses(self, output: bool): ) + self.data.fwbs.fw_armour_mass * ( - physics_variables.a_plasma_surface_outboard + self.data.physics.a_plasma_surface_outboard * self.data.fwbs.fw_armour_thickness / self.data.fwbs.fw_armour_vol ) diff --git a/process/models/blankets/hcpb.py b/process/models/blankets/hcpb.py index 455990b8e5..b27840c424 100644 --- a/process/models/blankets/hcpb.py +++ b/process/models/blankets/hcpb.py @@ -8,10 +8,7 @@ ) from process.core.coolprop_interface import FluidProperties from process.core.exceptions import ProcessValueError -from process.data_structure import ( - physics_variables, - tfcoil_variables, -) +from process.data_structure import tfcoil_variables from process.models.blankets.blanket_library import InboardBlanket, OutboardBlanket from process.models.engineering.ivc_functions import ( calculate_pipe_bend_radius, @@ -61,24 +58,24 @@ def run(self, output: bool = False): self.data.blanket.len_blkt_inboard_segment_toroidal = self.calculate_blanket_inboard_module_geometry( n_blkt_inboard_modules_toroidal=self.data.fwbs.n_blkt_inboard_modules_toroidal, - rmajor=physics_variables.rmajor, - rminor=physics_variables.rminor, + rmajor=self.data.physics.rmajor, + rminor=self.data.physics.rminor, dr_fw_plasma_gap_inboard=self.data.build.dr_fw_plasma_gap_inboard, ) self.data.blanket.len_blkt_outboard_segment_toroidal = self.calculate_blanket_outboard_module_geometry( n_blkt_outboard_modules_toroidal=self.data.fwbs.n_blkt_outboard_modules_toroidal, - rmajor=physics_variables.rmajor, - rminor=physics_variables.rminor, + rmajor=self.data.physics.rmajor, + rminor=self.data.physics.rminor, dr_fw_plasma_gap_outboard=self.data.build.dr_fw_plasma_gap_outboard, ) # Centrepost neutronics - if physics_variables.itart == 1: + if self.data.physics.itart == 1: # CP radius at the point of maximum sield radius [m] # The maximum shield radius is assumed to be at the X-point r_sh_inboard_out_top = ( - physics_variables.rmajor - - physics_variables.rminor * physics_variables.triang + self.data.physics.rmajor + - self.data.physics.rminor * self.data.physics.triang - 3 * self.data.build.dr_fw_plasma_gap_inboard ) @@ -94,14 +91,14 @@ def run(self, output: bool = False): h_sh_max_r, self.data.build.r_sh_inboard_out, r_sh_inboard_out_top, - physics_variables.rmajor, + self.data.physics.rmajor, ) # TF fast neutron flux (E > 0.1 MeV) [m^{-2}.s^{-1}] self.data.fwbs.neut_flux_cp = self.st_tf_centrepost_fast_neut_flux( - physics_variables.p_neutron_total_mw, + self.data.physics.p_neutron_total_mw, self.data.build.dr_shld_inboard, - physics_variables.rmajor, + self.data.physics.rmajor, ) # TF, shield and total CP nuclear heating [MW] @@ -110,7 +107,7 @@ def run(self, output: bool = False): self.data.fwbs.p_cp_shield_nuclear_heat_mw, self.data.fwbs.pnuc_cp, ) = self.st_centrepost_nuclear_heating( - physics_variables.p_neutron_total_mw, self.data.build.dr_shld_inboard + self.data.physics.p_neutron_total_mw, self.data.build.dr_shld_inboard ) else: # No CP @@ -130,13 +127,13 @@ def run(self, output: bool = False): self.data.fwbs.p_fw_nuclear_heat_total_mw = self.nuclear_heating_fw( m_fw_total=self.data.fwbs.m_fw_total, fw_armour_u_nuc_heating=self.data.ccfe_hcpb.fw_armour_u_nuc_heating, - p_fusion_total_mw=physics_variables.p_fusion_total_mw, + p_fusion_total_mw=self.data.physics.p_fusion_total_mw, ) self.data.fwbs.p_blkt_nuclear_heat_total_mw, self.data.ccfe_hcpb.exp_blanket = ( self.nuclear_heating_blanket( m_blkt_total=self.data.fwbs.m_blkt_total, - p_fusion_total_mw=physics_variables.p_fusion_total_mw, + p_fusion_total_mw=self.data.physics.p_fusion_total_mw, ) ) ( @@ -145,13 +142,13 @@ def run(self, output: bool = False): self.data.ccfe_hcpb.exp_shield2, self.data.ccfe_hcpb.shld_u_nuc_heating, ) = self.nuclear_heating_shield( - itart=physics_variables.itart, + itart=self.data.physics.itart, dr_shld_outboard=self.data.build.dr_shld_outboard, dr_shld_inboard=self.data.build.dr_shld_inboard, shield_density=self.data.ccfe_hcpb.shield_density, whtshld=self.data.fwbs.whtshld, x_blanket=self.data.ccfe_hcpb.x_blanket, - p_fusion_total_mw=physics_variables.p_fusion_total_mw, + p_fusion_total_mw=self.data.physics.p_fusion_total_mw, ) # Normalisation of the nuclear heating @@ -193,7 +190,7 @@ def run(self, output: bool = False): ) * self.data.fwbs.f_p_blkt_multiplication * f_geom_blanket - * physics_variables.p_neutron_total_mw + * self.data.physics.p_neutron_total_mw ) # Power to the blanket (MW) @@ -204,7 +201,7 @@ def run(self, output: bool = False): ) * self.data.fwbs.f_p_blkt_multiplication * f_geom_blanket - * physics_variables.p_neutron_total_mw + * self.data.physics.p_neutron_total_mw ) # Power to the shield(MW) @@ -216,7 +213,7 @@ def run(self, output: bool = False): ) * self.data.fwbs.f_p_blkt_multiplication * f_geom_blanket - * physics_variables.p_neutron_total_mw + * self.data.physics.p_neutron_total_mw ) # Power to the TF coils (MW) @@ -228,20 +225,20 @@ def run(self, output: bool = False): ) * self.data.fwbs.f_p_blkt_multiplication * f_geom_blanket - * physics_variables.p_neutron_total_mw + * self.data.physics.p_neutron_total_mw + self.data.fwbs.pnuc_cp_tf ) # Power deposited in the CP self.data.fwbs.p_cp_shield_nuclear_heat_mw = ( - f_geom_cp * physics_variables.p_neutron_total_mw - self.data.fwbs.pnuc_cp_tf + f_geom_cp * self.data.physics.p_neutron_total_mw - self.data.fwbs.pnuc_cp_tf ) # New code, a bit simpler self.data.fwbs.p_blkt_multiplication_mw = ( (self.data.fwbs.f_p_blkt_multiplication - 1) * f_geom_blanket - * physics_variables.p_neutron_total_mw + * self.data.physics.p_neutron_total_mw ) # powerflow calculation for pumping power @@ -319,8 +316,8 @@ def component_masses(self): self.data.divertor.fdiva * 2.0 * np.pi - * physics_variables.rmajor - * physics_variables.rminor + * self.data.physics.rmajor + * self.data.physics.rminor ) if self.data.divertor.n_divertors == 2: self.data.divertor.a_div_surface_total *= 2.0 @@ -358,7 +355,7 @@ def component_masses(self): # First wall armour volume (m^3) self.data.fwbs.fw_armour_vol = ( - physics_variables.a_plasma_surface * self.data.fwbs.fw_armour_thickness + self.data.physics.a_plasma_surface * self.data.fwbs.fw_armour_thickness ) # First wall armour mass (kg) @@ -477,7 +474,7 @@ def nuclear_heating_magnets(self, output: bool): self.data.ccfe_hcpb.vv_density = 0.0 # Calculation of average blanket/shield thickness [m] - if physics_variables.itart == 1: + if self.data.physics.itart == 1: # There is no inner blanket for TART design [m] th_blanket_av = self.data.build.dr_blkt_outboard @@ -514,7 +511,7 @@ def nuclear_heating_magnets(self, output: bool): ) / 1000.0 # If spherical tokamak, this is outboard only. pnuc_cp_tf is evaluated separately - if physics_variables.itart == 1: + if self.data.physics.itart == 1: # Nuclear heating in outobard TF coil legs (whttflgs) # Unit heating (W/kg/GW of fusion power) x legs mass only (kg) self.data.ccfe_hcpb.tfc_nuc_heating = ( @@ -536,7 +533,7 @@ def nuclear_heating_magnets(self, output: bool): # Total heating (MW) self.data.fwbs.p_tf_nuclear_heat_mw = ( self.data.ccfe_hcpb.tfc_nuc_heating - * (physics_variables.p_fusion_total_mw / 1000.0) + * (self.data.physics.p_fusion_total_mw / 1000.0) / 1.0e6 ) @@ -570,7 +567,7 @@ def nuclear_heating_magnets(self, output: bool): self.outfile, "p_fusion_total_mw", "(p_fusion_total_mw.)", - physics_variables.p_fusion_total_mw, + self.data.physics.p_fusion_total_mw, ) po.ovarre( self.outfile, @@ -744,12 +741,12 @@ def powerflow_calc(self, output: bool): """ # Radiation power incident on HCD apparatus (MW) self.data.fwbs.p_fw_hcd_rad_total_mw = ( - physics_variables.p_plasma_rad_mw * self.data.fwbs.f_a_fw_outboard_hcd + self.data.physics.p_plasma_rad_mw * self.data.fwbs.f_a_fw_outboard_hcd ) # Radiation power incident on first wall (MW) self.data.fwbs.p_fw_rad_total_mw = ( - physics_variables.p_plasma_rad_mw + self.data.physics.p_plasma_rad_mw - self.data.fwbs.p_div_rad_total_mw - self.data.fwbs.p_fw_hcd_rad_total_mw ) @@ -773,7 +770,7 @@ def powerflow_calc(self, output: bool): * self.data.first_wall.a_fw_outboard / self.data.first_wall.a_fw_total + self.data.current_drive.p_beam_orbit_loss_mw - + physics_variables.p_fw_alpha_mw + + self.data.physics.p_fw_alpha_mw ) self.data.fwbs.psurffwi = self.data.fwbs.p_fw_rad_total_mw * ( 1 - self.data.first_wall.a_fw_outboard / self.data.first_wall.a_fw_total @@ -798,7 +795,7 @@ def powerflow_calc(self, output: bool): p_blkt_nuclear_heat_total_mw=self.data.fwbs.p_blkt_nuclear_heat_total_mw, p_shld_nuclear_heat_mw=self.data.heat_transport.p_shld_nuclear_heat_mw, p_cp_shield_nuclear_heat_mw=self.data.fwbs.p_cp_shield_nuclear_heat_mw, - p_plasma_separatrix_mw=physics_variables.p_plasma_separatrix_mw, + p_plasma_separatrix_mw=self.data.physics.p_plasma_separatrix_mw, p_div_nuclear_heat_total_mw=self.data.fwbs.p_div_nuclear_heat_total_mw, p_div_rad_total_mw=self.data.fwbs.p_div_rad_total_mw, ) @@ -821,7 +818,7 @@ def powerflow_calc(self, output: bool): self.data.heat_transport.p_div_coolant_pump_mw = ( self.data.heat_transport.f_p_div_coolant_pump_total_heat * ( - physics_variables.p_plasma_separatrix_mw + self.data.physics.p_plasma_separatrix_mw + self.data.fwbs.p_div_nuclear_heat_total_mw + self.data.fwbs.p_div_rad_total_mw ) @@ -876,7 +873,7 @@ def powerflow_calc(self, output: bool): self.data.heat_transport.p_div_coolant_pump_mw = ( self.data.heat_transport.f_p_div_coolant_pump_total_heat * ( - physics_variables.p_plasma_separatrix_mw + self.data.physics.p_plasma_separatrix_mw + self.data.fwbs.p_div_nuclear_heat_total_mw + self.data.fwbs.p_div_rad_total_mw ) @@ -1175,28 +1172,28 @@ def st_centrepost_nuclear_heating(self, pneut, sh_width): # Nuclear power deposited in the CP winding pack by gammas [MW] pnuc_cp_wp_gam = 16.3 * np.exp( -14.63 * sh_width_eff - ) + 143.08 * sh_width_eff * (sh_width / physics_variables.rmajor) * np.exp( + ) + 143.08 * sh_width_eff * (sh_width / self.data.physics.rmajor) * np.exp( -21.747 * sh_width_eff ) # Nuclear power deposited in the CP winding pack by neutrons [MW] pnuc_cp_wp_n = 1.403 * np.exp( -16.535 * sh_width_eff - ) + 3.812 * sh_width_eff * (sh_width / physics_variables.rmajor) * np.exp( + ) + 3.812 * sh_width_eff * (sh_width / self.data.physics.rmajor) * np.exp( -23.631 * sh_width_eff ) # Nuclear power deposited in the CP steel case by gammas [MW] pnuc_cp_case_gam = 1.802 * np.exp( -13.993 * sh_width_eff - ) + 38.592 * sh_width * (sh_width_eff / physics_variables.rmajor) * np.exp( + ) + 38.592 * sh_width * (sh_width_eff / self.data.physics.rmajor) * np.exp( -27.051 * sh_width_eff ) # Nuclear power deposited in the CP steel case by neutrons [MW] pnuc_cp_case_n = 0.158 * np.exp( -55.046 * sh_width_eff - ) + 2.0742 * sh_width_eff * (sh_width / physics_variables.rmajor) * np.exp( + ) + 2.0742 * sh_width_eff * (sh_width / self.data.physics.rmajor) * np.exp( -24.401 * sh_width_eff ) @@ -1383,7 +1380,7 @@ def write_output(self): po.osubhd(self.outfile, "Nuclear heating :") # ST centre post - if physics_variables.itart == 1: + if self.data.physics.itart == 1: if tfcoil_variables.i_tf_sup == TFConductorModel.WATER_COOLED_COPPER: po.osubhd(self.outfile, "(Copper resistive centrepost used)") elif tfcoil_variables.i_tf_sup == TFConductorModel.SUPERCONDUCTING: diff --git a/process/models/build.py b/process/models/build.py index 67b58849e6..46580ffff4 100644 --- a/process/models/build.py +++ b/process/models/build.py @@ -8,7 +8,6 @@ from process.core.model import Model from process.data_structure import ( numerics, - physics_variables, superconducting_tf_coil_variables, tfcoil_variables, ) @@ -51,7 +50,7 @@ def run(self): self.data.current_drive.radius_beam_tangency_max, ) = self.calculate_beam_port_size( f_radius_beam_tangency_rmajor=self.data.current_drive.f_radius_beam_tangency_rmajor, - rmajor=physics_variables.rmajor, + rmajor=self.data.physics.rmajor, n_tf_coils=tfcoil_variables.n_tf_coils, dx_tf_inboard_out_toroidal=tfcoil_variables.dx_tf_inboard_out_toroidal, dr_tf_outboard=self.data.build.dr_tf_outboard, @@ -157,10 +156,10 @@ def calculate_vertical_build(self, output: bool): # Set the X-point heights for the top and bottom of the plasma # Assumes top-down plasma symmetry self.data.build.z_plasma_xpoint_upper = ( - physics_variables.rminor * physics_variables.kappa + self.data.physics.rminor * self.data.physics.kappa ) self.data.build.z_plasma_xpoint_lower = ( - physics_variables.rminor * physics_variables.kappa + self.data.physics.rminor * self.data.physics.kappa ) if output: @@ -170,10 +169,10 @@ def calculate_vertical_build(self, output: bool): self.mfile, "Divertor null switch", "(i_single_null)", - physics_variables.i_single_null, + self.data.physics.i_single_null, ) - i_single_null = DivertorNumberModels(physics_variables.i_single_null) + i_single_null = DivertorNumberModels(self.data.physics.i_single_null) if i_single_null == DivertorNumberModels.DOUBLE_NULL: po.ocmmnt(self.outfile, "Double null case") @@ -806,7 +805,7 @@ def calculate_vertical_build(self, output: bool): ) # Vertical locations of divertor coils - i_single_null = DivertorNumberModels(physics_variables.i_single_null) + i_single_null = DivertorNumberModels(self.data.physics.i_single_null) if i_single_null == DivertorNumberModels.DOUBLE_NULL: self.data.build.z_tf_top = ( self.data.build.z_tf_inside_half + self.data.build.dr_tf_inboard @@ -849,14 +848,14 @@ def divgeom(self, output: bool): divht: divertor height (m) """ - if physics_variables.itart == 1: - return 1.75e0 * physics_variables.rminor + if self.data.physics.itart == 1: + return 1.75e0 * self.data.physics.rminor # Conventional tokamak divertor model - # options for seperate upper and lower physics_variables.triangularity + # options for seperate upper and lower self.data.physics.triangularity - kap = physics_variables.kappa - triu = physics_variables.triang - tril = physics_variables.triang + kap = self.data.physics.kappa + triu = self.data.physics.triang + tril = self.data.physics.triang # New method, assuming straight legs -- superceded by new method 26/5/2016 # Assumed 90 degrees at X-pt -- wrong# @@ -871,26 +870,26 @@ def divgeom(self, output: bool): # Find radius of inner and outer plasma arcs rco = 0.5 * np.sqrt( - (physics_variables.rminor**2 * ((tril + 1.0e0) ** 2 + kap**2) ** 2) + (self.data.physics.rminor**2 * ((tril + 1.0e0) ** 2 + kap**2) ** 2) / ((tril + 1.0e0) ** 2) ) rci = 0.5 * np.sqrt( - (physics_variables.rminor**2 * ((tril - 1.0e0) ** 2 + kap**2) ** 2) + (self.data.physics.rminor**2 * ((tril - 1.0e0) ** 2 + kap**2) ** 2) / ((tril - 1.0e0) ** 2) ) # Find angles between vertical and legs # Inboard arc angle = outboard leg angle - thetao = np.arcsin(1.0e0 - (physics_variables.rminor * (1.0e0 - tril)) / rci) + thetao = np.arcsin(1.0e0 - (self.data.physics.rminor * (1.0e0 - tril)) / rci) # Outboard arc angle = inboard leg angle - thetai = np.arcsin(1.0e0 - (physics_variables.rminor * (1.0e0 + tril)) / rco) + thetai = np.arcsin(1.0e0 - (self.data.physics.rminor * (1.0e0 + tril)) / rco) # Position of lower x-pt - rxpt = physics_variables.rmajor - tril * physics_variables.rminor - zxpt = -1.0e0 * kap * physics_variables.rminor + rxpt = self.data.physics.rmajor - tril * self.data.physics.rminor + zxpt = -1.0e0 * kap * self.data.physics.rminor # Position of inner strike point # rspi = rxpt - self.data.build.plsepi*cos(alphad) @@ -937,8 +936,8 @@ def divgeom(self, output: bool): po.oheadr(self.outfile, "Divertor build and plasma position") po.ocmmnt(self.outfile, "Divertor Configuration = Single Null Divertor") po.oblnkl(self.outfile) - ptop_radial = physics_variables.rmajor - triu * physics_variables.rminor - ptop_vertical = kap * physics_variables.rminor + ptop_radial = self.data.physics.rmajor - triu * self.data.physics.rminor + ptop_vertical = kap * self.data.physics.rminor po.ovarrf( self.outfile, "Plasma top position, radial (m)", @@ -957,7 +956,7 @@ def divgeom(self, output: bool): self.outfile, "Plasma geometric centre, radial (m)", "(rmajor.)", - physics_variables.rmajor, + self.data.physics.rmajor, "OP ", ) po.ovarrf( @@ -1151,8 +1150,8 @@ def divgeom(self, output: bool): po.ocmmnt(self.outfile, "Divertor Configuration = Double Null Divertor") po.oblnkl(self.outfile) # Assume upper and lower divertors geometries are symmetric. - ptop_radial = physics_variables.rmajor - triu * physics_variables.rminor - ptop_vertical = kap * physics_variables.rminor + ptop_radial = self.data.physics.rmajor - triu * self.data.physics.rminor + ptop_vertical = kap * self.data.physics.rminor po.ovarrf( self.outfile, "Plasma top position, radial (m)", @@ -1171,7 +1170,7 @@ def divgeom(self, output: bool): self.outfile, "Plasma geometric centre, radial (m)", "(rmajor.)", - physics_variables.rmajor, + self.data.physics.rmajor, "OP ", ) po.ovarrf( @@ -1183,7 +1182,7 @@ def divgeom(self, output: bool): ) po.ovarrf( self.outfile, - "Plasma physics_variables.triangularity", + "Plasma self.data.physics.triangularity", "(tril)", tril, "OP ", @@ -1648,7 +1647,7 @@ def calculate_radial_build(self, output: bool): self.data.build.dr_blkt_inboard + self.data.build.dr_blkt_outboard ) - i_single_null = DivertorNumberModels(physics_variables.i_single_null) + i_single_null = DivertorNumberModels(self.data.physics.i_single_null) if i_single_null == DivertorNumberModels.SINGLE_NULL: # Check if self.data.build.dz_fw_plasma_gap has been set too small self.data.build.dz_fw_plasma_gap = max( @@ -1734,12 +1733,12 @@ def calculate_radial_build(self, output: bool): ) # Radius of the centrepost at the top of the machine - if physics_variables.itart == 1 and tfcoil_variables.i_tf_sup != 1: + if self.data.physics.itart == 1 and tfcoil_variables.i_tf_sup != 1: # self.data.build.r_cp_top is set using the plasma shape if self.data.build.i_r_cp_top == 0: self.data.build.r_cp_top = ( - physics_variables.rmajor - - physics_variables.rminor * physics_variables.triang + self.data.physics.rmajor + - self.data.physics.rminor * self.data.physics.triang - ( self.data.build.dr_tf_shld_gap + self.data.build.dr_shld_thermal_inboard @@ -1790,13 +1789,13 @@ def calculate_radial_build(self, output: bool): self.data.build.f_r_cp * self.data.build.r_tf_inboard_out ) - else: # End of physics_variables.itart == 1 .and. tfcoil_variables.i_tf_sup /= 1 + else: # End of self.data.physics.itart == 1 .and. tfcoil_variables.i_tf_sup /= 1 self.data.build.r_cp_top = self.data.build.r_tf_inboard_out if self.data.build.i_r_cp_top != 0 and ( self.data.build.r_cp_top - > physics_variables.rmajor - - physics_variables.rminor * physics_variables.triang + > self.data.physics.rmajor + - self.data.physics.rminor * self.data.physics.triang - ( self.data.build.dr_tf_shld_gap + self.data.build.dr_shld_thermal_inboard @@ -1839,20 +1838,20 @@ def calculate_radial_build(self, output: bool): self.data.build.r_sh_inboard_in + self.data.build.dr_shld_inboard ) - # Radial build to centre of plasma (should be equal to physics_variables.rmajor) + # Radial build to centre of plasma (should be equal to self.data.physics.rmajor) self.data.build.rbld = ( self.data.build.r_sh_inboard_out + self.data.build.dr_shld_blkt_gap + self.data.build.dr_blkt_inboard + self.data.build.dr_fw_inboard + self.data.build.dr_fw_plasma_gap_inboard - + physics_variables.rminor + + self.data.physics.rminor ) # Radius to inner edge of inboard shield self.data.build.r_shld_inboard_inner = ( - physics_variables.rmajor - - physics_variables.rminor + self.data.physics.rmajor + - self.data.physics.rminor - self.data.build.dr_fw_plasma_gap_inboard - self.data.build.dr_fw_inboard - self.data.build.dr_blkt_inboard @@ -1861,8 +1860,8 @@ def calculate_radial_build(self, output: bool): # Radius to outer edge of outboard shield self.data.build.r_shld_outboard_outer = ( - physics_variables.rmajor - + physics_variables.rminor + self.data.physics.rmajor + + self.data.physics.rminor + self.data.build.dr_fw_plasma_gap_outboard + self.data.build.dr_fw_outboard + self.data.build.dr_blkt_outboard @@ -1901,8 +1900,8 @@ def calculate_radial_build(self, output: bool): ripple_b_tf_plasma_edge_max=tfcoil_variables.ripple_b_tf_plasma_edge_max, r_tf_outboard_mid=self.data.build.r_tf_outboard_mid, n_tf_coils=tfcoil_variables.n_tf_coils, - rmajor=physics_variables.rmajor, - rminor=physics_variables.rminor, + rmajor=self.data.physics.rmajor, + rminor=self.data.physics.rminor, r_tf_wp_inboard_inner=superconducting_tf_coil_variables.r_tf_wp_inboard_inner, r_tf_wp_inboard_centre=superconducting_tf_coil_variables.r_tf_wp_inboard_centre, r_tf_wp_inboard_outer=superconducting_tf_coil_variables.r_tf_wp_inboard_outer, @@ -1942,8 +1941,8 @@ def calculate_radial_build(self, output: bool): ripple_b_tf_plasma_edge_max=tfcoil_variables.ripple_b_tf_plasma_edge_max, r_tf_outboard_mid=self.data.build.r_tf_outboard_mid, n_tf_coils=tfcoil_variables.n_tf_coils, - rmajor=physics_variables.rmajor, - rminor=physics_variables.rminor, + rmajor=self.data.physics.rmajor, + rminor=self.data.physics.rminor, r_tf_wp_inboard_inner=superconducting_tf_coil_variables.r_tf_wp_inboard_inner, r_tf_wp_inboard_centre=superconducting_tf_coil_variables.r_tf_wp_inboard_centre, r_tf_wp_inboard_outer=superconducting_tf_coil_variables.r_tf_wp_inboard_outer, @@ -1974,7 +1973,7 @@ def calculate_radial_build(self, output: bool): diagnostic = ( tfcoil_variables.dx_tf_wp_primary_toroidal * tfcoil_variables.n_tf_coils - / physics_variables.rmajor + / self.data.physics.rmajor ) logger.warning( "(TF coil ripple calculation) Dimensionless coil width X out of fitted range. %s", @@ -1986,7 +1985,7 @@ def calculate_radial_build(self, output: bool): ) else: diagnostic = ( - physics_variables.rmajor + physics_variables.rminor + self.data.physics.rmajor + self.data.physics.rminor ) / self.data.build.r_tf_outboard_mid logger.warning( @@ -2004,7 +2003,7 @@ def calculate_radial_build(self, output: bool): self.outfile, "Inboard build thickness (m)", "(dr_inboard_build)", - physics_variables.rmajor - physics_variables.rminor, + self.data.physics.rmajor - self.data.physics.rminor, "OP ", ) @@ -2187,19 +2186,19 @@ def calculate_radial_build(self, output: bool): radius, ]) - radius += physics_variables.rminor + radius += self.data.physics.rminor radial_build_data.append([ "Plasma geometric centre", "rminor", - physics_variables.rminor, + self.data.physics.rminor, radius, ]) - radius += physics_variables.rminor + radius += self.data.physics.rminor radial_build_data.append([ "Plasma outboard edge", "rminor", - physics_variables.rminor, + self.data.physics.rminor, radius, ]) diff --git a/process/models/buildings.py b/process/models/buildings.py index afe8ce2b1f..f61e78bcca 100644 --- a/process/models/buildings.py +++ b/process/models/buildings.py @@ -5,10 +5,7 @@ from process.core import constants from process.core import process_output as po from process.core.model import Model -from process.data_structure import ( - physics_variables, - tfcoil_variables, -) +from process.data_structure import tfcoil_variables from process.models.physics.current_drive import ( CurrentDriveMethodType, CurrentDriveModel, @@ -579,9 +576,9 @@ def bldgs_sizes(self, output, tf_radial_dim, tf_vertical_dim): 2 * np.pi * ( - physics_variables.rmajor + self.data.physics.rmajor - ( - physics_variables.rminor + self.data.physics.rminor + self.data.build.dr_fw_plasma_gap_inboard + self.data.build.dr_fw_inboard + self.data.build.dr_blkt_inboard @@ -624,8 +621,8 @@ def bldgs_sizes(self, output, tf_radial_dim, tf_vertical_dim): 2 * np.pi * ( - physics_variables.rmajor - + physics_variables.rminor + self.data.physics.rmajor + + self.data.physics.rminor + self.data.build.dr_fw_plasma_gap_outboard + self.data.build.dr_fw_outboard + self.data.build.dr_blkt_outboard @@ -652,8 +649,8 @@ def bldgs_sizes(self, output, tf_radial_dim, tf_vertical_dim): # Note: this estimation developed before the divertor design has been finalised if self.data.costs.life_div_fpy != 0.0e0: # noqa: RUF069 hcomp_height = self.data.divertor.dz_divertor - hcomp_rad_thk = 2 * physics_variables.rminor - hcomp_tor_thk = physics_variables.rmajor + physics_variables.rminor + hcomp_rad_thk = 2 * self.data.physics.rminor + hcomp_tor_thk = self.data.physics.rmajor + self.data.physics.rminor hcomp_footprint = (hcomp_height + self.data.buildings.hot_sepdist) * ( max(hcomp_rad_thk, hcomp_tor_thk) + self.data.buildings.hot_sepdist ) diff --git a/process/models/costs/costs.py b/process/models/costs/costs.py index bc68a495e3..578f54d42f 100644 --- a/process/models/costs/costs.py +++ b/process/models/costs/costs.py @@ -6,10 +6,7 @@ from process.core import process_output as po from process.core.exceptions import ProcessValueError from process.core.model import Model -from process.data_structure import ( - physics_variables, - tfcoil_variables, -) +from process.data_structure import tfcoil_variables from process.models.tfcoil.base import TFConductorModel logger = logging.getLogger(__name__) @@ -101,7 +98,7 @@ def output(self): "(life_div)", self.data.costs.life_div, ) - if physics_variables.itart == 1: + if self.data.physics.itart == 1: po.ovarrf( self.outfile, "Centrepost life (years)", @@ -135,7 +132,7 @@ def output(self): "(divcst)", self.data.costs.divcst, ) - if physics_variables.itart == 1: + if self.data.physics.itart == 1: po.ovarrf( self.outfile, "Centrepost direct capital cost (M$)", @@ -377,7 +374,7 @@ def output(self): if ( tfcoil_variables.i_tf_sup != TFConductorModel.SUPERCONDUCTING ): # Resistive TF coils - if physics_variables.itart == 1: + if self.data.physics.itart == 1: po.ocosts( self.outfile, "(c22211)", @@ -1455,10 +1452,10 @@ def acc2221(self): self.data.costs.c22211 = self.data.costs.fkind * self.data.costs.c22211 self.data.costs.cpstcst = 0.0e0 # TART centrepost - if (physics_variables.itart == 1) and (self.data.costs.ifueltyp == 1): + if (self.data.physics.itart == 1) and (self.data.costs.ifueltyp == 1): self.data.costs.cpstcst = self.data.costs.c22211 self.data.costs.c22211 = 0.0e0 - elif (physics_variables.itart == 1) and (self.data.costs.ifueltyp == 2): + elif (self.data.physics.itart == 1) and (self.data.costs.ifueltyp == 2): self.data.costs.cpstcst = self.data.costs.c22211 # Account 222.1.2 : Outboard TF coil legs @@ -2335,14 +2332,14 @@ def acc2272(self): """ if self.data.ife.ife != 1: # Previous calculation, using molflow_plasma_fuelling_required in Amps: - # 1.3 should have been physics_variables.m_fuel_amu*umass/electron_charge*1000*s/day = 2.2 + # 1.3 should have been self.data.physics.m_fuel_amu*umass/electron_charge*1000*s/day = 2.2 # wtgpd = burnup * molflow_plasma_fuelling_required * 1.3e0 # New calculation: 2 nuclei * reactions/sec * kg/nucleus * g/kg * sec/day - physics_variables.wtgpd = ( + self.data.physics.wtgpd = ( 2.0e0 - * physics_variables.rndfuel - * physics_variables.m_fuel_amu + * self.data.physics.rndfuel + * self.data.physics.m_fuel_amu * constants.UMASS * 1000.0e0 * 86400.0e0 @@ -2356,13 +2353,13 @@ def acc2272(self): * 1.0e3 / (constants.ELECTRON_VOLT * 17.6e6 * self.data.ife.fburn) ) - physics_variables.wtgpd = targtm * self.data.ife.reprat * 86400.0e0 + self.data.physics.wtgpd = targtm * self.data.ife.reprat * 86400.0e0 # Assumes that He3 costs same as tritium to process... self.data.costs.c2272 = ( 1.0e-6 * self.data.costs.UCFPR - * (0.5e0 + 0.5e0 * (physics_variables.wtgpd / 60.0e0) ** 0.67e0) + * (0.5e0 + 0.5e0 * (self.data.physics.wtgpd / 60.0e0) ** 0.67e0) ) self.data.costs.c2272 = self.data.costs.fkind * self.data.costs.c2272 @@ -2374,7 +2371,7 @@ def acc2273(self): cfrht = 1.0e5 # No detritiation needed if purely D-He3 reaction - if physics_variables.f_plasma_fuel_tritium > 1.0e-3: + if self.data.physics.f_plasma_fuel_tritium > 1.0e-3: self.data.costs.c2273 = ( 1.0e-6 * self.data.costs.UCDTC @@ -2538,7 +2535,7 @@ def acc26(self): # Calculate rejected heat for non-reactor (==0) and reactor (==1) if self.data.costs.ireactor == 0: pwrrej = ( - physics_variables.p_fusion_total_mw + self.data.physics.p_fusion_total_mw + self.data.heat_transport.p_hcd_electric_total_mw + tfcoil_variables.tfcmw ) @@ -2799,7 +2796,7 @@ def coelc(self): # Costs due to centrepost renewal # =============================== - if (physics_variables.itart == 1) and (self.data.ife.ife != 1): + if (self.data.physics.itart == 1) and (self.data.ife.ife != 1): # Compound interest factor fefcp = (1.0e0 + self.data.costs.discount_rate) ** self.data.costs.cplife_cal @@ -2891,8 +2888,8 @@ def coelc(self): * self.data.heat_transport.p_plant_electric_net_mw / 1200.0e0 + 1.0e-6 - * physics_variables.f_plasma_fuel_helium3 - * physics_variables.wtgpd + * self.data.physics.f_plasma_fuel_helium3 + * self.data.physics.wtgpd * 1.0e-3 * self.data.costs.uche3 * constants.N_DAY_YEAR @@ -2996,7 +2993,7 @@ def convert_fpy_to_calendar(self): self.data.costs.life_div = self.data.costs.life_div_fpy # Centrepost - if physics_variables.itart == 1: + if self.data.physics.itart == 1: if self.data.costs.cplife < self.data.costs.life_plant: self.data.costs.cplife_cal = ( self.data.costs.cplife * self.data.costs.f_t_plant_available diff --git a/process/models/costs/costs_2015.py b/process/models/costs/costs_2015.py index 5ad234e4e7..2cf0167236 100644 --- a/process/models/costs/costs_2015.py +++ b/process/models/costs/costs_2015.py @@ -7,7 +7,6 @@ from process.core.model import Model from process.data_structure import ( global_variables, - physics_variables, tfcoil_variables, ) @@ -915,7 +914,7 @@ def calc_remaining_subsystems(self): # Cost of ITER divertor self.data.costs_2015.s_cref[37] = 381.0e6 # Scale with max power to SOL (MW) - self.data.costs_2015.s_k[37] = physics_variables.p_plasma_separatrix_mw + self.data.costs_2015.s_k[37] = self.data.physics.p_plasma_separatrix_mw self.data.costs_2015.s_kref[37] = 140.0e0 self.data.costs_2015.s_cost[37] = ( self.data.costs_2015.s_cost_factor[37] @@ -1018,7 +1017,7 @@ def calc_remaining_subsystems(self): # Cost of ITER pellet injector and pellet injection system self.data.costs_2015.s_cref[46] = 25.0e6 # Scale with fusion power (MW) - self.data.costs_2015.s_k[46] = physics_variables.p_fusion_total_mw + self.data.costs_2015.s_k[46] = self.data.physics.p_fusion_total_mw self.data.costs_2015.s_kref[46] = 500.0e0 self.data.costs_2015.s_cost[46] = ( self.data.costs_2015.s_cost_factor[46] @@ -1031,7 +1030,7 @@ def calc_remaining_subsystems(self): # # Cost of ITER gas injection system, GDC, Gi valve boxes self.data.costs_2015.s_cref[47] = 32.0e6 # Scale with fusion power (MW) - self.data.costs_2015.s_k[47] = physics_variables.p_fusion_total_mw + self.data.costs_2015.s_k[47] = self.data.physics.p_fusion_total_mw self.data.costs_2015.s_kref[47] = 500.0e0 self.data.costs_2015.s_cost[47] = ( self.data.costs_2015.s_cost_factor[47] @@ -1044,7 +1043,7 @@ def calc_remaining_subsystems(self): # Cost of ITER vacuum pumping self.data.costs_2015.s_cref[48] = 201.0e6 # Scale with fusion power (MW) - self.data.costs_2015.s_k[48] = physics_variables.p_fusion_total_mw + self.data.costs_2015.s_k[48] = self.data.physics.p_fusion_total_mw self.data.costs_2015.s_kref[48] = 500.0e0 self.data.costs_2015.s_cost[48] = ( self.data.costs_2015.s_cost_factor[48] @@ -1057,7 +1056,7 @@ def calc_remaining_subsystems(self): # Cost of ITER tritium plant self.data.costs_2015.s_cref[49] = 226.0e6 # Scale with fusion power (MW) - self.data.costs_2015.s_k[49] = physics_variables.p_fusion_total_mw + self.data.costs_2015.s_k[49] = self.data.physics.p_fusion_total_mw self.data.costs_2015.s_kref[49] = 500.0e0 self.data.costs_2015.s_cost[49] = ( self.data.costs_2015.s_cost_factor[49] @@ -1086,7 +1085,7 @@ def calc_remaining_subsystems(self): # For ITER value see # K:\Power Plant Physics and Technology\PROCESS\PROCESS documentation papers\resistive diffusion time.xmcd or pdf self.data.costs_2015.s_k[51] = ( - self.data.pf_power.ensxpfm * 1.0e6 / physics_variables.t_plasma_res_diffusion + self.data.pf_power.ensxpfm * 1.0e6 / self.data.physics.t_plasma_res_diffusion ) self.data.costs_2015.s_kref[51] = 8.0e9 / 953.0e0 self.data.costs_2015.s_cost[51] = ( @@ -1123,7 +1122,7 @@ def calc_remaining_subsystems(self): # Cost of ITER radiological protection self.data.costs_2015.s_cref[54] = 19.0e6 # Scale with fusion power (MW) - self.data.costs_2015.s_k[54] = physics_variables.p_fusion_total_mw + self.data.costs_2015.s_k[54] = self.data.physics.p_fusion_total_mw self.data.costs_2015.s_kref[54] = 500.0e0 self.data.costs_2015.s_cost[54] = ( self.data.costs_2015.s_cost_factor[54] diff --git a/process/models/divertor.py b/process/models/divertor.py index 2e67887f98..4e775d8de7 100644 --- a/process/models/divertor.py +++ b/process/models/divertor.py @@ -6,7 +6,6 @@ from process.core import process_output as po from process.core.exceptions import ProcessValueError from process.core.model import Model -from process.data_structure import physics_variables as pv from process.data_structure import tfcoil_variables as tfv from process.data_structure.physics_variables import DivertorNumberModels @@ -37,13 +36,13 @@ def run(self, output: bool = False): indicate whether output should be written to the output file, or not """ self.data.fwbs.p_div_nuclear_heat_total_mw = self.incident_neutron_power( - p_plasma_neutron_mw=pv.p_plasma_neutron_mw, + p_plasma_neutron_mw=self.data.physics.p_plasma_neutron_mw, f_ster_div_single=self.data.fwbs.f_ster_div_single, n_divertors=self.data.divertor.n_divertors, ) self.data.fwbs.p_div_rad_total_mw = self.incident_radiation_power( - p_plasma_rad_mw=pv.p_plasma_rad_mw, + p_plasma_rad_mw=self.data.physics.p_plasma_rad_mw, f_ster_div_single=self.data.fwbs.f_ster_div_single, n_divertors=self.data.divertor.n_divertors, ) @@ -58,30 +57,30 @@ def run(self, output: bool = False): return if self.data.divertor.i_div_heat_load == 1: self.divtart( - pv.rmajor, - pv.rminor, - pv.triang, + self.data.physics.rmajor, + self.data.physics.rminor, + self.data.physics.triang, self.data.build.dr_fw_plasma_gap_inboard, self.data.build.dz_xpoint_divertor, - pv.p_plasma_separatrix_mw, + self.data.physics.p_plasma_separatrix_mw, output=output, - i_single_null=pv.i_single_null, + i_single_null=self.data.physics.i_single_null, dz_divertor=self.data.divertor.dz_divertor, ) return if self.data.divertor.i_div_heat_load == 2: self.divwade( - pv.rmajor, - pv.rminor, - pv.aspect, - pv.b_plasma_toroidal_on_axis, - pv.b_plasma_surface_poloidal_average, - pv.p_plasma_separatrix_mw, + self.data.physics.rmajor, + self.data.physics.rminor, + self.data.physics.aspect, + self.data.physics.b_plasma_toroidal_on_axis, + self.data.physics.b_plasma_surface_poloidal_average, + self.data.physics.p_plasma_separatrix_mw, self.data.divertor.f_div_flux_expansion, - pv.nd_plasma_separatrix_electron, + self.data.physics.nd_plasma_separatrix_electron, self.data.divertor.deg_div_field_plate, - pv.rad_fraction_sol, - pv.f_p_div_lower, + self.data.physics.rad_fraction_sol, + self.data.physics.f_p_div_lower, output=output, ) return @@ -411,13 +410,13 @@ def run(self, output: bool): super().run(output=output) self.data.divertor.p_div_lower_nuclear_heat_mw = self.incident_neutron_power( - p_plasma_neutron_mw=pv.p_plasma_neutron_mw, + p_plasma_neutron_mw=self.data.physics.p_plasma_neutron_mw, f_ster_div_single=self.data.fwbs.f_ster_div_single, n_divertors=1, ) self.data.divertor.p_div_lower_rad_mw = self.incident_radiation_power( - p_plasma_rad_mw=pv.p_plasma_rad_mw, + p_plasma_rad_mw=self.data.physics.p_plasma_rad_mw, f_ster_div_single=self.data.fwbs.f_ster_div_single, n_divertors=1, ) @@ -430,13 +429,13 @@ def run(self, output: bool): super().run(output=output) self.data.divertor.p_div_upper_nuclear_heat_mw = self.incident_neutron_power( - p_plasma_neutron_mw=pv.p_plasma_neutron_mw, + p_plasma_neutron_mw=self.data.physics.p_plasma_neutron_mw, f_ster_div_single=self.data.fwbs.f_ster_div_single, n_divertors=1, ) self.data.divertor.p_div_upper_rad_mw = self.incident_radiation_power( - p_plasma_rad_mw=pv.p_plasma_rad_mw, + p_plasma_rad_mw=self.data.physics.p_plasma_rad_mw, f_ster_div_single=self.data.fwbs.f_ster_div_single, n_divertors=1, ) diff --git a/process/models/fw.py b/process/models/fw.py index 2d58c6c356..be146e78ac 100644 --- a/process/models/fw.py +++ b/process/models/fw.py @@ -7,7 +7,6 @@ from process.core.coolprop_interface import FluidProperties from process.core.exceptions import ProcessValueError from process.core.model import Model -from process.data_structure import physics_variables from process.models.build import FwBlktVVShape from process.models.engineering.ivc_functions import ( calculate_pipe_bend_radius, @@ -48,7 +47,7 @@ def run(self): ) if ( - physics_variables.itart == 1 + self.data.physics.itart == 1 or self.data.fwbs.i_fw_blkt_vv_shape == FwBlktVVShape.D_SHAPED ): ( @@ -56,8 +55,8 @@ def run(self): self.data.first_wall.a_fw_outboard_full_coverage, self.data.first_wall.a_fw_total_full_coverage, ) = self.calculate_dshaped_first_wall_areas( - rmajor=physics_variables.rmajor, - rminor=physics_variables.rminor, + rmajor=self.data.physics.rmajor, + rminor=self.data.physics.rminor, dz_fw_half=self.data.fwbs.dz_fw_half, dr_fw_plasma_gap_inboard=self.data.build.dr_fw_plasma_gap_inboard, dr_fw_plasma_gap_outboard=self.data.build.dr_fw_plasma_gap_outboard, @@ -69,9 +68,9 @@ def run(self): self.data.first_wall.a_fw_outboard_full_coverage, self.data.first_wall.a_fw_total_full_coverage, ) = self.calculate_elliptical_first_wall_areas( - rmajor=physics_variables.rmajor, - rminor=physics_variables.rminor, - triang=physics_variables.triang, + rmajor=self.data.physics.rmajor, + rminor=self.data.physics.rminor, + triang=self.data.physics.triang, dz_fw_half=self.data.fwbs.dz_fw_half, dr_fw_plasma_gap_inboard=self.data.build.dr_fw_plasma_gap_inboard, dr_fw_plasma_gap_outboard=self.data.build.dr_fw_plasma_gap_outboard, @@ -110,34 +109,34 @@ def run(self): b_bz_liq=self.data.fwbs.b_bz_liq, ) - if physics_variables.i_pflux_fw_neutron == 1: - physics_variables.pflux_fw_neutron_mw = ( - physics_variables.ffwal - * physics_variables.pflux_plasma_surface_neutron_avg_mw + if self.data.physics.i_pflux_fw_neutron == 1: + self.data.physics.pflux_fw_neutron_mw = ( + self.data.physics.ffwal + * self.data.physics.pflux_plasma_surface_neutron_avg_mw ) else: - physics_variables.pflux_fw_neutron_mw = ( - physics_variables.p_neutron_total_mw / self.data.first_wall.a_fw_total + self.data.physics.pflux_fw_neutron_mw = ( + self.data.physics.p_neutron_total_mw / self.data.first_wall.a_fw_total ) - if physics_variables.i_pflux_fw_neutron == 1: - physics_variables.pflux_fw_rad_mw = ( - physics_variables.ffwal - * physics_variables.p_plasma_rad_mw - / physics_variables.a_plasma_surface + if self.data.physics.i_pflux_fw_neutron == 1: + self.data.physics.pflux_fw_rad_mw = ( + self.data.physics.ffwal + * self.data.physics.p_plasma_rad_mw + / self.data.physics.a_plasma_surface ) else: - physics_variables.pflux_fw_rad_mw = ( - physics_variables.p_plasma_rad_mw / self.data.first_wall.a_fw_total + self.data.physics.pflux_fw_rad_mw = ( + self.data.physics.p_plasma_rad_mw / self.data.first_wall.a_fw_total ) self.data.constraints.pflux_fw_rad_max_mw = ( - physics_variables.pflux_fw_rad_mw * self.data.constraints.f_fw_rad_max + self.data.physics.pflux_fw_rad_mw * self.data.constraints.f_fw_rad_max ) # Power transported to the first wall by escaped alpha particles - physics_variables.p_fw_alpha_mw = physics_variables.p_alpha_total_mw * ( - 1.0e0 - physics_variables.f_p_alpha_plasma_deposited + self.data.physics.p_fw_alpha_mw = self.data.physics.p_alpha_total_mw * ( + 1.0e0 - self.data.physics.f_p_alpha_plasma_deposited ) @staticmethod @@ -794,7 +793,7 @@ def output_fw_surface_loads(self): self.outfile, "Nominal mean radiation load on vessel first-wall (MW/m^2)", "(pflux_fw_rad_mw)", - physics_variables.pflux_fw_rad_mw, + self.data.physics.pflux_fw_rad_mw, "OP ", ) po.ovarre( @@ -822,13 +821,13 @@ def output_fw_surface_loads(self): self.outfile, "Fast alpha particle power incident on the first-wall (MW)", "(p_fw_alpha_mw)", - physics_variables.p_fw_alpha_mw, + self.data.physics.p_fw_alpha_mw, "OP ", ) po.ovarre( self.outfile, "Nominal mean neutron load on vessel first-wall (MW/m^2)", "(pflux_fw_neutron_mw)", - physics_variables.pflux_fw_neutron_mw, + self.data.physics.pflux_fw_neutron_mw, "OP ", ) diff --git a/process/models/ife.py b/process/models/ife.py index f609f278d0..a66c7cf3a5 100644 --- a/process/models/ife.py +++ b/process/models/ife.py @@ -10,7 +10,6 @@ from process.core import constants, process_output from process.core.exceptions import ProcessValueError from process.core.model import Model -from process.data_structure import physics_variables from process.data_structure.ife_variables import MAXMAT MATERIALS = [ @@ -1367,7 +1366,7 @@ def ifephy(self, output: bool = False): # Repetition rate (Hz) self.data.ife.reprat = self.data.ife.pdrive / self.data.ife.edrive # Fusion power (MW) - physics_variables.p_fusion_total_mw = ( + self.data.physics.p_fusion_total_mw = ( 1.0e-6 * self.data.ife.pdrive * self.data.ife.gain ) else: @@ -1375,8 +1374,8 @@ def ifephy(self, output: bool = False): self.data.ife.reprat = self.data.ife.rrin self.data.ife.pdrive = self.data.ife.reprat * self.data.ife.edrive # Gain - physics_variables.p_fusion_total_mw = self.data.ife.pfusife - self.data.ife.gain = physics_variables.p_fusion_total_mw / ( + self.data.physics.p_fusion_total_mw = self.data.ife.pfusife + self.data.ife.gain = self.data.physics.p_fusion_total_mw / ( 1.0e-6 * self.data.ife.pdrive ) @@ -1387,8 +1386,8 @@ def ifephy(self, output: bool = False): phi = 0.5 * np.pi + np.arctan(self.data.ife.zl1 / self.data.ife.r1) sang = 1.0 - np.cos(phi) - physics_variables.pflux_fw_neutron_mw = ( - physics_variables.p_fusion_total_mw + self.data.physics.pflux_fw_neutron_mw = ( + self.data.physics.p_fusion_total_mw * 0.5 * sang / self.data.first_wall.a_fw_total @@ -1402,16 +1401,16 @@ def ifephy(self, output: bool = False): sang = 1.0 - np.cos(phi) phi = np.arctan(self.data.ife.flirad / self.data.ife.zu1) sang -= 1.0 - np.cos(phi) - physics_variables.pflux_fw_neutron_mw = ( - physics_variables.p_fusion_total_mw + self.data.physics.pflux_fw_neutron_mw = ( + self.data.physics.p_fusion_total_mw * 0.5 * sang / self.data.first_wall.a_fw_total ) else: - physics_variables.pflux_fw_neutron_mw = ( - physics_variables.p_fusion_total_mw / self.data.first_wall.a_fw_total + self.data.physics.pflux_fw_neutron_mw = ( + self.data.physics.p_fusion_total_mw / self.data.first_wall.a_fw_total ) if not output: @@ -1452,13 +1451,13 @@ def ifephy(self, output: bool = False): self.outfile, "Fusion power (MW)", "(p_fusion_total_mw)", - physics_variables.p_fusion_total_mw, + self.data.physics.p_fusion_total_mw, ) process_output.ovarre( self.outfile, "Neutron wall load (MW/m2)", "(pflux_fw_neutron_mw)", - physics_variables.pflux_fw_neutron_mw, + self.data.physics.pflux_fw_neutron_mw, ) def driver(self, edrive, gainve, etave): @@ -1766,7 +1765,7 @@ def ifefbs(self, output: bool = False): self.data.costs.life_plant, self.data.costs.abktflnc / ( - physics_variables.pflux_fw_neutron_mw + self.data.physics.pflux_fw_neutron_mw * self.data.costs.f_t_plant_available ), ) @@ -1828,7 +1827,7 @@ def ifepw1(self): # Total thermal power removed from fusion core self.data.heat_transport.priheat = ( - self.data.fwbs.f_p_blkt_multiplication * physics_variables.p_fusion_total_mw + self.data.fwbs.f_p_blkt_multiplication * self.data.physics.p_fusion_total_mw ) # Useful (high-grade) thermal power (MW) diff --git a/process/models/pfcoil.py b/process/models/pfcoil.py index 868263034f..d8ab16932e 100644 --- a/process/models/pfcoil.py +++ b/process/models/pfcoil.py @@ -11,7 +11,6 @@ from process.core import process_output as op from process.core.exceptions import ProcessValueError from process.core.model import DataStructure, Model -from process.data_structure import physics_variables as pv from process.data_structure import rebco_variables as rcv from process.data_structure import superconducting_tf_coil_variables from process.data_structure import tfcoil_variables as tfv @@ -252,11 +251,11 @@ def pfcoil(self): ) = self.place_pf_above_tf( n_pf_coils_in_group=self.data.pf_coil.n_pf_coils_in_group, n_pf_group=group, - rmajor=pv.rmajor, - triang=pv.triang, - rminor=pv.rminor, - itart=pv.itart, - itartpf=pv.itartpf, + rmajor=self.data.physics.rmajor, + triang=self.data.physics.triang, + rminor=self.data.physics.rminor, + itart=self.data.physics.itart, + itartpf=self.data.physics.itartpf, z_tf_inside_half=self.data.build.z_tf_inside_half, dz_tf_upper_lower_midplane=self.data.build.dz_tf_upper_lower_midplane, z_tf_top=self.data.build.z_tf_top, @@ -282,7 +281,7 @@ def pfcoil(self): ) = self.place_pf_outside_tf( n_pf_coils_in_group=self.data.pf_coil.n_pf_coils_in_group, n_pf_group=group, - rminor=pv.rminor, + rminor=self.data.physics.rminor, zref=self.data.pf_coil.zref, i_tf_shape=tfv.i_tf_shape, i_r_pf_outside_tf_placement=self.data.pf_coil.i_r_pf_outside_tf_placement, @@ -306,8 +305,8 @@ def pfcoil(self): ) = self.place_pf_generally( n_pf_coils_in_group=self.data.pf_coil.n_pf_coils_in_group, n_pf_group=group, - rminor=pv.rminor, - rmajor=pv.rmajor, + rminor=self.data.physics.rminor, + rmajor=self.data.physics.rmajor, zref=self.data.pf_coil.zref, rref=self.data.pf_coil.rref, ) @@ -349,8 +348,8 @@ def pfcoil(self): ) # Position and B-field at each test point - drpt = 2.0e0 * pv.rminor / (npts - 1) - rpt0 = pv.rmajor - pv.rminor + drpt = 2.0e0 * self.data.physics.rminor / (npts - 1) + rpt0 = self.data.physics.rmajor - self.data.physics.rminor for i in range(npts): rpts[i] = rpt0 + (i) * drpt @@ -383,7 +382,7 @@ def pfcoil(self): if self.data.pf_coil.i_pf_current == 1: # Simple coil current scaling for STs (good only for A < about 1.8) # Bypasses SVD solver - if pv.itart == 1 and pv.itartpf == 0: + if self.data.physics.itart == 1 and self.data.physics.itartpf == 0: for i in range(self.data.pf_coil.n_pf_coil_groups): if self.data.pf_coil.i_pf_location[i] == 1: # PF coil is stacked on top of the Central Solenoid @@ -395,12 +394,16 @@ def pfcoil(self): if self.data.pf_coil.i_pf_location[i] == 2: # PF coil is on top of the TF coil self.data.pf_coil.ccls[i] = ( - 0.3e0 * pv.aspect**1.6e0 * pv.plasma_current + 0.3e0 + * self.data.physics.aspect**1.6e0 + * self.data.physics.plasma_current ) elif self.data.pf_coil.i_pf_location[i] == 3: # PF coil is radially outside the TF coil - self.data.pf_coil.ccls[i] = -0.4e0 * pv.plasma_current + self.data.pf_coil.ccls[i] = ( + -0.4e0 * self.data.physics.plasma_current + ) else: raise ProcessValueError( @@ -410,14 +413,14 @@ def pfcoil(self): ) # Vertical field (T) - pv.b_plasma_vertical_required = ( + self.data.physics.b_plasma_vertical_required = ( -1.0e-7 - * pv.plasma_current - / pv.rmajor + * self.data.physics.plasma_current + / self.data.physics.rmajor * ( - math.log(8.0e0 * pv.aspect) - + pv.beta_poloidal_vol_avg - + (pv.ind_plasma_internal_norm / 2.0e0) + math.log(8.0e0 * self.data.physics.aspect) + + self.data.physics.beta_poloidal_vol_avg + + (self.data.physics.ind_plasma_internal_norm / 2.0e0) - 1.5e0 ) ) @@ -456,11 +459,11 @@ def pfcoil(self): # This is a fixed current for this calculation -- RK 07/12 self.data.pf_coil.ccls[i] = ( - pv.plasma_current + self.data.physics.plasma_current * 2.0e0 * ( 1.0e0 - - (pv.kappa * pv.rminor) + - (self.data.physics.kappa * self.data.physics.rminor) / abs( self.data.pf_coil.z_pf_coil_middle_group_array[i, 0] ) @@ -518,25 +521,25 @@ def pfcoil(self): ] npts0 = 1 - rpts[0] = pv.rmajor + rpts[0] = self.data.physics.rmajor zpts[0] = 0.0e0 brin[0] = 0.0e0 - # Added pv.ind_plasma_internal_norm term correctly -- RK 07/12 + # Added self.data.physics.ind_plasma_internal_norm term correctly -- RK 07/12 bzin[0] = ( -1.0e-7 - * pv.plasma_current - / pv.rmajor + * self.data.physics.plasma_current + / self.data.physics.rmajor * ( - math.log(8.0e0 * pv.aspect) - + pv.beta_poloidal_vol_avg - + (pv.ind_plasma_internal_norm / 2.0e0) + math.log(8.0e0 * self.data.physics.aspect) + + self.data.physics.beta_poloidal_vol_avg + + (self.data.physics.ind_plasma_internal_norm / 2.0e0) - 1.5e0 ) ) - pv.b_plasma_vertical_required = bzin[0] + self.data.physics.b_plasma_vertical_required = bzin[0] _ssqef, ccls0 = self.efc( npts0, @@ -585,7 +588,13 @@ def pfcoil(self): nocoil += 1 # Flux swing required from CS coil - csflux = -(pv.vs_plasma_res_ramp + pv.vs_plasma_ind_ramp) - pfflux + csflux = ( + -( + self.data.physics.vs_plasma_res_ramp + + self.data.physics.vs_plasma_ind_ramp + ) + - pfflux + ) if self.data.build.iohcl == 1: # Required current change in CS coil @@ -1016,16 +1025,16 @@ def pfcoil(self): # Plasma size and shape self.data.pf_coil.z_pf_coil_upper[self.data.pf_coil.n_cs_pf_coils] = ( - pv.rminor * pv.kappa + self.data.physics.rminor * self.data.physics.kappa ) self.data.pf_coil.z_pf_coil_lower[self.data.pf_coil.n_cs_pf_coils] = ( - -pv.rminor * pv.kappa + -self.data.physics.rminor * self.data.physics.kappa ) self.data.pf_coil.r_pf_coil_inner[self.data.pf_coil.n_cs_pf_coils] = ( - pv.rmajor - pv.rminor + self.data.physics.rmajor - self.data.physics.rminor ) self.data.pf_coil.r_pf_coil_outer[self.data.pf_coil.n_cs_pf_coils] = ( - pv.rmajor + pv.rminor + self.data.physics.rmajor + self.data.physics.rminor ) self.data.pf_coil.n_pf_coil_turns[self.data.pf_coil.n_cs_pf_coils] = 1.0e0 @@ -1050,13 +1059,13 @@ def pfcoil(self): ] = 0.0e0 self.data.pf_coil.c_pf_coil_turn[ self.data.pf_coil.n_pf_cs_plasma_circuits - 1, 2 - ] = pv.plasma_current + ] = self.data.physics.plasma_current self.data.pf_coil.c_pf_coil_turn[ self.data.pf_coil.n_pf_cs_plasma_circuits - 1, 3 - ] = pv.plasma_current + ] = self.data.physics.plasma_current self.data.pf_coil.c_pf_coil_turn[ self.data.pf_coil.n_pf_cs_plasma_circuits - 1, 4 - ] = pv.plasma_current + ] = self.data.physics.plasma_current self.data.pf_coil.c_pf_coil_turn[ self.data.pf_coil.n_pf_cs_plasma_circuits - 1, 5 ] = 0.0e0 @@ -1726,7 +1735,7 @@ def induct(self, output): self.data.pf_coil.n_cs_pf_coils - 1 ] - delzoh * (0.5e0 + i) - rplasma[0] = pv.rmajor # assumes nplas==1 + rplasma[0] = self.data.physics.rmajor # assumes nplas==1 zplasma[0] = 0.0 # Central Solenoid / plasma mutual inductance @@ -1797,7 +1806,7 @@ def induct(self, output): self.data.pf_coil.ind_pf_cs_plasma_mutual[ self.data.pf_coil.n_pf_cs_plasma_circuits - 1, self.data.pf_coil.n_pf_cs_plasma_circuits - 1, - ] = pv.ind_plasma + ] = self.data.physics.ind_plasma # PF coil / plasma mutual inductances ncoils = 0 @@ -2267,7 +2276,7 @@ def outpf(self): tfv.temp_cs_superconductor_margin_min, ) # only output CS fatigue model for pulsed reactor design - if pv.f_c_plasma_inductive > 0.0e-4: + if self.data.physics.f_c_plasma_inductive > 0.0e-4: op.ovarre( self.outfile, "Residual hoop stress in CS Steel (Pa)", @@ -2609,7 +2618,7 @@ def outpf(self): # Plasma op.write( self.outfile, - f"Plasma\t\t\t{pv.rmajor:.2e}\t0.0e0\t\t{2.0e0 * pv.rminor:.2e}\t{2.0e0 * pv.rminor * pv.kappa:.2e}\t1.0e0", + f"Plasma\t\t\t{self.data.physics.rmajor:.2e}\t0.0e0\t\t{2.0e0 * self.data.physics.rminor:.2e}\t{2.0e0 * self.data.physics.rminor * self.data.physics.kappa:.2e}\t1.0e0", ) op.osubhd(self.outfile, "PF Coil Information at Peak Current:") @@ -3358,7 +3367,7 @@ def ohcalc(self): # Calculation of CS fatigue # this is only valid for pulsed reactor design - if pv.f_c_plasma_inductive > 0.0e-4: + if self.data.physics.f_c_plasma_inductive > 0.0e-4: ( self.data.cs_fatigue.n_cycle, self.data.cs_fatigue.t_crack_radial, @@ -4050,9 +4059,9 @@ def peak_b_field_at_pf_coil( # Plasma contribution if t_b_field_peak > 2: kk += 1 - data.pf_coil.r_pf_cs_current_filaments[kk - 1] = pv.rmajor + data.pf_coil.r_pf_cs_current_filaments[kk - 1] = data.physics.rmajor data.pf_coil.z_pf_cs_current_filaments[kk - 1] = 0.0e0 - data.pf_coil.c_pf_cs_current_filaments[kk - 1] = pv.plasma_current + data.pf_coil.c_pf_cs_current_filaments[kk - 1] = data.physics.plasma_current # Calculate the field at the inner and outer edges # of the coil of interest diff --git a/process/models/physics/bootstrap_current.py b/process/models/physics/bootstrap_current.py index e40a2a8a7f..a9036d59f6 100644 --- a/process/models/physics/bootstrap_current.py +++ b/process/models/physics/bootstrap_current.py @@ -13,9 +13,6 @@ from process.core import process_output as po from process.core.exceptions import ProcessValueError from process.core.model import Model -from process.data_structure import ( - physics_variables, -) from process.models.physics.plasma_profiles import PlasmaProfile logger = logging.getLogger(__name__) @@ -86,32 +83,32 @@ def run(self) -> None: self.data.current_drive.f_c_plasma_bootstrap_iter89 = ( self.data.current_drive.cboot * self.bootstrap_fraction_iter89( - aspect=physics_variables.aspect, - beta=physics_variables.beta_total_vol_avg, - b_plasma_toroidal_on_axis=physics_variables.b_plasma_total, - plasma_current=physics_variables.plasma_current, - q95=physics_variables.q95, - q0=physics_variables.q0, - rmajor=physics_variables.rmajor, - vol_plasma=physics_variables.vol_plasma, + aspect=self.data.physics.aspect, + beta=self.data.physics.beta_total_vol_avg, + b_plasma_toroidal_on_axis=self.data.physics.b_plasma_total, + plasma_current=self.data.physics.plasma_current, + q95=self.data.physics.q95, + q0=self.data.physics.q0, + rmajor=self.data.physics.rmajor, + vol_plasma=self.data.physics.vol_plasma, ) ) self.data.current_drive.f_c_plasma_bootstrap_nevins = ( self.data.current_drive.cboot * self.bootstrap_fraction_nevins( - alphan=physics_variables.alphan, - alphat=physics_variables.alphat, - beta_toroidal=physics_variables.beta_toroidal_vol_avg, - b_plasma_toroidal_on_axis=physics_variables.b_plasma_toroidal_on_axis, - nd_plasma_electrons_vol_avg=physics_variables.nd_plasma_electrons_vol_avg, - plasma_current=physics_variables.plasma_current, - q95=physics_variables.q95, - q0=physics_variables.q0, - rmajor=physics_variables.rmajor, - rminor=physics_variables.rminor, - te=physics_variables.temp_plasma_electron_vol_avg_kev, - zeff=physics_variables.n_charge_plasma_effective_vol_avg, + alphan=self.data.physics.alphan, + alphat=self.data.physics.alphat, + beta_toroidal=self.data.physics.beta_toroidal_vol_avg, + b_plasma_toroidal_on_axis=self.data.physics.b_plasma_toroidal_on_axis, + nd_plasma_electrons_vol_avg=self.data.physics.nd_plasma_electrons_vol_avg, + plasma_current=self.data.physics.plasma_current, + q95=self.data.physics.q95, + q0=self.data.physics.q0, + rmajor=self.data.physics.rmajor, + rminor=self.data.physics.rminor, + te=self.data.physics.temp_plasma_electron_vol_avg_kev, + zeff=self.data.physics.n_charge_plasma_effective_vol_avg, ) ) @@ -119,20 +116,20 @@ def run(self) -> None: self.data.current_drive.f_c_plasma_bootstrap_wilson = ( self.data.current_drive.cboot * self.bootstrap_fraction_wilson( - alphaj=physics_variables.alphaj, - alphap=physics_variables.alphap, - alphat=physics_variables.alphat, - betpth=physics_variables.beta_thermal_poloidal_vol_avg, - q0=physics_variables.q0, - q95=physics_variables.q95, - rmajor=physics_variables.rmajor, - rminor=physics_variables.rminor, + alphaj=self.data.physics.alphaj, + alphap=self.data.physics.alphap, + alphat=self.data.physics.alphat, + betpth=self.data.physics.beta_thermal_poloidal_vol_avg, + q0=self.data.physics.q0, + q95=self.data.physics.q95, + rmajor=self.data.physics.rmajor, + rminor=self.data.physics.rminor, ) ) ( self.data.current_drive.f_c_plasma_bootstrap_sauter, - physics_variables.j_plasma_bootstrap_sauter_profile, + self.data.physics.j_plasma_bootstrap_sauter_profile, ) = self.bootstrap_fraction_sauter(self.plasma_profile) self.data.current_drive.f_c_plasma_bootstrap_sauter *= ( self.data.current_drive.cboot @@ -141,112 +138,112 @@ def run(self) -> None: self.data.current_drive.f_c_plasma_bootstrap_sakai = ( self.data.current_drive.cboot * self.bootstrap_fraction_sakai( - beta_poloidal=physics_variables.beta_poloidal_vol_avg, - q95=physics_variables.q95, - q0=physics_variables.q0, - alphan=physics_variables.alphan, - alphat=physics_variables.alphat, - eps=physics_variables.eps, - ind_plasma_internal_norm=physics_variables.ind_plasma_internal_norm, + beta_poloidal=self.data.physics.beta_poloidal_vol_avg, + q95=self.data.physics.q95, + q0=self.data.physics.q0, + alphan=self.data.physics.alphan, + alphat=self.data.physics.alphat, + eps=self.data.physics.eps, + ind_plasma_internal_norm=self.data.physics.ind_plasma_internal_norm, ) ) self.data.current_drive.f_c_plasma_bootstrap_aries = ( self.data.current_drive.cboot * self.bootstrap_fraction_aries( - beta_poloidal=physics_variables.beta_poloidal_vol_avg, - ind_plasma_internal_norm=physics_variables.ind_plasma_internal_norm, - core_density=physics_variables.nd_plasma_electron_on_axis, - average_density=physics_variables.nd_plasma_electrons_vol_avg, - inverse_aspect=physics_variables.eps, + beta_poloidal=self.data.physics.beta_poloidal_vol_avg, + ind_plasma_internal_norm=self.data.physics.ind_plasma_internal_norm, + core_density=self.data.physics.nd_plasma_electron_on_axis, + average_density=self.data.physics.nd_plasma_electrons_vol_avg, + inverse_aspect=self.data.physics.eps, ) ) self.data.current_drive.f_c_plasma_bootstrap_andrade = ( self.data.current_drive.cboot * self.bootstrap_fraction_andrade( - beta_poloidal=physics_variables.beta_poloidal_vol_avg, - core_pressure=physics_variables.pres_plasma_thermal_on_axis, - average_pressure=physics_variables.pres_plasma_thermal_vol_avg, - inverse_aspect=physics_variables.eps, + beta_poloidal=self.data.physics.beta_poloidal_vol_avg, + core_pressure=self.data.physics.pres_plasma_thermal_on_axis, + average_pressure=self.data.physics.pres_plasma_thermal_vol_avg, + inverse_aspect=self.data.physics.eps, ) ) self.data.current_drive.f_c_plasma_bootstrap_hoang = ( self.data.current_drive.cboot * self.bootstrap_fraction_hoang( - beta_poloidal=physics_variables.beta_poloidal_vol_avg, - pressure_index=physics_variables.alphap, - current_index=physics_variables.alphaj, - inverse_aspect=physics_variables.eps, + beta_poloidal=self.data.physics.beta_poloidal_vol_avg, + pressure_index=self.data.physics.alphap, + current_index=self.data.physics.alphaj, + inverse_aspect=self.data.physics.eps, ) ) self.data.current_drive.f_c_plasma_bootstrap_wong = ( self.data.current_drive.cboot * self.bootstrap_fraction_wong( - beta_poloidal=physics_variables.beta_poloidal_vol_avg, - density_index=physics_variables.alphan, - temperature_index=physics_variables.alphat, - inverse_aspect=physics_variables.eps, - elongation=physics_variables.kappa, + beta_poloidal=self.data.physics.beta_poloidal_vol_avg, + density_index=self.data.physics.alphan, + temperature_index=self.data.physics.alphat, + inverse_aspect=self.data.physics.eps, + elongation=self.data.physics.kappa, ) ) self.data.current_drive.bscf_gi_i = ( self.data.current_drive.cboot * self.bootstrap_fraction_gi_I( - beta_poloidal=physics_variables.beta_poloidal_vol_avg, - pressure_index=physics_variables.alphap, - temperature_index=physics_variables.alphat, - inverse_aspect=physics_variables.eps, - effective_charge=physics_variables.n_charge_plasma_effective_vol_avg, - q95=physics_variables.q95, - q0=physics_variables.q0, + beta_poloidal=self.data.physics.beta_poloidal_vol_avg, + pressure_index=self.data.physics.alphap, + temperature_index=self.data.physics.alphat, + inverse_aspect=self.data.physics.eps, + effective_charge=self.data.physics.n_charge_plasma_effective_vol_avg, + q95=self.data.physics.q95, + q0=self.data.physics.q0, ) ) self.data.current_drive.bscf_gi_ii = ( self.data.current_drive.cboot * self.bootstrap_fraction_gi_II( - beta_poloidal=physics_variables.beta_poloidal_vol_avg, - pressure_index=physics_variables.alphap, - temperature_index=physics_variables.alphat, - inverse_aspect=physics_variables.eps, - effective_charge=physics_variables.n_charge_plasma_effective_vol_avg, + beta_poloidal=self.data.physics.beta_poloidal_vol_avg, + pressure_index=self.data.physics.alphap, + temperature_index=self.data.physics.alphat, + inverse_aspect=self.data.physics.eps, + effective_charge=self.data.physics.n_charge_plasma_effective_vol_avg, ) ) self.data.current_drive.f_c_plasma_bootstrap_sugiyama_l = ( self.data.current_drive.cboot * self.bootstrap_fraction_sugiyama_l_mode( - eps=physics_variables.eps, - beta_poloidal=physics_variables.beta_poloidal_vol_avg, - alphan=physics_variables.alphan, - alphat=physics_variables.alphat, - zeff=physics_variables.n_charge_plasma_effective_vol_avg, - q95=physics_variables.q95, - q0=physics_variables.q0, + eps=self.data.physics.eps, + beta_poloidal=self.data.physics.beta_poloidal_vol_avg, + alphan=self.data.physics.alphan, + alphat=self.data.physics.alphat, + zeff=self.data.physics.n_charge_plasma_effective_vol_avg, + q95=self.data.physics.q95, + q0=self.data.physics.q0, ) ) self.data.current_drive.f_c_plasma_bootstrap_sugiyama_h = ( self.data.current_drive.cboot * self.bootstrap_fraction_sugiyama_h_mode( - eps=physics_variables.eps, - beta_poloidal=physics_variables.beta_poloidal_vol_avg, - alphan=physics_variables.alphan, - alphat=physics_variables.alphat, - tbeta=physics_variables.tbeta, - zeff=physics_variables.n_charge_plasma_effective_vol_avg, - q95=physics_variables.q95, - q0=physics_variables.q0, - radius_plasma_pedestal_density_norm=physics_variables.radius_plasma_pedestal_density_norm, - nd_plasma_pedestal_electron=physics_variables.nd_plasma_pedestal_electron, - n_greenwald=physics_variables.nd_plasma_electron_max_array[6], - temp_plasma_pedestal_kev=physics_variables.temp_plasma_pedestal_kev, + eps=self.data.physics.eps, + beta_poloidal=self.data.physics.beta_poloidal_vol_avg, + alphan=self.data.physics.alphan, + alphat=self.data.physics.alphat, + tbeta=self.data.physics.tbeta, + zeff=self.data.physics.n_charge_plasma_effective_vol_avg, + q95=self.data.physics.q95, + q0=self.data.physics.q0, + radius_plasma_pedestal_density_norm=self.data.physics.radius_plasma_pedestal_density_norm, + nd_plasma_pedestal_electron=self.data.physics.nd_plasma_pedestal_electron, + n_greenwald=self.data.physics.nd_plasma_electron_max_array[6], + temp_plasma_pedestal_kev=self.data.physics.temp_plasma_pedestal_kev, ) ) # Calculate beta_norm_max based on i_beta_norm_max try: model = BootstrapCurrentFractionModel( - int(physics_variables.i_bootstrap_current) + int(self.data.physics.i_bootstrap_current) ) self.data.current_drive.f_c_plasma_bootstrap = ( self.get_bootstrap_current_fraction_value(model) @@ -254,7 +251,7 @@ def run(self) -> None: except ValueError: raise ProcessValueError( "Illegal value of i_bootstrap_current", - i_bootstrap_current=physics_variables.i_bootstrap_current, + i_bootstrap_current=self.data.physics.i_bootstrap_current, ) from None def get_bootstrap_current_fraction_value( @@ -668,8 +665,8 @@ def bootstrap_fraction_nevins( # profiles. betae0 = ( - physics_variables.nd_plasma_electron_on_axis - * physics_variables.temp_plasma_electron_on_axis_kev + self.data.physics.nd_plasma_electron_on_axis + * self.data.physics.temp_plasma_electron_on_axis_kev * 1.0e3 * constants.ELECTRON_CHARGE / (b_plasma_toroidal_on_axis**2 / (2.0 * constants.RMU0)) @@ -1269,11 +1266,11 @@ def output(self): self.outfile, "Plasma bootstrap current fraction scaling used", "(i_bootstrap_current)", - physics_variables.i_bootstrap_current, + self.data.physics.i_bootstrap_current, ) po.ocmmnt( self.outfile, - f"Bootstrap current fraction model selected: {BootstrapCurrentFractionModel(physics_variables.i_bootstrap_current).full_name} ", + f"Bootstrap current fraction model selected: {BootstrapCurrentFractionModel(self.data.physics.i_bootstrap_current).full_name} ", ) po.oblnkl(self.outfile) @@ -1312,12 +1309,12 @@ def output(self): self.data.current_drive.f_c_plasma_bootstrap_sauter, "OP ", ) - for point in range(len(physics_variables.j_plasma_bootstrap_sauter_profile)): + for point in range(len(self.data.physics.j_plasma_bootstrap_sauter_profile)): po.ovarrf( self.mfile, f"Sauter et al bootstrap current density profile at point {point}", f"(j_plasma_bootstrap_sauter_profile{point})", - physics_variables.j_plasma_bootstrap_sauter_profile[point], + self.data.physics.j_plasma_bootstrap_sauter_profile[point], "OP ", ) @@ -1396,19 +1393,19 @@ def output(self): "OP ", ) # Error to catch if bootstap fraction limit has been enforced - if physics_variables.err242 == 1: + if self.data.physics.err242 == 1: logger.error("Bootstrap fraction upper limit enforced") # Error to catch if self-driven current fraction limit has been enforced - if physics_variables.err243 == 1: + if self.data.physics.err243 == 1: logger.error( "Predicted plasma driven current is more than upper limit on " "non-inductive fraction" ) - if physics_variables.i_pfirsch_schluter_current == 0: + if self.data.physics.i_pfirsch_schluter_current == 0: po.ocmmnt(self.outfile, " Pfirsch-Schluter current fraction not calculated") - elif physics_variables.i_pfirsch_schluter_current == 1: + elif self.data.physics.i_pfirsch_schluter_current == 1: po.ocmmnt( self.outfile, " (SCENE Pfirsch-Schluter current fraction scaling used)", @@ -1437,9 +1434,15 @@ def output(self): ) -class SauterBootstrapCurrent: +class SauterBootstrapCurrent(Model): """Class to calculate the bootstrap current using the Sauter et al formula.""" + def run(self): + """This model isn't run""" + + def output(self): + """This model doesn't have any output""" + def bootstrap_fraction_sauter(self, plasma_profile: float) -> float: """Calculate the bootstrap current fraction from the Sauter et al scaling. @@ -1478,40 +1481,40 @@ def bootstrap_fraction_sauter(self, plasma_profile: float) -> float: roa = plasma_profile.neprofile.profile_x # Local circularised minor radius - rho = np.sqrt(physics_variables.a_plasma_poloidal / np.pi) * roa + rho = np.sqrt(self.data.physics.a_plasma_poloidal / np.pi) * roa # Square root of local aspect ratio - sqeps = np.sqrt(roa * (physics_variables.rminor / physics_variables.rmajor)) + sqeps = np.sqrt(roa * (self.data.physics.rminor / self.data.physics.rmajor)) # Calculate electron and ion density profiles ne = plasma_profile.neprofile.profile_y * 1e-19 ni = ( - physics_variables.nd_plasma_ions_total_vol_avg - / physics_variables.nd_plasma_electrons_vol_avg + self.data.physics.nd_plasma_ions_total_vol_avg + / self.data.physics.nd_plasma_electrons_vol_avg ) * ne # Calculate electron and ion temperature profiles tempe = plasma_profile.teprofile.profile_y tempi = ( - physics_variables.temp_plasma_ion_vol_avg_kev - / physics_variables.temp_plasma_electron_vol_avg_kev + self.data.physics.temp_plasma_ion_vol_avg_kev + / self.data.physics.temp_plasma_electron_vol_avg_kev ) * tempe # Flat Zeff profile assumed # Return tempi like array object filled with zeff - zeff = np.full_like(tempi, physics_variables.n_charge_plasma_effective_vol_avg) + zeff = np.full_like(tempi, self.data.physics.n_charge_plasma_effective_vol_avg) # inverse_q = 1/safety factor # Parabolic q profile assumed inverse_q = 1 / ( - physics_variables.q0 - + (physics_variables.q95 - physics_variables.q0) * roa**2 + self.data.physics.q0 + + (self.data.physics.q95 - self.data.physics.q0) * roa**2 ) # Create new array of average mass of fuel portion of ions - amain = np.full_like(inverse_q, physics_variables.m_ions_total_amu) + amain = np.full_like(inverse_q, self.data.physics.m_ions_total_amu) # Create new array of average main ion charge - zmain = np.full_like(inverse_q, 1.0 + physics_variables.f_plasma_fuel_helium3) + zmain = np.full_like(inverse_q, 1.0 + self.data.physics.f_plasma_fuel_helium3) # Calculate total bootstrap current (MA) by summing along profiles # Looping from 2 because _calculate_l31_coefficient() etc should return 0 @@ -1535,9 +1538,9 @@ def bootstrap_fraction_sauter(self, plasma_profile: float) -> float: self._calculate_l31_coefficient( radial_elements, plasma_profile.profile_size, - physics_variables.rmajor, - physics_variables.b_plasma_toroidal_on_axis, - physics_variables.triang, + self.data.physics.rmajor, + self.data.physics.b_plasma_toroidal_on_axis, + self.data.physics.triang, ne, ni, tempe, @@ -1551,9 +1554,9 @@ def bootstrap_fraction_sauter(self, plasma_profile: float) -> float: + self._calculate_l31_32_coefficient( radial_elements, plasma_profile.profile_size, - physics_variables.rmajor, - physics_variables.b_plasma_toroidal_on_axis, - physics_variables.triang, + self.data.physics.rmajor, + self.data.physics.b_plasma_toroidal_on_axis, + self.data.physics.triang, ne, ni, tempe, @@ -1567,9 +1570,9 @@ def bootstrap_fraction_sauter(self, plasma_profile: float) -> float: + self._calculate_l34_alpha_31_coefficient( radial_elements, plasma_profile.profile_size, - physics_variables.rmajor, - physics_variables.b_plasma_toroidal_on_axis, - physics_variables.triang, + self.data.physics.rmajor, + self.data.physics.b_plasma_toroidal_on_axis, + self.data.physics.triang, inverse_q, sqeps, tempi, @@ -1585,14 +1588,14 @@ def bootstrap_fraction_sauter(self, plasma_profile: float) -> float: ) * 1.0e6 * ( - -physics_variables.b_plasma_toroidal_on_axis - / (0.2 * np.pi * physics_variables.rmajor) + -self.data.physics.b_plasma_toroidal_on_axis + / (0.2 * np.pi * self.data.physics.rmajor) * rho[radial_elements - 1] * inverse_q[radial_elements - 1] ) ) # A/m2 - return (np.sum(da * jboot, axis=0) / physics_variables.plasma_current), jboot + return (np.sum(da * jboot, axis=0) / self.data.physics.plasma_current), jboot @staticmethod @nb.njit(cache=True) diff --git a/process/models/physics/confinement_time.py b/process/models/physics/confinement_time.py index 451b634e1d..e83830d545 100644 --- a/process/models/physics/confinement_time.py +++ b/process/models/physics/confinement_time.py @@ -10,7 +10,7 @@ from process.core import process_output as po from process.core.exceptions import ProcessValueError from process.core.model import Model -from process.data_structure import physics_variables +from process.data_structure.physics_variables import N_CONFINEMENT_SCALINGS from process.models.physics.plasma_geometry import PlasmaGeom logger = logging.getLogger(__name__) @@ -237,9 +237,9 @@ def calculate_confinement_time( # Calculate heating power (MW) p_plasma_loss_mw = ( - physics_variables.f_p_alpha_plasma_deposited * p_alpha_total_mw + self.data.physics.f_p_alpha_plasma_deposited * p_alpha_total_mw + p_non_alpha_charged_mw - + physics_variables.p_plasma_ohmic_mw + + self.data.physics.p_plasma_ohmic_mw ) # If the device is not ignited, add the injected auxiliary power @@ -248,17 +248,17 @@ def calculate_confinement_time( # Include the radiation as a loss term based on radiation model try: - model = ConfinementRadiationLossModel(int(physics_variables.i_rad_loss)) + model = ConfinementRadiationLossModel(int(self.data.physics.i_rad_loss)) if model == ConfinementRadiationLossModel.FULL_RADIATION: - p_plasma_loss_mw -= physics_variables.pden_plasma_rad_mw * vol_plasma + p_plasma_loss_mw -= self.data.physics.pden_plasma_rad_mw * vol_plasma elif model == ConfinementRadiationLossModel.CORE_ONLY: p_plasma_loss_mw -= pden_plasma_core_rad_mw * vol_plasma # NO_RADIATION: do not adjust p_plasma_loss_mw for radiation except ValueError as e: raise ProcessValueError( "Illegal value of i_rad_loss", - i_rad_loss=physics_variables.i_rad_loss, + i_rad_loss=self.data.physics.i_rad_loss, ) from e # Ensure heating power is positive (shouldn't be necessary) @@ -284,7 +284,7 @@ def calculate_confinement_time( # vol. 48, no. 9, pp. 099801099801, Aug. 2008, # doi: https://doi.org/10.1088/0029-5515/48/9/099801. - physics_variables.kappa_ipb = PlasmaGeom.calculate_iter_physics_basis_elongation( + self.data.physics.kappa_ipb = PlasmaGeom.calculate_iter_physics_basis_elongation( vol_plasma=vol_plasma, rmajor=rmajor, rminor=rminor ) @@ -304,7 +304,7 @@ def calculate_confinement_time( if ( model == ConfinementTimeModel.USER_INPUT ): # t_electron_energy_confinement is an input - t_electron_confinement = physics_variables.tauee_in + t_electron_confinement = self.data.physics.tauee_in # ======================================================================== @@ -731,7 +731,7 @@ def calculate_confinement_time( dnla19, p_plasma_loss_mw, rmajor, - physics_variables.kappa_ipb, + self.data.physics.kappa_ipb, aspect, m_fuel_amu, ) @@ -761,7 +761,7 @@ def calculate_confinement_time( dnla19, p_plasma_loss_mw, rmajor, - physics_variables.kappa_ipb, + self.data.physics.kappa_ipb, aspect, m_fuel_amu, ) @@ -776,7 +776,7 @@ def calculate_confinement_time( dnla19, p_plasma_loss_mw, rmajor, - physics_variables.kappa_ipb, + self.data.physics.kappa_ipb, aspect, m_fuel_amu, ) @@ -791,7 +791,7 @@ def calculate_confinement_time( dnla19, p_plasma_loss_mw, rmajor, - physics_variables.kappa_ipb, + self.data.physics.kappa_ipb, aspect, m_fuel_amu, ) @@ -806,7 +806,7 @@ def calculate_confinement_time( dnla19, p_plasma_loss_mw, rmajor, - physics_variables.kappa_ipb, + self.data.physics.kappa_ipb, aspect, m_fuel_amu, ) @@ -863,7 +863,7 @@ def calculate_confinement_time( t_electron_confinement = self.murari_confinement_time( pcur, rmajor, - physics_variables.kappa_ipb, + self.data.physics.kappa_ipb, dnla19, b_plasma_toroidal_on_axis, p_plasma_loss_mw, @@ -879,7 +879,7 @@ def calculate_confinement_time( dnla19, p_plasma_loss_mw, rmajor, - physics_variables.kappa_ipb, + self.data.physics.kappa_ipb, aspect, ) @@ -898,7 +898,7 @@ def calculate_confinement_time( qstar, aspect, m_fuel_amu, - physics_variables.kappa_ipb, + self.data.physics.kappa_ipb, ) # ========================================================================== @@ -944,7 +944,7 @@ def calculate_confinement_time( dnla19, p_plasma_loss_mw, rmajor, - physics_variables.kappa_ipb, + self.data.physics.kappa_ipb, aspect, m_fuel_amu, ) @@ -959,7 +959,7 @@ def calculate_confinement_time( dnla19, p_plasma_loss_mw, rmajor, - physics_variables.kappa_ipb, + self.data.physics.kappa_ipb, aspect, m_fuel_amu, ) @@ -986,10 +986,10 @@ def calculate_confinement_time( dnla19, p_plasma_loss_mw, rmajor, - physics_variables.triang, - physics_variables.kappa_ipb, + self.data.physics.triang, + self.data.physics.kappa_ipb, eps, - physics_variables.m_ions_total_amu, + self.data.physics.m_ions_total_amu, ) # ========================================================================== @@ -1001,10 +1001,10 @@ def calculate_confinement_time( b_plasma_toroidal_on_axis, p_plasma_loss_mw, dnla19, - physics_variables.m_ions_total_amu, + self.data.physics.m_ions_total_amu, rmajor, - physics_variables.triang, - physics_variables.kappa_ipb, + self.data.physics.triang, + self.data.physics.kappa_ipb, ) # ========================================================================== @@ -1023,33 +1023,33 @@ def calculate_confinement_time( # Calculate H* non-radiation corrected H factor # Note: we will assume the IPB-98y2 scaling. - if physics_variables.i_rad_loss == 1: - physics_variables.hstar = ( + if self.data.physics.i_rad_loss == 1: + self.data.physics.hstar = ( hfact * ( p_plasma_loss_mw / ( p_plasma_loss_mw - + physics_variables.pden_plasma_sync_mw * vol_plasma - + physics_variables.p_plasma_inner_rad_mw + + self.data.physics.pden_plasma_sync_mw * vol_plasma + + self.data.physics.p_plasma_inner_rad_mw ) ) ** 0.31 ) - elif physics_variables.i_rad_loss == 0: - physics_variables.hstar = ( + elif self.data.physics.i_rad_loss == 0: + self.data.physics.hstar = ( hfact * ( p_plasma_loss_mw / ( p_plasma_loss_mw - + physics_variables.pden_plasma_rad_mw * vol_plasma + + self.data.physics.pden_plasma_rad_mw * vol_plasma ) ) ** 0.31 ) - elif physics_variables.i_rad_loss == 2: - physics_variables.hstar = hfact + elif self.data.physics.i_rad_loss == 2: + self.data.physics.hstar = hfact # Calculation of the transport power loss terms # Transport losses in Watts/m3 are 3/2 * n.e.T / tau , with T in eV @@ -1087,8 +1087,8 @@ def calculate_confinement_time( # For comparison directly calculate the confinement time from the stored energy # calculated from the total plasma beta and the loss power used above. - physics_variables.t_energy_confinement_beta = ( - physics_variables.e_plasma_beta / 1e6 + self.data.physics.t_energy_confinement_beta = ( + self.data.physics.e_plasma_beta / 1e6 ) / p_plasma_loss_mw return ( @@ -1171,56 +1171,56 @@ def fhz(hfact: float) -> float: _, _, ) = self.calculate_confinement_time( - m_fuel_amu=physics_variables.m_fuel_amu, - p_alpha_total_mw=physics_variables.p_alpha_total_mw, - aspect=physics_variables.aspect, - b_plasma_toroidal_on_axis=physics_variables.b_plasma_toroidal_on_axis, - nd_plasma_ions_total_vol_avg=physics_variables.nd_plasma_ions_total_vol_avg, - nd_plasma_electrons_vol_avg=physics_variables.nd_plasma_electrons_vol_avg, - nd_plasma_electron_line=physics_variables.nd_plasma_electron_line, - eps=physics_variables.eps, + m_fuel_amu=self.data.physics.m_fuel_amu, + p_alpha_total_mw=self.data.physics.p_alpha_total_mw, + aspect=self.data.physics.aspect, + b_plasma_toroidal_on_axis=self.data.physics.b_plasma_toroidal_on_axis, + nd_plasma_ions_total_vol_avg=self.data.physics.nd_plasma_ions_total_vol_avg, + nd_plasma_electrons_vol_avg=self.data.physics.nd_plasma_electrons_vol_avg, + nd_plasma_electron_line=self.data.physics.nd_plasma_electron_line, + eps=self.data.physics.eps, hfact=hfact, i_confinement_time=i_confinement_time, - i_plasma_ignited=physics_variables.i_plasma_ignited, - kappa=physics_variables.kappa, - kappa95=physics_variables.kappa95, - p_non_alpha_charged_mw=physics_variables.p_non_alpha_charged_mw, + i_plasma_ignited=self.data.physics.i_plasma_ignited, + kappa=self.data.physics.kappa, + kappa95=self.data.physics.kappa95, + p_non_alpha_charged_mw=self.data.physics.p_non_alpha_charged_mw, p_hcd_injected_total_mw=self.data.current_drive.p_hcd_injected_total_mw, - plasma_current=physics_variables.plasma_current, - pden_plasma_core_rad_mw=physics_variables.pden_plasma_core_rad_mw, - rmajor=physics_variables.rmajor, - rminor=physics_variables.rminor, - temp_plasma_electron_density_weighted_kev=physics_variables.temp_plasma_electron_density_weighted_kev, - temp_plasma_ion_density_weighted_kev=physics_variables.temp_plasma_ion_density_weighted_kev, - q95=physics_variables.q95, - qstar=physics_variables.qstar, - vol_plasma=physics_variables.vol_plasma, - zeff=physics_variables.n_charge_plasma_effective_vol_avg, + plasma_current=self.data.physics.plasma_current, + pden_plasma_core_rad_mw=self.data.physics.pden_plasma_core_rad_mw, + rmajor=self.data.physics.rmajor, + rminor=self.data.physics.rminor, + temp_plasma_electron_density_weighted_kev=self.data.physics.temp_plasma_electron_density_weighted_kev, + temp_plasma_ion_density_weighted_kev=self.data.physics.temp_plasma_ion_density_weighted_kev, + q95=self.data.physics.q95, + qstar=self.data.physics.qstar, + vol_plasma=self.data.physics.vol_plasma, + zeff=self.data.physics.n_charge_plasma_effective_vol_avg, ) # At power balance, fhz is zero. fhz_value = ( ptrez + ptriz - - physics_variables.f_p_alpha_plasma_deposited - * physics_variables.pden_alpha_total_mw - - physics_variables.pden_non_alpha_charged_mw - - physics_variables.pden_plasma_ohmic_mw + - self.data.physics.f_p_alpha_plasma_deposited + * self.data.physics.pden_alpha_total_mw + - self.data.physics.pden_non_alpha_charged_mw + - self.data.physics.pden_plasma_ohmic_mw ) # Take into account whether injected power is included in tau_e calculation # (i.e. whether device is ignited) - if physics_variables.i_plasma_ignited == 0: + if self.data.physics.i_plasma_ignited == 0: fhz_value -= ( self.data.current_drive.p_hcd_injected_total_mw - / physics_variables.vol_plasma + / self.data.physics.vol_plasma ) # Include the radiation power if requested - if physics_variables.i_rad_loss == 0: - fhz_value += physics_variables.pden_plasma_rad_mw - elif physics_variables.i_rad_loss == 1: - fhz_value += physics_variables.pden_plasma_core_rad_mw + if self.data.physics.i_rad_loss == 0: + fhz_value += self.data.physics.pden_plasma_rad_mw + elif self.data.physics.i_rad_loss == 1: + fhz_value += self.data.physics.pden_plasma_core_rad_mw return fhz_value @@ -1234,7 +1234,7 @@ def output_confinement_time_info(self): """ po.oheadr(self.outfile, "Plasma Energy Confinement") - if physics_variables.i_plasma_ignited == 1: + if self.data.physics.i_plasma_ignited == 1: po.ocmmnt( self.outfile, "Device is assumed to be ignited for the calculation of confinement " @@ -1242,7 +1242,7 @@ def output_confinement_time_info(self): ) po.oblnkl(self.outfile) - tauelaw = ConfinementTimeModel(physics_variables.i_confinement_time).full_name + tauelaw = ConfinementTimeModel(self.data.physics.i_confinement_time).full_name po.ocmmnt( self.outfile, @@ -1257,20 +1257,20 @@ def output_confinement_time_info(self): ) po.ovarrf( - self.outfile, "Confinement H factor", "(hfact)", physics_variables.hfact + self.outfile, "Confinement H factor", "(hfact)", self.data.physics.hfact ) po.ovarrf( self.outfile, "Global thermal energy confinement time, from scaling (τₑ) (s)", "(t_energy_confinement)", - physics_variables.t_energy_confinement, + self.data.physics.t_energy_confinement, "OP ", ) po.ovarrf( self.outfile, "Directly calculated total energy confinement time (τₑᵦ) (s)", "(t_energy_confinement_beta)", - physics_variables.t_energy_confinement_beta, + self.data.physics.t_energy_confinement_beta, "OP ", ) po.ocmmnt( @@ -1285,14 +1285,14 @@ def output_confinement_time_info(self): self.outfile, "Ion energy confinement time, from scaling (s)", "(t_ion_energy_confinement)", - physics_variables.t_ion_energy_confinement, + self.data.physics.t_ion_energy_confinement, "OP ", ) po.ovarrf( self.outfile, "Electron energy confinement time, from scaling (s)", "(t_electron_energy_confinement)", - physics_variables.t_electron_energy_confinement, + self.data.physics.t_electron_energy_confinement, "OP ", ) po.oblnkl(self.outfile) @@ -1302,14 +1302,14 @@ def output_confinement_time_info(self): self.outfile, "Fusion double product (nτ) (s/m³)", "(ntau)", - physics_variables.ntau, + self.data.physics.ntau, "OP ", ) po.ovarre( self.outfile, "Lawson Triple product (nTτ) (keV s/m³)", "(nTtau)", - physics_variables.nTtau, + self.data.physics.nTtau, "OP ", ) po.oblnkl(self.outfile) @@ -1319,23 +1319,23 @@ def output_confinement_time_info(self): self.outfile, "Transport loss power assumed in scaling law (MW)", "(p_plasma_loss_mw)", - physics_variables.p_plasma_loss_mw, + self.data.physics.p_plasma_loss_mw, "OP ", ) po.ovarin( self.outfile, "Switch for radiation loss term usage in power balance", "(i_rad_loss)", - physics_variables.i_rad_loss, + self.data.physics.i_rad_loss, ) - model = ConfinementRadiationLossModel(physics_variables.i_rad_loss) + model = ConfinementRadiationLossModel(self.data.physics.i_rad_loss) if model == ConfinementRadiationLossModel.FULL_RADIATION: po.ovarre( self.outfile, "Radiation power subtracted from plasma heating power balance (MW)", "", - physics_variables.p_plasma_rad_mw, + self.data.physics.p_plasma_rad_mw, "OP ", ) elif model == ConfinementRadiationLossModel.CORE_ONLY: @@ -1343,7 +1343,7 @@ def output_confinement_time_info(self): self.outfile, "Radiation power subtracted from plasma heating power balance (MW)", "", - physics_variables.p_plasma_inner_rad_mw, + self.data.physics.p_plasma_inner_rad_mw, "OP ", ) else: # NO_RADIATION @@ -1359,7 +1359,7 @@ def output_confinement_time_info(self): self.outfile, "H* non-radiation corrected", "(hstar)", - physics_variables.hstar, + self.data.physics.hstar, "OP", ) po.ocmmnt(self.outfile, " (H* assumes IPB98(y,2), ELMy H-mode scaling)") @@ -1371,7 +1371,7 @@ def output_confinement_time_info(self): self.outfile, "Alpha particle confinement time (τ_α) (s)", # noqa: RUF001 "(t_alpha_confinement)", - physics_variables.t_alpha_confinement, + self.data.physics.t_alpha_confinement, "OP ", ) # Note alpha confinement time is no longer equal to fuel particle @@ -1380,7 +1380,7 @@ def output_confinement_time_info(self): self.outfile, "Alpha particle to energy confinement time ratio (τ_α/τₑ)", # noqa: RUF001 "(f_alpha_energy_confinement)", - physics_variables.f_alpha_energy_confinement, + self.data.physics.f_alpha_energy_confinement, "OP ", ) po.ovarrf( @@ -1445,9 +1445,7 @@ def output_confinement_comparison(self, istell: int): # Start from range 1 as the first i_confinement_time is a user input # If stellarator, use the stellarator scalings for i_confinement_time in ( - range(1, physics_variables.N_CONFINEMENT_SCALINGS) - if istell == 0 - else stellarator_scalings + range(1, N_CONFINEMENT_SCALINGS) if istell == 0 else stellarator_scalings ): if i_confinement_time == 25: continue @@ -1459,49 +1457,49 @@ def output_confinement_comparison(self, istell: int): _, _, ) = self.calculate_confinement_time( - m_fuel_amu=physics_variables.m_fuel_amu, - p_alpha_total_mw=physics_variables.p_alpha_total_mw, - aspect=physics_variables.aspect, - b_plasma_toroidal_on_axis=physics_variables.b_plasma_toroidal_on_axis, - nd_plasma_ions_total_vol_avg=physics_variables.nd_plasma_ions_total_vol_avg, - nd_plasma_electrons_vol_avg=physics_variables.nd_plasma_electrons_vol_avg, - nd_plasma_electron_line=physics_variables.nd_plasma_electron_line, - eps=physics_variables.eps, + m_fuel_amu=self.data.physics.m_fuel_amu, + p_alpha_total_mw=self.data.physics.p_alpha_total_mw, + aspect=self.data.physics.aspect, + b_plasma_toroidal_on_axis=self.data.physics.b_plasma_toroidal_on_axis, + nd_plasma_ions_total_vol_avg=self.data.physics.nd_plasma_ions_total_vol_avg, + nd_plasma_electrons_vol_avg=self.data.physics.nd_plasma_electrons_vol_avg, + nd_plasma_electron_line=self.data.physics.nd_plasma_electron_line, + eps=self.data.physics.eps, hfact=1.0, i_confinement_time=i_confinement_time, - i_plasma_ignited=physics_variables.i_plasma_ignited, - kappa=physics_variables.kappa, - kappa95=physics_variables.kappa95, - p_non_alpha_charged_mw=physics_variables.p_non_alpha_charged_mw, + i_plasma_ignited=self.data.physics.i_plasma_ignited, + kappa=self.data.physics.kappa, + kappa95=self.data.physics.kappa95, + p_non_alpha_charged_mw=self.data.physics.p_non_alpha_charged_mw, p_hcd_injected_total_mw=self.data.current_drive.p_hcd_injected_total_mw, - plasma_current=physics_variables.plasma_current, - pden_plasma_core_rad_mw=physics_variables.pden_plasma_core_rad_mw, - rmajor=physics_variables.rmajor, - rminor=physics_variables.rminor, - temp_plasma_electron_density_weighted_kev=physics_variables.temp_plasma_electron_density_weighted_kev, - temp_plasma_ion_density_weighted_kev=physics_variables.temp_plasma_ion_density_weighted_kev, - q95=physics_variables.q95, - qstar=physics_variables.qstar, - vol_plasma=physics_variables.vol_plasma, - zeff=physics_variables.n_charge_plasma_effective_vol_avg, + plasma_current=self.data.physics.plasma_current, + pden_plasma_core_rad_mw=self.data.physics.pden_plasma_core_rad_mw, + rmajor=self.data.physics.rmajor, + rminor=self.data.physics.rminor, + temp_plasma_electron_density_weighted_kev=self.data.physics.temp_plasma_electron_density_weighted_kev, + temp_plasma_ion_density_weighted_kev=self.data.physics.temp_plasma_ion_density_weighted_kev, + q95=self.data.physics.q95, + qstar=self.data.physics.qstar, + vol_plasma=self.data.physics.vol_plasma, + zeff=self.data.physics.n_charge_plasma_effective_vol_avg, ) try: # Calculate the H-factor for the same confinement time in other scalings - physics_variables.hfac[i_confinement_time - 1] = ( + self.data.physics.hfac[i_confinement_time - 1] = ( self.find_other_h_factors(i_confinement_time) ) except ValueError: # This is only used for a table in the OUT.DAT so if it fails # just write a NaN--its not worth crashing PROCESS over. - physics_variables.hfac[i_confinement_time - 1] = np.nan + self.data.physics.hfac[i_confinement_time - 1] = np.nan scaling_name = ConfinementTimeModel(i_confinement_time).full_name po.ocmmnt( self.outfile, f"{'':>2}{scaling_name:<38}" - f"{taueez:<28.3f}{physics_variables.hfac[i_confinement_time - 1]:.3f}", + f"{taueez:<28.3f}{self.data.physics.hfac[i_confinement_time - 1]:.3f}", ) po.oblnkl(self.outfile) diff --git a/process/models/physics/current_drive.py b/process/models/physics/current_drive.py index 0cfcd15090..ab76724940 100644 --- a/process/models/physics/current_drive.py +++ b/process/models/physics/current_drive.py @@ -12,9 +12,6 @@ ) from process.core.exceptions import ProcessError, ProcessValueError from process.core.model import Model -from process.data_structure import ( - physics_variables, -) from process.models.physics.plasma_profiles import PlasmaProfile logger = logging.getLogger(__name__) @@ -173,64 +170,64 @@ def iternb(self): """ # Check argument sanity if ( - 1 + physics_variables.eps + 1 + self.data.physics.eps ) < self.data.current_drive.f_radius_beam_tangency_rmajor: raise ProcessValueError( "Imminent negative square root argument; NBI will miss plasma " "completely", - eps=physics_variables.eps, + eps=self.data.physics.eps, f_radius_beam_tangency_rmajor=self.data.current_drive.f_radius_beam_tangency_rmajor, ) # Calculate beam path length to centre - dpath = physics_variables.rmajor * np.sqrt( - (1.0 + physics_variables.eps) ** 2 + dpath = self.data.physics.rmajor * np.sqrt( + (1.0 + self.data.physics.eps) ** 2 - self.data.current_drive.f_radius_beam_tangency_rmajor**2 ) # Calculate beam stopping cross-section sigstop = self.sigbeam( - self.data.current_drive.e_beam_kev / physics_variables.m_beam_amu, - physics_variables.temp_plasma_electron_vol_avg_kev, - physics_variables.nd_plasma_electrons_vol_avg, - physics_variables.f_nd_alpha_electron, - physics_variables.f_nd_plasma_carbon_electron, - physics_variables.f_nd_plasma_oxygen_electron, - physics_variables.f_nd_plasma_iron_argon_electron, + self.data.current_drive.e_beam_kev / self.data.physics.m_beam_amu, + self.data.physics.temp_plasma_electron_vol_avg_kev, + self.data.physics.nd_plasma_electrons_vol_avg, + self.data.physics.f_nd_alpha_electron, + self.data.physics.f_nd_plasma_carbon_electron, + self.data.physics.f_nd_plasma_oxygen_electron, + self.data.physics.f_nd_plasma_iron_argon_electron, ) # Calculate number of decay lengths to centre self.data.current_drive.n_beam_decay_lengths_core = ( - dpath * physics_variables.nd_plasma_electrons_vol_avg * sigstop + dpath * self.data.physics.nd_plasma_electrons_vol_avg * sigstop ) # Shine-through fraction of beam fshine = np.exp( - -2.0 * dpath * physics_variables.nd_plasma_electrons_vol_avg * sigstop + -2.0 * dpath * self.data.physics.nd_plasma_electrons_vol_avg * sigstop ) fshine = max(fshine, 1e-20) # Power split to ions / electrons f_p_beam_injected_ions = self.cfnbi( - afast=physics_variables.m_beam_amu, + afast=self.data.physics.m_beam_amu, efast=self.data.current_drive.e_beam_kev, - te=physics_variables.temp_plasma_electron_density_weighted_kev, - ne=physics_variables.nd_plasma_electrons_vol_avg, - n_charge_plasma_effective_mass_weighted_vol_avg=physics_variables.n_charge_plasma_effective_mass_weighted_vol_avg, - xlmbda=physics_variables.dlamie, + te=self.data.physics.temp_plasma_electron_density_weighted_kev, + ne=self.data.physics.nd_plasma_electrons_vol_avg, + n_charge_plasma_effective_mass_weighted_vol_avg=self.data.physics.n_charge_plasma_effective_mass_weighted_vol_avg, + xlmbda=self.data.physics.dlamie, ) # Current drive efficiency effnbss = self.data.current_drive.f_radius_beam_tangency_rmajor * self.etanb( - physics_variables.m_beam_amu, - physics_variables.alphan, - physics_variables.alphat, - physics_variables.aspect, - physics_variables.nd_plasma_electrons_vol_avg, + self.data.physics.m_beam_amu, + self.data.physics.alphan, + self.data.physics.alphat, + self.data.physics.aspect, + self.data.physics.nd_plasma_electrons_vol_avg, self.data.current_drive.e_beam_kev, - physics_variables.rmajor, - physics_variables.temp_plasma_electron_density_weighted_kev, - physics_variables.n_charge_plasma_effective_vol_avg, + self.data.physics.rmajor, + self.data.physics.temp_plasma_electron_density_weighted_kev, + self.data.physics.n_charge_plasma_effective_vol_avg, ) return effnbss, f_p_beam_injected_ions, fshine @@ -263,74 +260,74 @@ def culnbi(self) -> tuple[float, float, float]: AEA FUS 172: Physics Assessment for the European Reactor Study """ if ( - 1.0e0 + physics_variables.eps + 1.0e0 + self.data.physics.eps ) < self.data.current_drive.f_radius_beam_tangency_rmajor: raise ProcessValueError( "Imminent negative square root argument; NBI will miss plasma " "completely", - eps=physics_variables.eps, + eps=self.data.physics.eps, f_radius_beam_tangency_rmajor=self.data.current_drive.f_radius_beam_tangency_rmajor, ) # Calculate beam path length to centre - dpath = physics_variables.rmajor * np.sqrt( - (1.0e0 + physics_variables.eps) ** 2 + dpath = self.data.physics.rmajor * np.sqrt( + (1.0e0 + self.data.physics.eps) ** 2 - self.data.current_drive.f_radius_beam_tangency_rmajor**2 ) # Calculate beam stopping cross-section sigstop = self.sigbeam( - self.data.current_drive.e_beam_kev / physics_variables.m_beam_amu, - physics_variables.temp_plasma_electron_vol_avg_kev, - physics_variables.nd_plasma_electrons_vol_avg, - physics_variables.f_nd_alpha_electron, - physics_variables.f_nd_plasma_carbon_electron, - physics_variables.f_nd_plasma_oxygen_electron, - physics_variables.f_nd_plasma_iron_argon_electron, + self.data.current_drive.e_beam_kev / self.data.physics.m_beam_amu, + self.data.physics.temp_plasma_electron_vol_avg_kev, + self.data.physics.nd_plasma_electrons_vol_avg, + self.data.physics.f_nd_alpha_electron, + self.data.physics.f_nd_plasma_carbon_electron, + self.data.physics.f_nd_plasma_oxygen_electron, + self.data.physics.f_nd_plasma_iron_argon_electron, ) # Calculate number of decay lengths to centre self.data.current_drive.n_beam_decay_lengths_core = ( - dpath * physics_variables.nd_plasma_electron_line * sigstop + dpath * self.data.physics.nd_plasma_electron_line * sigstop ) # Shine-through fraction of beam fshine = np.exp( - -2.0e0 * dpath * physics_variables.nd_plasma_electron_line * sigstop + -2.0e0 * dpath * self.data.physics.nd_plasma_electron_line * sigstop ) fshine = max(fshine, 1.0e-20) # Power split to ions / electrons f_p_beam_injected_ions = self.cfnbi( - afast=physics_variables.m_beam_amu, + afast=self.data.physics.m_beam_amu, efast=self.data.current_drive.e_beam_kev, - te=physics_variables.temp_plasma_electron_density_weighted_kev, - ne=physics_variables.nd_plasma_electrons_vol_avg, - n_charge_plasma_effective_mass_weighted_vol_avg=physics_variables.n_charge_plasma_effective_mass_weighted_vol_avg, - xlmbda=physics_variables.dlamie, + te=self.data.physics.temp_plasma_electron_density_weighted_kev, + ne=self.data.physics.nd_plasma_electrons_vol_avg, + n_charge_plasma_effective_mass_weighted_vol_avg=self.data.physics.n_charge_plasma_effective_mass_weighted_vol_avg, + xlmbda=self.data.physics.dlamie, ) # Current drive efficiency effnbss = self.etanb2( - physics_variables.m_beam_amu, - physics_variables.alphan, - physics_variables.alphat, - physics_variables.aspect, - physics_variables.nd_plasma_electrons_vol_avg, - physics_variables.nd_plasma_electron_line, + self.data.physics.m_beam_amu, + self.data.physics.alphan, + self.data.physics.alphat, + self.data.physics.aspect, + self.data.physics.nd_plasma_electrons_vol_avg, + self.data.physics.nd_plasma_electron_line, self.data.current_drive.e_beam_kev, self.data.current_drive.f_radius_beam_tangency_rmajor, fshine, - physics_variables.rmajor, - physics_variables.rminor, - physics_variables.temp_plasma_electron_density_weighted_kev, - physics_variables.n_charge_plasma_effective_vol_avg, + self.data.physics.rmajor, + self.data.physics.rminor, + self.data.physics.temp_plasma_electron_density_weighted_kev, + self.data.physics.n_charge_plasma_effective_vol_avg, ) return effnbss, f_p_beam_injected_ions, fshine @@ -810,29 +807,29 @@ def culecd(self): # Temperature tlocal = self.plasma_profile.teprofile.calculate_profile_y( rrr, - physics_variables.radius_plasma_pedestal_temp_norm, - physics_variables.temp_plasma_electron_on_axis_kev, - physics_variables.temp_plasma_pedestal_kev, - physics_variables.temp_plasma_separatrix_kev, - physics_variables.alphat, - physics_variables.tbeta, + self.data.physics.radius_plasma_pedestal_temp_norm, + self.data.physics.temp_plasma_electron_on_axis_kev, + self.data.physics.temp_plasma_pedestal_kev, + self.data.physics.temp_plasma_separatrix_kev, + self.data.physics.alphat, + self.data.physics.tbeta, ) # Density (10**20 m**-3) dlocal = 1.0e-20 * self.plasma_profile.neprofile.calculate_profile_y( rrr, - physics_variables.radius_plasma_pedestal_density_norm, - physics_variables.nd_plasma_electron_on_axis, - physics_variables.nd_plasma_pedestal_electron, - physics_variables.nd_plasma_separatrix_electron, - physics_variables.alphan, + self.data.physics.radius_plasma_pedestal_density_norm, + self.data.physics.nd_plasma_electron_on_axis, + self.data.physics.nd_plasma_pedestal_electron, + self.data.physics.nd_plasma_separatrix_electron, + self.data.physics.alphan, ) # Inverse aspect ratio - epsloc = rrr * physics_variables.rminor / physics_variables.rmajor + epsloc = rrr * self.data.physics.rminor / self.data.physics.rmajor # Effective charge (use average value) - zlocal = physics_variables.n_charge_plasma_effective_vol_avg + zlocal = self.data.physics.n_charge_plasma_effective_vol_avg # Coulomb logarithm for ion-electron collisions # (From J. A. Wesson, 'Tokamaks', Clarendon Press, Oxford, p.293) @@ -855,7 +852,7 @@ def culecd(self): ecgam = 0.25e0 * (ecgam1 + ecgam2 + ecgam3 + ecgam4) # Current drive efficiency (A/W) - return ecgam / (dlocal * physics_variables.rmajor) + return ecgam / (dlocal * self.data.physics.rmajor) def eccdef(self, tlocal, epsloc, zlocal, cosang, coulog): """Calculate Electron Cyclotron current drive efficiency. @@ -1336,31 +1333,31 @@ def cullhy(self): AEA FUS 172: Physics Assessment for the European Reactor Study """ rratio = self.lhrad() - rpenet = rratio * physics_variables.rminor + rpenet = rratio * self.data.physics.rminor # Local density, temperature, toroidal field at this minor radius dlocal = 1.0e-19 * self.plasma_profile.neprofile.calculate_profile_y( rratio, - physics_variables.radius_plasma_pedestal_density_norm, - physics_variables.nd_plasma_electron_on_axis, - physics_variables.nd_plasma_pedestal_electron, - physics_variables.nd_plasma_separatrix_electron, - physics_variables.alphan, + self.data.physics.radius_plasma_pedestal_density_norm, + self.data.physics.nd_plasma_electron_on_axis, + self.data.physics.nd_plasma_pedestal_electron, + self.data.physics.nd_plasma_separatrix_electron, + self.data.physics.alphan, ) tlocal = self.plasma_profile.teprofile.calculate_profile_y( rratio, - physics_variables.radius_plasma_pedestal_temp_norm, - physics_variables.temp_plasma_electron_on_axis_kev, - physics_variables.temp_plasma_pedestal_kev, - physics_variables.temp_plasma_separatrix_kev, - physics_variables.alphat, - physics_variables.tbeta, + self.data.physics.radius_plasma_pedestal_temp_norm, + self.data.physics.temp_plasma_electron_on_axis_kev, + self.data.physics.temp_plasma_pedestal_kev, + self.data.physics.temp_plasma_separatrix_kev, + self.data.physics.alphat, + self.data.physics.tbeta, ) blocal = ( - physics_variables.b_plasma_toroidal_on_axis - * physics_variables.rmajor - / (physics_variables.rmajor - rpenet) + self.data.physics.b_plasma_toroidal_on_axis + * self.data.physics.rmajor + / (self.data.physics.rmajor - rpenet) ) # Calculated on inboard side # Parallel refractive index needed for plasma access @@ -1370,7 +1367,7 @@ def cullhy(self): # Local inverse aspect ratio - epslh = rpenet / physics_variables.rmajor + epslh = rpenet / self.data.physics.rmajor # LH normalised efficiency (A/W m**-2) @@ -1379,7 +1376,7 @@ def cullhy(self): term01 = 6.1e0 / ( nplacc * nplacc - * (physics_variables.n_charge_plasma_effective_vol_avg + 5.0e0) + * (self.data.physics.n_charge_plasma_effective_vol_avg + 5.0e0) ) term02 = 1.0e0 + (tlocal / 25.0e0) ** 1.16e0 term03 = epslh**0.77e0 * np.sqrt(12.25e0 + x * x) @@ -1396,7 +1393,7 @@ def cullhy(self): # Current drive efficiency (A/W) - return gamlh / ((0.1e0 * dlocal) * physics_variables.rmajor) + return gamlh / ((0.1e0 * dlocal) * self.data.physics.rmajor) def lhrad(self): """Routine to calculate Lower Hybrid wave absorption radius @@ -1409,7 +1406,7 @@ def lhrad(self): # Correction to refractive index (kept within valid bounds) drfind = min( 0.7e0, - max(0.1e0, 12.5e0 / physics_variables.temp_plasma_electron_on_axis_kev), + max(0.1e0, 12.5e0 / self.data.physics.temp_plasma_electron_on_axis_kev), ) # Use Newton-Raphson method to establish the correct minor radius @@ -1487,31 +1484,31 @@ def lheval(self, drfind, rratio): """ dlocal = 1.0e-19 * self.plasma_profile.neprofile.calculate_profile_y( rratio, - physics_variables.radius_plasma_pedestal_density_norm, - physics_variables.nd_plasma_electron_on_axis, - physics_variables.nd_plasma_pedestal_electron, - physics_variables.nd_plasma_separatrix_electron, - physics_variables.alphan, + self.data.physics.radius_plasma_pedestal_density_norm, + self.data.physics.nd_plasma_electron_on_axis, + self.data.physics.nd_plasma_pedestal_electron, + self.data.physics.nd_plasma_separatrix_electron, + self.data.physics.alphan, ) # Local electron temperature tlocal = self.plasma_profile.teprofile.calculate_profile_y( rratio, - physics_variables.radius_plasma_pedestal_temp_norm, - physics_variables.temp_plasma_electron_on_axis_kev, - physics_variables.temp_plasma_pedestal_kev, - physics_variables.temp_plasma_separatrix_kev, - physics_variables.alphat, - physics_variables.tbeta, + self.data.physics.radius_plasma_pedestal_temp_norm, + self.data.physics.temp_plasma_electron_on_axis_kev, + self.data.physics.temp_plasma_pedestal_kev, + self.data.physics.temp_plasma_separatrix_kev, + self.data.physics.alphat, + self.data.physics.tbeta, ) # Local toroidal field (evaluated at the inboard region of the flux surface) blocal = ( - physics_variables.b_plasma_toroidal_on_axis - * physics_variables.rmajor - / (physics_variables.rmajor - rratio * physics_variables.rminor) + self.data.physics.b_plasma_toroidal_on_axis + * self.data.physics.rmajor + / (self.data.physics.rmajor - rratio * self.data.physics.rminor) ) # Parallel refractive index needed for plasma access @@ -1677,7 +1674,7 @@ def current_drive(self): if self.data.current_drive.i_hcd_calculations != 0: # Put electron density in desired units (10^-20 m-3) - dene20 = physics_variables.nd_plasma_electrons_vol_avg * 1.0e-20 + dene20 = self.data.physics.nd_plasma_electrons_vol_avg * 1.0e-20 # Calculate current drive efficiencies # ============================================================== @@ -1687,37 +1684,37 @@ def current_drive(self): hcd_models = { 1: lambda: ( self.lower_hybrid.lower_hybrid_fenstermacher( - physics_variables.temp_plasma_electron_vol_avg_kev, - physics_variables.rmajor, + self.data.physics.temp_plasma_electron_vol_avg_kev, + self.data.physics.rmajor, dene20, ) * self.data.current_drive.feffcd ), 2: lambda: ( self.ion_cyclotron.ion_cyclotron_ipdg89( - temp_plasma_electron_density_weighted_kev=physics_variables.temp_plasma_electron_density_weighted_kev, - zeff=physics_variables.n_charge_plasma_effective_vol_avg, - rmajor=physics_variables.rmajor, + temp_plasma_electron_density_weighted_kev=self.data.physics.temp_plasma_electron_density_weighted_kev, + zeff=self.data.physics.n_charge_plasma_effective_vol_avg, + rmajor=self.data.physics.rmajor, dene20=dene20, ) * self.data.current_drive.feffcd ), 3: lambda: ( self.electron_cyclotron.electron_cyclotron_fenstermacher( - temp_plasma_electron_density_weighted_kev=physics_variables.temp_plasma_electron_density_weighted_kev, - rmajor=physics_variables.rmajor, + temp_plasma_electron_density_weighted_kev=self.data.physics.temp_plasma_electron_density_weighted_kev, + rmajor=self.data.physics.rmajor, dene20=dene20, - dlamee=physics_variables.dlamee, + dlamee=self.data.physics.dlamee, ) * self.data.current_drive.feffcd ), 4: lambda: ( self.lower_hybrid.lower_hybrid_ehst( - te=physics_variables.temp_plasma_electron_vol_avg_kev, - beta=physics_variables.beta_total_vol_avg, - rmajor=physics_variables.rmajor, + te=self.data.physics.temp_plasma_electron_vol_avg_kev, + beta=self.data.physics.beta_total_vol_avg, + rmajor=self.data.physics.rmajor, dene20=dene20, - zeff=physics_variables.n_charge_plasma_effective_vol_avg, + zeff=self.data.physics.n_charge_plasma_effective_vol_avg, ) * self.data.current_drive.feffcd ), @@ -1733,14 +1730,14 @@ def current_drive(self): ), 10: lambda: ( self.data.current_drive.eta_cd_norm_ecrh - / (dene20 * physics_variables.rmajor) + / (dene20 * self.data.physics.rmajor) ), 12: lambda: ( self.electron_bernstein.electron_bernstein_freethy( - te=physics_variables.temp_plasma_electron_vol_avg_kev, - rmajor=physics_variables.rmajor, + te=self.data.physics.temp_plasma_electron_vol_avg_kev, + rmajor=self.data.physics.rmajor, dene20=dene20, - b_plasma_toroidal_on_axis=physics_variables.b_plasma_toroidal_on_axis, + b_plasma_toroidal_on_axis=self.data.physics.b_plasma_toroidal_on_axis, n_ecrh_harmonic=self.data.current_drive.n_ecrh_harmonic, xi_ebw=self.data.current_drive.xi_ebw, ) @@ -1748,11 +1745,11 @@ def current_drive(self): ), 13: lambda: ( self.electron_cyclotron.electron_cyclotron_freethy( - te=physics_variables.temp_plasma_electron_vol_avg_kev, - zeff=physics_variables.n_charge_plasma_effective_vol_avg, - rmajor=physics_variables.rmajor, - nd_plasma_electrons_vol_avg=physics_variables.nd_plasma_electrons_vol_avg, - b_plasma_toroidal_on_axis=physics_variables.b_plasma_toroidal_on_axis, + te=self.data.physics.temp_plasma_electron_vol_avg_kev, + zeff=self.data.physics.n_charge_plasma_effective_vol_avg, + rmajor=self.data.physics.rmajor, + nd_plasma_electrons_vol_avg=self.data.physics.nd_plasma_electrons_vol_avg, + b_plasma_toroidal_on_axis=self.data.physics.b_plasma_toroidal_on_axis, n_ecrh_harmonic=self.data.current_drive.n_ecrh_harmonic, i_ecrh_wave_mode=self.data.current_drive.i_ecrh_wave_mode, ) @@ -1796,15 +1793,15 @@ def current_drive(self): # heating method self.data.current_drive.eta_cd_norm_hcd_primary = self.calculate_normalised_current_drive_efficiency( eta_cd_hcd=self.data.current_drive.eta_cd_hcd_primary, - nd_plasma_electrons_vol_avg=physics_variables.nd_plasma_electrons_vol_avg, - rmajor=physics_variables.rmajor, + nd_plasma_electrons_vol_avg=self.data.physics.nd_plasma_electrons_vol_avg, + rmajor=self.data.physics.rmajor, ) # Calculate the normalised current drive efficieny for the secondary # heating method self.data.current_drive.eta_cd_norm_hcd_secondary = self.calculate_normalised_current_drive_efficiency( eta_cd_hcd=self.data.current_drive.eta_cd_hcd_secondary, - nd_plasma_electrons_vol_avg=physics_variables.nd_plasma_electrons_vol_avg, - rmajor=physics_variables.rmajor, + nd_plasma_electrons_vol_avg=self.data.physics.nd_plasma_electrons_vol_avg, + rmajor=self.data.physics.rmajor, ) # Calculate the driven current for the secondary heating method @@ -1817,17 +1814,17 @@ def current_drive(self): # heating method self.data.current_drive.f_c_plasma_hcd_secondary = ( self.data.current_drive.c_hcd_secondary_driven - / physics_variables.plasma_current + / self.data.physics.plasma_current ) # Calculate the injected power for the primary heating method self.data.current_drive.p_hcd_primary_injected_mw = ( 1.0e-6 * ( - physics_variables.f_c_plasma_auxiliary + self.data.physics.f_c_plasma_auxiliary - self.data.current_drive.f_c_plasma_hcd_secondary ) - * physics_variables.plasma_current + * self.data.physics.plasma_current / self.data.current_drive.eta_cd_hcd_primary ) @@ -1841,14 +1838,14 @@ def current_drive(self): # heating method self.data.current_drive.f_c_plasma_hcd_primary = ( self.data.current_drive.c_hcd_primary_driven - / physics_variables.plasma_current + / self.data.physics.plasma_current ) # Calculate the dimensionless current drive efficiency for the primary heating method (ζ) self.data.current_drive.eta_cd_dimensionless_hcd_primary = self.calculate_dimensionless_current_drive_efficiency( - nd_plasma_electrons_vol_avg=physics_variables.nd_plasma_electrons_vol_avg, - rmajor=physics_variables.rmajor, - temp_plasma_electron_vol_avg_kev=physics_variables.temp_plasma_electron_vol_avg_kev, + nd_plasma_electrons_vol_avg=self.data.physics.nd_plasma_electrons_vol_avg, + rmajor=self.data.physics.rmajor, + temp_plasma_electron_vol_avg_kev=self.data.physics.temp_plasma_electron_vol_avg_kev, c_hcd_driven=self.data.current_drive.c_hcd_primary_driven, p_hcd_injected=self.data.current_drive.p_hcd_primary_injected_mw * 1.0e6, ) @@ -1857,9 +1854,9 @@ def current_drive(self): # Calculate the dimensionless current drive efficiency for the secondary # heating method (ζ) self.data.current_drive.eta_cd_dimensionless_hcd_secondary = self.calculate_dimensionless_current_drive_efficiency( - nd_plasma_electrons_vol_avg=physics_variables.nd_plasma_electrons_vol_avg, - rmajor=physics_variables.rmajor, - temp_plasma_electron_vol_avg_kev=physics_variables.temp_plasma_electron_vol_avg_kev, + nd_plasma_electrons_vol_avg=self.data.physics.nd_plasma_electrons_vol_avg, + rmajor=self.data.physics.rmajor, + temp_plasma_electron_vol_avg_kev=self.data.physics.temp_plasma_electron_vol_avg_kev, c_hcd_driven=self.data.current_drive.c_hcd_secondary_driven, p_hcd_injected=self.data.current_drive.p_hcd_secondary_injected_mw * 1.0e6, @@ -2281,16 +2278,16 @@ def current_drive(self): ) # Reset injected power to zero for ignited plasma (fudge) - if physics_variables.i_plasma_ignited == 1: + if self.data.physics.i_plasma_ignited == 1: self.data.heat_transport.p_hcd_electric_total_mw = 0.0e0 # Ratio of fusion to input (injection+ohmic) power self.data.current_drive.big_q_plasma = ( - physics_variables.p_fusion_total_mw + self.data.physics.p_fusion_total_mw / ( self.data.current_drive.p_hcd_injected_total_mw + self.data.current_drive.p_beam_orbit_loss_mw - + physics_variables.p_plasma_ohmic_mw + + self.data.physics.p_plasma_ohmic_mw ) ) @@ -2383,15 +2380,15 @@ def output(self): self.outfile, "Ignited plasma switch (0=not ignited, 1=ignited)", "(i_plasma_ignited)", - physics_variables.i_plasma_ignited, + self.data.physics.i_plasma_ignited, ) - if physics_variables.i_plasma_ignited == 1: + if self.data.physics.i_plasma_ignited == 1: po.ocmmnt( self.outfile, "Ignited plasma; injected power only used for start-up phase", ) po.oblnkl(self.outfile) - if abs(physics_variables.f_c_plasma_inductive) > 1.0e-8: + if abs(self.data.physics.f_c_plasma_inductive) > 1.0e-8: po.ocmmnt( self.outfile, "Current is driven by both inductive and non-inductive means.", @@ -2946,24 +2943,24 @@ def output(self): self.outfile, "Auxiliary current drive fraction", "(f_c_plasma_auxiliary)", - physics_variables.f_c_plasma_auxiliary, + self.data.physics.f_c_plasma_auxiliary, "OP ", ) po.ovarrf( self.outfile, "Inductive fraction", "(f_c_plasma_inductive)", - physics_variables.f_c_plasma_inductive, + self.data.physics.f_c_plasma_inductive, "OP ", ) - # MDK Add physics_variables.f_c_plasma_non_inductive as it can be an iteration + # MDK Add self.data.physics.f_c_plasma_non_inductive as it can be an iteration # variable po.ovarrf( self.outfile, "Fraction of the plasma current produced by non-inductive means", "(f_c_plasma_non_inductive)", - physics_variables.f_c_plasma_non_inductive, + self.data.physics.f_c_plasma_non_inductive, ) if ( diff --git a/process/models/physics/density_limit.py b/process/models/physics/density_limit.py index 8ef3c46772..2a5d486197 100644 --- a/process/models/physics/density_limit.py +++ b/process/models/physics/density_limit.py @@ -15,9 +15,6 @@ from process.core import process_output as po from process.core.exceptions import ProcessValueError from process.core.model import Model -from process.data_structure import ( - physics_variables, -) logger = logging.getLogger(__name__) @@ -75,35 +72,38 @@ def run(self): ProcessValueError If i_density_limit has an illegal value. """ - physics_variables.nd_plasma_electron_max_array, _ = self.calculate_density_limit( - b_plasma_toroidal_on_axis=physics_variables.b_plasma_toroidal_on_axis, - i_density_limit=physics_variables.i_density_limit, - p_plasma_separatrix_mw=physics_variables.p_plasma_separatrix_mw, + self.data.physics.nd_plasma_electron_max_array, _ = self.calculate_density_limit( + b_plasma_toroidal_on_axis=self.data.physics.b_plasma_toroidal_on_axis, + i_density_limit=self.data.physics.i_density_limit, + p_plasma_separatrix_mw=self.data.physics.p_plasma_separatrix_mw, p_hcd_injected_total_mw=self.data.current_drive.p_hcd_injected_total_mw, - plasma_current=physics_variables.plasma_current, + plasma_current=self.data.physics.plasma_current, prn1=self.data.divertor.prn1, - qcyl=physics_variables.qstar, - q95=physics_variables.q95, - rmajor=physics_variables.rmajor, - rminor=physics_variables.rminor, - a_plasma_surface=physics_variables.a_plasma_surface, - zeff=physics_variables.n_charge_plasma_effective_vol_avg, + qcyl=self.data.physics.qstar, + q95=self.data.physics.q95, + rmajor=self.data.physics.rmajor, + rminor=self.data.physics.rminor, + a_plasma_surface=self.data.physics.a_plasma_surface, + zeff=self.data.physics.n_charge_plasma_effective_vol_avg, ) # Calculate beta_norm_max based on i_beta_norm_max try: - model = DensityLimitModel(int(physics_variables.i_density_limit)) - physics_variables.nd_plasma_electrons_max = self.get_density_limit_value( - model + model = DensityLimitModel(int(self.data.physics.i_density_limit)) + self.data.physics.nd_plasma_electrons_max = self.get_density_limit_value( + model, + self.data.physics.nd_plasma_electron_max_array, ) except ValueError: raise ProcessValueError( "Illegal value of i_density_limit", - i_density_limit=physics_variables.i_density_limit, + i_density_limit=self.data.physics.i_density_limit, ) from None @staticmethod - def get_density_limit_value(model: DensityLimitModel) -> float: + def get_density_limit_value( + model: DensityLimitModel, nd_plasma_electron_max_array: np.ndarray + ) -> float: """ Get the density limit value (n_e_max) for the specified model. @@ -112,34 +112,23 @@ def get_density_limit_value(model: DensityLimitModel) -> float: model : DensityLimitModel The density limit model type. + nd_plasma_electron_max_array: np.ndarray + Array of plasma electron density upper limits values (/m3) + Returns ------- float The density limit value (m⁻³). """ model_map = { - DensityLimitModel.ASDEX: physics_variables.nd_plasma_electron_max_array[0], - DensityLimitModel.BORRASS_ITER_I: physics_variables.nd_plasma_electron_max_array[ - 1 - ], - DensityLimitModel.BORRASS_ITER_II: physics_variables.nd_plasma_electron_max_array[ - 2 - ], - DensityLimitModel.JET_EDGE_RADIATION: physics_variables.nd_plasma_electron_max_array[ - 3 - ], - DensityLimitModel.JET_SIMPLE: physics_variables.nd_plasma_electron_max_array[ - 4 - ], - DensityLimitModel.HUGILL_MURAKAMI: physics_variables.nd_plasma_electron_max_array[ - 5 - ], - DensityLimitModel.GREENWALD: physics_variables.nd_plasma_electron_max_array[ - 6 - ], - DensityLimitModel.ASDEX_NEW: physics_variables.nd_plasma_electron_max_array[ - 7 - ], + DensityLimitModel.ASDEX: nd_plasma_electron_max_array[0], + DensityLimitModel.BORRASS_ITER_I: nd_plasma_electron_max_array[1], + DensityLimitModel.BORRASS_ITER_II: nd_plasma_electron_max_array[2], + DensityLimitModel.JET_EDGE_RADIATION: nd_plasma_electron_max_array[3], + DensityLimitModel.JET_SIMPLE: nd_plasma_electron_max_array[4], + DensityLimitModel.HUGILL_MURAKAMI: nd_plasma_electron_max_array[5], + DensityLimitModel.GREENWALD: nd_plasma_electron_max_array[6], + DensityLimitModel.ASDEX_NEW: nd_plasma_electron_max_array[7], } return model_map[model] @@ -626,18 +615,18 @@ def output(self): self.outfile, "Plasma density limit model used", "(i_density_limit)", - physics_variables.i_density_limit, + self.data.physics.i_density_limit, ) po.ocmmnt( self.outfile, "Density limit model selected: " - f"{DensityLimitModel(physics_variables.i_density_limit).full_name}", + f"{DensityLimitModel(self.data.physics.i_density_limit).full_name}", ) po.ovarre( self.outfile, "Density limit from scaling (nₑ<)(/m³)", "(nd_plasma_electrons_max)", - physics_variables.nd_plasma_electrons_max, + self.data.physics.nd_plasma_electrons_max, "OP ", ) po.oblnkl(self.outfile) @@ -645,56 +634,56 @@ def output(self): self.outfile, "Old ASDEX model", "(nd_plasma_electron_max_array(1))", - physics_variables.nd_plasma_electron_max_array[0], + self.data.physics.nd_plasma_electron_max_array[0], "OP ", ) po.ovarre( self.outfile, "Borrass ITER model I", "(nd_plasma_electron_max_array(2))", - physics_variables.nd_plasma_electron_max_array[1], + self.data.physics.nd_plasma_electron_max_array[1], "OP ", ) po.ovarre( self.outfile, "Borrass ITER model II", "(nd_plasma_electron_max_array(3))", - physics_variables.nd_plasma_electron_max_array[2], + self.data.physics.nd_plasma_electron_max_array[2], "OP ", ) po.ovarre( self.outfile, "JET edge radiation model", "(nd_plasma_electron_max_array(4))", - physics_variables.nd_plasma_electron_max_array[3], + self.data.physics.nd_plasma_electron_max_array[3], "OP ", ) po.ovarre( self.outfile, "JET simplified model", "(nd_plasma_electron_max_array(5))", - physics_variables.nd_plasma_electron_max_array[4], + self.data.physics.nd_plasma_electron_max_array[4], "OP ", ) po.ovarre( self.outfile, "Hugill-Murakami Mq model", "(nd_plasma_electron_max_array(6))", - physics_variables.nd_plasma_electron_max_array[5], + self.data.physics.nd_plasma_electron_max_array[5], "OP ", ) po.ovarre( self.outfile, "Greenwald model", "(nd_plasma_electron_max_array(7))", - physics_variables.nd_plasma_electron_max_array[6], + self.data.physics.nd_plasma_electron_max_array[6], "OP ", ) po.ovarre( self.outfile, "ASDEX New", "(nd_plasma_electron_max_array(8))", - physics_variables.nd_plasma_electron_max_array[7], + self.data.physics.nd_plasma_electron_max_array[7], "OP ", ) po.oblnkl(self.outfile) diff --git a/process/models/physics/exhaust.py b/process/models/physics/exhaust.py index b95219e7cb..2b3a30e321 100644 --- a/process/models/physics/exhaust.py +++ b/process/models/physics/exhaust.py @@ -5,7 +5,6 @@ from process.core import constants from process.core import process_output as po from process.core.model import Model -from process.data_structure import physics_variables logger = logging.getLogger(__name__) @@ -27,15 +26,15 @@ def output(self): self.outfile, "Plasma separatrix power (Pₛₑₚ) (MW)", "(p_plasma_separatrix_mw)", - physics_variables.p_plasma_separatrix_mw, + self.data.physics.p_plasma_separatrix_mw, "OP ", ) - if physics_variables.p_plasma_separatrix_mw <= 0.001e0: + if self.data.physics.p_plasma_separatrix_mw <= 0.001e0: logger.error( "Possible problem with high radiation power, forcing " "p_plasma_separatrix_mw to odd values. " - f"{physics_variables.p_plasma_separatrix_mw=}" + f"{self.data.physics.p_plasma_separatrix_mw=}" ) po.oblnkl(self.outfile) po.ocmmnt( @@ -55,7 +54,7 @@ def output(self): "Plasma separatrix power over major radius (Pₛₑₚ / R₀) (MW/m) " "(On peak divertor)", "(p_plasma_separatrix_rmajor_mw)", - physics_variables.p_plasma_separatrix_rmajor_mw, + self.data.physics.p_plasma_separatrix_rmajor_mw, "OP ", ) po.ovarre( @@ -63,7 +62,7 @@ def output(self): "EU-DEMO divertor protection re-attachment metric (PₛₑₚBₜ / q₉₅AR₀) " "(MWT/m) (On peak divertor)", "(p_div_bt_q_aspect_rmajor_mw)", - physics_variables.p_div_bt_q_aspect_rmajor_mw, + self.data.physics.p_div_bt_q_aspect_rmajor_mw, "OP ", ) else: @@ -72,7 +71,7 @@ def output(self): self.outfile, "Plasma separatrix power over major radius (Pₛₑₚ / R₀) (MW/m)", "(p_plasma_separatrix_rmajor_mw)", - physics_variables.p_plasma_separatrix_rmajor_mw, + self.data.physics.p_plasma_separatrix_rmajor_mw, "OP ", ) po.ovarre( @@ -80,7 +79,7 @@ def output(self): "EU-DEMO divertor protection re-attachment metric (PₛₑₚBₜ / q₉₅AR₀) " "(MWT/m)", "(p_div_bt_q_aspect_rmajor_mw)", - physics_variables.p_div_bt_q_aspect_rmajor_mw, + self.data.physics.p_div_bt_q_aspect_rmajor_mw, "OP ", ) diff --git a/process/models/physics/fusion_reactions.py b/process/models/physics/fusion_reactions.py index f5f9be3fe2..4ad5305d52 100644 --- a/process/models/physics/fusion_reactions.py +++ b/process/models/physics/fusion_reactions.py @@ -7,7 +7,8 @@ from scipy import integrate from process.core import constants -from process.data_structure import physics_variables +from process.core.model import Model +from process.data_structure.physics_variables import PhysicsData from process.models.physics.plasma_profiles import PlasmaProfile logger = logging.getLogger(__name__) @@ -62,7 +63,7 @@ } -class FusionReactionRate: +class FusionReactionRate(Model): """Calculate the fusion reaction rate for each reaction case (DT, DHE3, DD1, DD2). This class provides methods to numerically integrate over the plasma cross-section @@ -125,6 +126,12 @@ def __init__(self, plasma_profile: PlasmaProfile): self.proton_rate_density = 0.0 self.f_dd_branching_trit = 0.0 + def run(self): + """This model isn't run""" + + def output(self): + """This model has no output""" + def deuterium_branching(self, ion_temperature: float) -> float: """Calculate the relative rate of tritium producing D-D reactions to 3He ones based on the volume averaged ion temperature @@ -180,22 +187,22 @@ def dt_reaction(self): # Initialize Bosch-Hale constants for the D-T reaction dt = BoschHaleConstants(**REACTION_CONSTANTS_DT) - physics_variables.fusrat_plasma_dt_profile = ( + self.data.physics.fusrat_plasma_dt_profile = ( bosch_hale_reactivity( ( - physics_variables.temp_plasma_ion_vol_avg_kev - / physics_variables.temp_plasma_electron_vol_avg_kev + self.data.physics.temp_plasma_ion_vol_avg_kev + / self.data.physics.temp_plasma_electron_vol_avg_kev ) * self.plasma_profile.teprofile.profile_y, dt, ) - * physics_variables.f_plasma_fuel_deuterium - * physics_variables.f_plasma_fuel_tritium + * self.data.physics.f_plasma_fuel_deuterium + * self.data.physics.f_plasma_fuel_tritium * ( self.plasma_profile.neprofile.profile_y * ( - physics_variables.nd_plasma_fuel_ions_vol_avg - / physics_variables.nd_plasma_electrons_vol_avg + self.data.physics.nd_plasma_fuel_ions_vol_avg + / self.data.physics.nd_plasma_electrons_vol_avg ) ) ** 2 @@ -206,6 +213,7 @@ def dt_reaction(self): fusion_rate_integral(self.plasma_profile, dt), x=self.plasma_profile.neprofile.profile_x, dx=self.plasma_profile.neprofile.profile_dx, + physics_data=self.data.physics, ) # Store the average fusion reaction rate @@ -219,12 +227,12 @@ def dt_reaction(self): sigmav * reaction_energy * ( - physics_variables.f_plasma_fuel_deuterium - * physics_variables.nd_plasma_fuel_ions_vol_avg + self.data.physics.f_plasma_fuel_deuterium + * self.data.physics.nd_plasma_fuel_ions_vol_avg ) * ( - physics_variables.f_plasma_fuel_tritium - * physics_variables.nd_plasma_fuel_ions_vol_avg + self.data.physics.f_plasma_fuel_tritium + * self.data.physics.nd_plasma_fuel_ions_vol_avg ) ) @@ -285,24 +293,25 @@ def dhe3_reaction(self): fusion_rate_integral(self.plasma_profile, dhe3), x=self.plasma_profile.neprofile.profile_x, dx=self.plasma_profile.neprofile.profile_dx, + physics_data=self.data.physics, ) - physics_variables.fusrat_plasma_dhe3_profile = ( + self.data.physics.fusrat_plasma_dhe3_profile = ( bosch_hale_reactivity( ( - physics_variables.temp_plasma_ion_vol_avg_kev - / physics_variables.temp_plasma_electron_vol_avg_kev + self.data.physics.temp_plasma_ion_vol_avg_kev + / self.data.physics.temp_plasma_electron_vol_avg_kev ) * self.plasma_profile.teprofile.profile_y, dhe3, ) - * physics_variables.f_plasma_fuel_deuterium - * physics_variables.f_plasma_fuel_helium3 + * self.data.physics.f_plasma_fuel_deuterium + * self.data.physics.f_plasma_fuel_helium3 * ( self.plasma_profile.neprofile.profile_y * ( - physics_variables.nd_plasma_fuel_ions_vol_avg - / physics_variables.nd_plasma_electrons_vol_avg + self.data.physics.nd_plasma_fuel_ions_vol_avg + / self.data.physics.nd_plasma_electrons_vol_avg ) ) ** 2 @@ -316,12 +325,12 @@ def dhe3_reaction(self): sigmav * reaction_energy * ( - physics_variables.f_plasma_fuel_deuterium - * physics_variables.nd_plasma_fuel_ions_vol_avg + self.data.physics.f_plasma_fuel_deuterium + * self.data.physics.nd_plasma_fuel_ions_vol_avg ) * ( - physics_variables.f_plasma_fuel_helium3 - * physics_variables.nd_plasma_fuel_ions_vol_avg + self.data.physics.f_plasma_fuel_helium3 + * self.data.physics.nd_plasma_fuel_ions_vol_avg ) ) @@ -382,24 +391,25 @@ def dd_helion_reaction(self): fusion_rate_integral(self.plasma_profile, dd1), x=self.plasma_profile.neprofile.profile_x, dx=self.plasma_profile.neprofile.profile_dx, + physics_data=self.data.physics, ) - physics_variables.fusrat_plasma_dd_helion_profile = ( + self.data.physics.fusrat_plasma_dd_helion_profile = ( bosch_hale_reactivity( ( - physics_variables.temp_plasma_ion_vol_avg_kev - / physics_variables.temp_plasma_electron_vol_avg_kev + self.data.physics.temp_plasma_ion_vol_avg_kev + / self.data.physics.temp_plasma_electron_vol_avg_kev ) * self.plasma_profile.teprofile.profile_y, dd1, ) - * physics_variables.f_plasma_fuel_deuterium - * physics_variables.f_plasma_fuel_deuterium + * self.data.physics.f_plasma_fuel_deuterium + * self.data.physics.f_plasma_fuel_deuterium * ( self.plasma_profile.neprofile.profile_y * ( - physics_variables.nd_plasma_fuel_ions_vol_avg - / physics_variables.nd_plasma_electrons_vol_avg + self.data.physics.nd_plasma_fuel_ions_vol_avg + / self.data.physics.nd_plasma_electrons_vol_avg ) ) ** 2 @@ -416,12 +426,12 @@ def dd_helion_reaction(self): * reaction_energy * (1.0 - self.f_dd_branching_trit) * ( - physics_variables.f_plasma_fuel_deuterium - * physics_variables.nd_plasma_fuel_ions_vol_avg + self.data.physics.f_plasma_fuel_deuterium + * self.data.physics.nd_plasma_fuel_ions_vol_avg ) * ( - physics_variables.f_plasma_fuel_deuterium - * physics_variables.nd_plasma_fuel_ions_vol_avg + self.data.physics.f_plasma_fuel_deuterium + * self.data.physics.nd_plasma_fuel_ions_vol_avg ) ) @@ -482,24 +492,25 @@ def dd_triton_reaction(self): fusion_rate_integral(self.plasma_profile, dd2), x=self.plasma_profile.neprofile.profile_x, dx=self.plasma_profile.neprofile.profile_dx, + physics_data=self.data.physics, ) - physics_variables.fusrat_plasma_dd_triton_profile = ( + self.data.physics.fusrat_plasma_dd_triton_profile = ( bosch_hale_reactivity( ( - physics_variables.temp_plasma_ion_vol_avg_kev - / physics_variables.temp_plasma_electron_vol_avg_kev + self.data.physics.temp_plasma_ion_vol_avg_kev + / self.data.physics.temp_plasma_electron_vol_avg_kev ) * self.plasma_profile.teprofile.profile_y, dd2, ) - * physics_variables.f_plasma_fuel_deuterium - * physics_variables.f_plasma_fuel_deuterium + * self.data.physics.f_plasma_fuel_deuterium + * self.data.physics.f_plasma_fuel_deuterium * ( self.plasma_profile.neprofile.profile_y * ( - physics_variables.nd_plasma_fuel_ions_vol_avg - / physics_variables.nd_plasma_electrons_vol_avg + self.data.physics.nd_plasma_fuel_ions_vol_avg + / self.data.physics.nd_plasma_electrons_vol_avg ) ) ** 2 @@ -516,12 +527,12 @@ def dd_triton_reaction(self): * reaction_energy * self.f_dd_branching_trit * ( - physics_variables.f_plasma_fuel_deuterium - * physics_variables.nd_plasma_fuel_ions_vol_avg + self.data.physics.f_plasma_fuel_deuterium + * self.data.physics.nd_plasma_fuel_ions_vol_avg ) * ( - physics_variables.f_plasma_fuel_deuterium - * physics_variables.nd_plasma_fuel_ions_vol_avg + self.data.physics.f_plasma_fuel_deuterium + * self.data.physics.nd_plasma_fuel_ions_vol_avg ) ) @@ -611,24 +622,24 @@ def calculate_fusion_rates(self): def set_physics_variables(self): """Set the required physics variables in the physics_variables and - physics_module modules. + physics modules. This method updates the global physics variables and module variables with the current instance's fusion power densities and reaction rates. """ - physics_variables.pden_plasma_alpha_mw = self.alpha_power_density - physics_variables.pden_non_alpha_charged_mw = self.pden_non_alpha_charged_mw - physics_variables.pden_plasma_neutron_mw = self.neutron_power_density - physics_variables.fusden_plasma = self.fusion_rate_density - physics_variables.fusden_plasma_alpha = self.alpha_rate_density - physics_variables.proton_rate_density = self.proton_rate_density - physics_variables.sigmav_dt_average = self.sigmav_dt_average - physics_variables.dt_power_density_plasma = self.dt_power_density - physics_variables.dhe3_power_density = self.dhe3_power_density - physics_variables.dd_power_density = self.dd_power_density - physics_variables.f_dd_branching_trit = self.f_dd_branching_trit + self.data.physics.pden_plasma_alpha_mw = self.alpha_power_density + self.data.physics.pden_non_alpha_charged_mw = self.pden_non_alpha_charged_mw + self.data.physics.pden_plasma_neutron_mw = self.neutron_power_density + self.data.physics.fusden_plasma = self.fusion_rate_density + self.data.physics.fusden_plasma_alpha = self.alpha_rate_density + self.data.physics.proton_rate_density = self.proton_rate_density + self.data.physics.sigmav_dt_average = self.sigmav_dt_average + self.data.physics.dt_power_density_plasma = self.dt_power_density + self.data.physics.dhe3_power_density = self.dhe3_power_density + self.data.physics.dd_power_density = self.dd_power_density + self.data.physics.f_dd_branching_trit = self.f_dd_branching_trit @dataclass @@ -649,7 +660,9 @@ class BoschHaleConstants: def fusion_rate_integral( - plasma_profile: PlasmaProfile, reaction_constants: BoschHaleConstants + plasma_profile: PlasmaProfile, + reaction_constants: BoschHaleConstants, + physics_data: PhysicsData, ) -> np.ndarray: """Evaluate the integrand for the fusion power integration. @@ -659,7 +672,8 @@ def fusion_rate_integral( Parameterised temperature and density profiles. reaction_constants : Bosch-Hale reaction constants. - + physics_data: PhysicsData + physics dataclass Returns ------- @@ -676,8 +690,8 @@ def fusion_rate_integral( # ion temperature profile by the ratio of the volume averaged ion to electron # temperature ion_temperature_profile = ( - physics_variables.temp_plasma_ion_vol_avg_kev - / physics_variables.temp_plasma_electron_vol_avg_kev + physics_data.temp_plasma_ion_vol_avg_kev + / physics_data.temp_plasma_electron_vol_avg_kev ) * plasma_profile.teprofile.profile_y # Number of fusion reactions per unit volume per particle volume density (m³/s) @@ -690,7 +704,7 @@ def fusion_rate_integral( # Set each point in the desnity profile as a fraction of the volume averaged desnity density_profile_normalised = ( - 1.0 / physics_variables.nd_plasma_electrons_vol_avg + 1.0 / physics_data.nd_plasma_electrons_vol_avg ) * plasma_profile.neprofile.profile_y # Calculate a volume averaged fusion reaction integral that allows for fusion power @@ -784,6 +798,7 @@ def set_fusion_powers( pden_plasma_neutron_mw: float, vol_plasma: float, pden_plasma_alpha_mw: float, + f_p_alpha_plasma_deposited: float, ) -> tuple: """Computes various fusion power metrics based on the provided plasma parameters. @@ -804,6 +819,8 @@ def set_fusion_powers( float pden_plasma_alpha_mw : float + f_p_alpha_plasma_deposited: float + Fraction of alpha power deposited in plasma Returns ------- @@ -875,13 +892,9 @@ def set_fusion_powers( # Alpha power to electrons and ions (used with electron # and ion power balance equations only) # No consideration of pden_non_alpha_charged_mw here. - f_pden_alpha_ions_mw = ( - physics_variables.f_p_alpha_plasma_deposited * pden_alpha_total_mw * f_alpha_ion - ) + f_pden_alpha_ions_mw = f_p_alpha_plasma_deposited * pden_alpha_total_mw * f_alpha_ion f_pden_alpha_electron_mw = ( - physics_variables.f_p_alpha_plasma_deposited - * pden_alpha_total_mw - * f_alpha_electron + f_p_alpha_plasma_deposited * pden_alpha_total_mw * f_alpha_electron ) return ( diff --git a/process/models/physics/l_h_transition.py b/process/models/physics/l_h_transition.py index ef84fdb281..ac9fb80ee5 100644 --- a/process/models/physics/l_h_transition.py +++ b/process/models/physics/l_h_transition.py @@ -5,10 +5,7 @@ from process.core import constants from process.core import process_output as po -from process.data_structure import ( - numerics, - physics_variables, -) +from process.data_structure import numerics logger = logging.getLogger(__name__) @@ -73,21 +70,21 @@ def run(self) -> None: and sets the enforced L-H power threshold value based on the selected scaling. """ # Calculate L- to H-mode power threshold for different scalings - physics_variables.l_h_threshold_powers = self.l_h_threshold_power( - physics_variables.nd_plasma_electron_line, - physics_variables.b_plasma_toroidal_on_axis, - physics_variables.rmajor, - physics_variables.rminor, - physics_variables.kappa, - physics_variables.a_plasma_surface, - physics_variables.m_ions_total_amu, - physics_variables.aspect, - physics_variables.plasma_current, + self.data.physics.l_h_threshold_powers = self.l_h_threshold_power( + self.data.physics.nd_plasma_electron_line, + self.data.physics.b_plasma_toroidal_on_axis, + self.data.physics.rmajor, + self.data.physics.rminor, + self.data.physics.kappa, + self.data.physics.a_plasma_surface, + self.data.physics.m_ions_total_amu, + self.data.physics.aspect, + self.data.physics.plasma_current, ) # Enforced L-H power threshold value (if constraint 15 is turned on) - physics_variables.p_l_h_threshold_mw = physics_variables.l_h_threshold_powers[ - physics_variables.i_l_h_threshold - 1 + self.data.physics.p_l_h_threshold_mw = self.data.physics.l_h_threshold_powers[ + self.data.physics.i_l_h_threshold - 1 ] def l_h_threshold_power( @@ -296,7 +293,7 @@ def l_h_threshold_power( martin_lb_aspect, ] - def output_l_h_threshold_powers(self) -> None: + def output(self) -> None: """Output L-H transition power thresholds to file.""" po.oheadr(self.outfile, "H-mode Power Threshold Scalings :") @@ -304,18 +301,18 @@ def output_l_h_threshold_powers(self) -> None: self.outfile, "L-H threshold scaling switch", "(i_l_h_threshold)", - physics_variables.i_l_h_threshold, + self.data.physics.i_l_h_threshold, ) po.ocmmnt( self.outfile, - f"{PlasmaConfinementTransitionModel(physics_variables.i_l_h_threshold).full_name}", + f"{PlasmaConfinementTransitionModel(self.data.physics.i_l_h_threshold).full_name}", ) if (numerics.ioptimz > 0) and (numerics.active_constraints[14]): po.ovarre( self.outfile, "L-H threshold power (MW)", "(p_l_h_threshold_mw)", - physics_variables.p_l_h_threshold_mw, + self.data.physics.p_l_h_threshold_mw, "OP ", ) else: @@ -323,7 +320,7 @@ def output_l_h_threshold_powers(self) -> None: self.outfile, "L-H threshold power (NOT enforced) (MW)", "(p_l_h_threshold_mw)", - physics_variables.p_l_h_threshold_mw, + self.data.physics.p_l_h_threshold_mw, "OP ", ) po.oblnkl(self.outfile) @@ -332,153 +329,153 @@ def output_l_h_threshold_powers(self) -> None: self.outfile, "ITER 1996 scaling: nominal (MW)", "(l_h_threshold_powers(1))", - physics_variables.l_h_threshold_powers[0], + self.data.physics.l_h_threshold_powers[0], "OP ", ) po.ovarre( self.outfile, "ITER 1996 scaling: upper bound (MW)", "(l_h_threshold_powers(2))", - physics_variables.l_h_threshold_powers[1], + self.data.physics.l_h_threshold_powers[1], "OP ", ) po.ovarre( self.outfile, "ITER 1996 scaling: lower bound (MW)", "(l_h_threshold_powers(3))", - physics_variables.l_h_threshold_powers[2], + self.data.physics.l_h_threshold_powers[2], "OP ", ) po.ovarre( self.outfile, "ITER 1997 scaling (1) (MW)", "(l_h_threshold_powers(4))", - physics_variables.l_h_threshold_powers[3], + self.data.physics.l_h_threshold_powers[3], "OP ", ) po.ovarre( self.outfile, "ITER 1997 scaling (2) (MW)", "(l_h_threshold_powers(5))", - physics_variables.l_h_threshold_powers[4], + self.data.physics.l_h_threshold_powers[4], "OP ", ) po.ovarre( self.outfile, "Martin 2008 scaling: nominal (MW)", "(l_h_threshold_powers(6))", - physics_variables.l_h_threshold_powers[5], + self.data.physics.l_h_threshold_powers[5], "OP ", ) po.ovarre( self.outfile, "Martin 2008 scaling: 95% upper bound (MW)", "(l_h_threshold_powers(7))", - physics_variables.l_h_threshold_powers[6], + self.data.physics.l_h_threshold_powers[6], "OP ", ) po.ovarre( self.outfile, "Martin 2008 scaling: 95% lower bound (MW)", "(l_h_threshold_powers(8))", - physics_variables.l_h_threshold_powers[7], + self.data.physics.l_h_threshold_powers[7], "OP ", ) po.ovarre( self.outfile, "Snipes 2000 scaling: nominal (MW)", "(l_h_threshold_powers(9))", - physics_variables.l_h_threshold_powers[8], + self.data.physics.l_h_threshold_powers[8], "OP ", ) po.ovarre( self.outfile, "Snipes 2000 scaling: upper bound (MW)", "(l_h_threshold_powers(10))", - physics_variables.l_h_threshold_powers[9], + self.data.physics.l_h_threshold_powers[9], "OP ", ) po.ovarre( self.outfile, "Snipes 2000 scaling: lower bound (MW)", "(l_h_threshold_powers(11))", - physics_variables.l_h_threshold_powers[10], + self.data.physics.l_h_threshold_powers[10], "OP ", ) po.ovarre( self.outfile, "Snipes 2000 scaling (closed divertor): nominal (MW)", "(l_h_threshold_powers(12))", - physics_variables.l_h_threshold_powers[11], + self.data.physics.l_h_threshold_powers[11], "OP ", ) po.ovarre( self.outfile, "Snipes 2000 scaling (closed divertor): upper bound (MW)", "(l_h_threshold_powers(13))", - physics_variables.l_h_threshold_powers[12], + self.data.physics.l_h_threshold_powers[12], "OP ", ) po.ovarre( self.outfile, "Snipes 2000 scaling (closed divertor): lower bound (MW)", "(l_h_threshold_powers(14))", - physics_variables.l_h_threshold_powers[13], + self.data.physics.l_h_threshold_powers[13], "OP ", ) po.ovarre( self.outfile, "Hubbard 2012 L-I threshold - nominal (MW)", "(l_h_threshold_powers(15))", - physics_variables.l_h_threshold_powers[14], + self.data.physics.l_h_threshold_powers[14], "OP ", ) po.ovarre( self.outfile, "Hubbard 2012 L-I threshold - lower bound (MW)", "(l_h_threshold_powers(16))", - physics_variables.l_h_threshold_powers[15], + self.data.physics.l_h_threshold_powers[15], "OP ", ) po.ovarre( self.outfile, "Hubbard 2012 L-I threshold - upper bound (MW)", "(l_h_threshold_powers(17))", - physics_variables.l_h_threshold_powers[16], + self.data.physics.l_h_threshold_powers[16], "OP ", ) po.ovarre( self.outfile, "Hubbard 2017 L-I threshold", "(l_h_threshold_powers(18))", - physics_variables.l_h_threshold_powers[17], + self.data.physics.l_h_threshold_powers[17], "OP ", ) po.ovarre( self.outfile, "Martin 2008 aspect ratio corrected scaling: nominal (MW)", "(l_h_threshold_powers(19))", - physics_variables.l_h_threshold_powers[18], + self.data.physics.l_h_threshold_powers[18], "OP ", ) po.ovarre( self.outfile, "Martin 2008 aspect ratio corrected scaling: 95% upper bound (MW)", "(l_h_threshold_powers(20))", - physics_variables.l_h_threshold_powers[19], + self.data.physics.l_h_threshold_powers[19], "OP ", ) po.ovarre( self.outfile, "Martin 2008 aspect ratio corrected scaling: 95% lower bound (MW)", "(l_h_threshold_powers(21))", - physics_variables.l_h_threshold_powers[20], + self.data.physics.l_h_threshold_powers[20], "OP ", ) po.oblnkl(self.outfile) - if physics_variables.i_l_h_threshold in {9, 10, 11}: - if (physics_variables.b_plasma_toroidal_on_axis < 0.78e0) or ( - physics_variables.b_plasma_toroidal_on_axis > 7.94e0 + if self.data.physics.i_l_h_threshold in {9, 10, 11}: + if (self.data.physics.b_plasma_toroidal_on_axis < 0.78e0) or ( + self.data.physics.b_plasma_toroidal_on_axis > 7.94e0 ): po.ocmmnt( self.outfile, @@ -488,47 +485,47 @@ def output_l_h_threshold_powers(self) -> None: "b_plasma_toroidal_on_axis outside Snipes 2000 fitted range" ) - if (physics_variables.rminor < 0.15e0) or ( - physics_variables.rminor > 1.15e0 + if (self.data.physics.rminor < 0.15e0) or ( + self.data.physics.rminor > 1.15e0 ): po.ocmmnt(self.outfile, "(rminor outside Snipes 2000 fitted range)") logger.warning("rminor outside Snipes 2000 fitted range") - if (physics_variables.rmajor < 0.55e0) or ( - physics_variables.rmajor > 3.37e0 + if (self.data.physics.rmajor < 0.55e0) or ( + self.data.physics.rmajor > 3.37e0 ): po.ocmmnt( self.outfile, - "(physics_variables.rmajor outside Snipes 2000 fitted range)", + "(self.data.physics.rmajor outside Snipes 2000 fitted range)", ) logger.warning("rmajor outside Snipes 2000 fitted range") - if (physics_variables.nd_plasma_electron_line < 0.09e20) or ( - physics_variables.nd_plasma_electron_line > 3.16e20 + if (self.data.physics.nd_plasma_electron_line < 0.09e20) or ( + self.data.physics.nd_plasma_electron_line > 3.16e20 ): po.ocmmnt( self.outfile, - "(physics_variables.nd_plasma_electron_line outside Snipes 2000 " + "(self.data.physics.nd_plasma_electron_line outside Snipes 2000 " "fitted range)", ) logger.warning( "nd_plasma_electron_line outside Snipes 2000 fitted range" ) - if (physics_variables.kappa < 1.0e0) or (physics_variables.kappa > 2.04e0): + if (self.data.physics.kappa < 1.0e0) or (self.data.physics.kappa > 2.04e0): po.ocmmnt( self.outfile, - "(physics_variables.kappa outside Snipes 2000 fitted range)", + "(self.data.physics.kappa outside Snipes 2000 fitted range)", ) logger.warning("kappa outside Snipes 2000 fitted range") - if (physics_variables.triang < 0.07e0) or ( - physics_variables.triang > 0.74e0 + if (self.data.physics.triang < 0.07e0) or ( + self.data.physics.triang > 0.74e0 ): po.ocmmnt(self.outfile, "(triang outside Snipes 2000 fitted range)") logger.warning("triang outside Snipes 2000 fitted range") - if physics_variables.i_l_h_threshold in {12, 13, 14}: + if self.data.physics.i_l_h_threshold in {12, 13, 14}: po.ocmmnt( self.outfile, "(L-H threshold for closed divertor only. Limited data used in Snipes " diff --git a/process/models/physics/physics.py b/process/models/physics/physics.py index b0df988ca5..7613bfb768 100644 --- a/process/models/physics/physics.py +++ b/process/models/physics/physics.py @@ -17,13 +17,14 @@ from process.core import process_output as po from process.core.exceptions import ProcessValueError from process.core.model import Model -from process.data_structure import numerics, physics_variables +from process.data_structure import numerics from process.data_structure.impurity_radiation_variables import N_IMPURITIES from process.models.physics import impurity_radiation from process.models.physics.plasma_geometry import PlasmaGeom from process.models.physics.profiles import PlasmaProfileShapeType if TYPE_CHECKING: + from process.data_structure.physics_variables import PhysicsData from process.models.physics.bootstrap_current import PlasmaBootstrapCurrent from process.models.physics.confinement_time import ( PlasmaConfinementTime, @@ -243,73 +244,73 @@ def run(self): self.plasma_composition() ( - physics_variables.m_plasma_fuel_ions, - physics_variables.m_plasma_ions_total, - physics_variables.m_plasma_alpha, - physics_variables.m_plasma_electron, - physics_variables.m_plasma, + self.data.physics.m_plasma_fuel_ions, + self.data.physics.m_plasma_ions_total, + self.data.physics.m_plasma_alpha, + self.data.physics.m_plasma_electron, + self.data.physics.m_plasma, ) = self.calculate_plasma_masses( - physics_variables.m_fuel_amu, - physics_variables.m_ions_total_amu, - physics_variables.nd_plasma_ions_total_vol_avg, - physics_variables.nd_plasma_fuel_ions_vol_avg, - physics_variables.nd_plasma_alphas_vol_avg, - physics_variables.vol_plasma, - physics_variables.nd_plasma_electrons_vol_avg, + self.data.physics.m_fuel_amu, + self.data.physics.m_ions_total_amu, + self.data.physics.nd_plasma_ions_total_vol_avg, + self.data.physics.nd_plasma_fuel_ions_vol_avg, + self.data.physics.nd_plasma_alphas_vol_avg, + self.data.physics.vol_plasma, + self.data.physics.nd_plasma_electrons_vol_avg, ) # Define coulomb logarithm # (collisions: ion-electron, electron-electron) - physics_variables.dlamee = ( + self.data.physics.dlamee = ( 31.0 - - (np.log(physics_variables.nd_plasma_electrons_vol_avg) / 2.0) - + np.log(physics_variables.temp_plasma_electron_vol_avg_kev * 1000.0) + - (np.log(self.data.physics.nd_plasma_electrons_vol_avg) / 2.0) + + np.log(self.data.physics.temp_plasma_electron_vol_avg_kev * 1000.0) ) - physics_variables.dlamie = ( + self.data.physics.dlamie = ( 31.3 - - (np.log(physics_variables.nd_plasma_electrons_vol_avg) / 2.0) - + np.log(physics_variables.temp_plasma_electron_vol_avg_kev * 1000.0) + - (np.log(self.data.physics.nd_plasma_electrons_vol_avg) / 2.0) + + np.log(self.data.physics.temp_plasma_electron_vol_avg_kev * 1000.0) ) # Calculate plasma current - physics_variables.plasma_current = self.current.calculate_plasma_current( - physics_variables.alphaj, - physics_variables.alphap, - physics_variables.b_plasma_toroidal_on_axis, - physics_variables.eps, - physics_variables.i_plasma_current, - physics_variables.kappa, - physics_variables.kappa95, - physics_variables.pres_plasma_thermal_on_axis, - physics_variables.len_plasma_poloidal, - physics_variables.q95, - physics_variables.rmajor, - physics_variables.rminor, - physics_variables.triang, - physics_variables.triang95, - ) - - physics_variables.qstar = calculate_cylindrical_safety_factor( - rmajor=physics_variables.rmajor, - rminor=physics_variables.rminor, - plasma_current=physics_variables.plasma_current, - b_plasma_toroidal_on_axis=physics_variables.b_plasma_toroidal_on_axis, - kappa95=physics_variables.kappa95, - triang95=physics_variables.triang95, + self.data.physics.plasma_current = self.current.calculate_plasma_current( + self.data.physics.alphaj, + self.data.physics.alphap, + self.data.physics.b_plasma_toroidal_on_axis, + self.data.physics.eps, + self.data.physics.i_plasma_current, + self.data.physics.kappa, + self.data.physics.kappa95, + self.data.physics.pres_plasma_thermal_on_axis, + self.data.physics.len_plasma_poloidal, + self.data.physics.q95, + self.data.physics.rmajor, + self.data.physics.rminor, + self.data.physics.triang, + self.data.physics.triang95, + ) + + self.data.physics.qstar = calculate_cylindrical_safety_factor( + rmajor=self.data.physics.rmajor, + rminor=self.data.physics.rminor, + plasma_current=self.data.physics.plasma_current, + b_plasma_toroidal_on_axis=self.data.physics.b_plasma_toroidal_on_axis, + kappa95=self.data.physics.kappa95, + triang95=self.data.physics.triang95, ) # Calculate the poloidal field generated by the plasma current - physics_variables.b_plasma_surface_poloidal_average = ( + self.data.physics.b_plasma_surface_poloidal_average = ( self.fields.calculate_surface_averaged_poloidal_field( - i_plasma_current=physics_variables.i_plasma_current, - ip=physics_variables.plasma_current, - q95=physics_variables.q95, - aspect=physics_variables.aspect, - eps=physics_variables.eps, - b_plasma_toroidal_on_axis=physics_variables.b_plasma_toroidal_on_axis, - kappa=physics_variables.kappa, - delta=physics_variables.triang, - perim=physics_variables.len_plasma_poloidal, + i_plasma_current=self.data.physics.i_plasma_current, + ip=self.data.physics.plasma_current, + q95=self.data.physics.q95, + aspect=self.data.physics.aspect, + eps=self.data.physics.eps, + b_plasma_toroidal_on_axis=self.data.physics.b_plasma_toroidal_on_axis, + kappa=self.data.physics.kappa, + delta=self.data.physics.triang, + perim=self.data.physics.len_plasma_poloidal, ) ) @@ -317,25 +318,25 @@ def run(self): # Plasma Current Profile # ----------------------------------------------------- - physics_variables.alphaj_wesson = self.calculate_current_profile_index_wesson( - qstar=physics_variables.qstar, q0=physics_variables.q0 + self.data.physics.alphaj_wesson = self.calculate_current_profile_index_wesson( + qstar=self.data.physics.qstar, q0=self.data.physics.q0 ) # Map calculation methods to a dictionary alphaj_calculations = { - 0: physics_variables.alphaj, - 1: physics_variables.alphaj_wesson, + 0: self.data.physics.alphaj, + 1: self.data.physics.alphaj_wesson, } # Calculate alphaj based on i_alphaj - if int(physics_variables.i_alphaj) in alphaj_calculations: - physics_variables.alphaj = alphaj_calculations[ - int(physics_variables.i_alphaj) + if int(self.data.physics.i_alphaj) in alphaj_calculations: + self.data.physics.alphaj = alphaj_calculations[ + int(self.data.physics.i_alphaj) ] else: raise ProcessValueError( "Illegal value of i_alphaj", - i_alphaj=physics_variables.i_alphaj, + i_alphaj=self.data.physics.i_alphaj, ) # ================================================== @@ -349,65 +350,65 @@ def run(self): # =================================================== # Calculate density and temperature profile quantities - # If physics_variables.i_plasma_pedestal = 1 then set pedestal density to - # physics_variables.f_nd_plasma_pedestal_greenwald * Greenwald density limit + # If self.data.physics.i_plasma_pedestal = 1 then set pedestal density to + # self.data.physics.f_nd_plasma_pedestal_greenwald * Greenwald density limit # Note: this used to be done before plasma current if ( - PlasmaProfileShapeType(physics_variables.i_plasma_pedestal) + PlasmaProfileShapeType(self.data.physics.i_plasma_pedestal) == PlasmaProfileShapeType.PEDESTAL_PROFILE - ) and (physics_variables.f_nd_plasma_pedestal_greenwald >= 0e0): - physics_variables.nd_plasma_pedestal_electron = ( - physics_variables.f_nd_plasma_pedestal_greenwald + ) and (self.data.physics.f_nd_plasma_pedestal_greenwald >= 0e0): + self.data.physics.nd_plasma_pedestal_electron = ( + self.data.physics.f_nd_plasma_pedestal_greenwald * 1.0e14 - * physics_variables.plasma_current - / (np.pi * physics_variables.rminor * physics_variables.rminor) + * self.data.physics.plasma_current + / (np.pi * self.data.physics.rminor * self.data.physics.rminor) ) if ( - PlasmaProfileShapeType(physics_variables.i_plasma_pedestal) + PlasmaProfileShapeType(self.data.physics.i_plasma_pedestal) == PlasmaProfileShapeType.PEDESTAL_PROFILE - ) and (physics_variables.f_nd_plasma_separatrix_greenwald >= 0e0): - physics_variables.nd_plasma_separatrix_electron = ( - physics_variables.f_nd_plasma_separatrix_greenwald + ) and (self.data.physics.f_nd_plasma_separatrix_greenwald >= 0e0): + self.data.physics.nd_plasma_separatrix_electron = ( + self.data.physics.f_nd_plasma_separatrix_greenwald * 1.0e14 - * physics_variables.plasma_current - / (np.pi * physics_variables.rminor * physics_variables.rminor) + * self.data.physics.plasma_current + / (np.pi * self.data.physics.rminor * self.data.physics.rminor) ) self.plasma_profile.run() # Calculate total magnetic field [T] - physics_variables.b_plasma_total = self.fields.calculate_total_magnetic_field( - b_plasma_toroidal=physics_variables.b_plasma_toroidal_on_axis, - b_plasma_poloidal=physics_variables.b_plasma_surface_poloidal_average, + self.data.physics.b_plasma_total = self.fields.calculate_total_magnetic_field( + b_plasma_toroidal=self.data.physics.b_plasma_toroidal_on_axis, + b_plasma_poloidal=self.data.physics.b_plasma_surface_poloidal_average, ) # Calculate the inboard and outboard toroidal field - physics_variables.b_plasma_inboard_toroidal = ( + self.data.physics.b_plasma_inboard_toroidal = ( self.fields.calculate_plasma_inboard_toroidal_field( - b_plasma_toroidal_on_axis=physics_variables.b_plasma_toroidal_on_axis, - rmajor=physics_variables.rmajor, - rminor=physics_variables.rminor, + b_plasma_toroidal_on_axis=self.data.physics.b_plasma_toroidal_on_axis, + rmajor=self.data.physics.rmajor, + rminor=self.data.physics.rminor, ) ) - physics_variables.b_plasma_outboard_toroidal = ( + self.data.physics.b_plasma_outboard_toroidal = ( self.fields.calculate_plasma_outboard_toroidal_field( - b_plasma_toroidal_on_axis=physics_variables.b_plasma_toroidal_on_axis, - rmajor=physics_variables.rmajor, - rminor=physics_variables.rminor, + b_plasma_toroidal_on_axis=self.data.physics.b_plasma_toroidal_on_axis, + rmajor=self.data.physics.rmajor, + rminor=self.data.physics.rminor, ) ) # Calculate the toroidal field across the plasma # Calculate the toroidal field profile across the plasma (1/R dependence) # Double element size to include both sides of the plasma - physics_variables.b_plasma_toroidal_profile = ( + self.data.physics.b_plasma_toroidal_profile = ( self.fields.calculate_toroidal_field_profile( - b_plasma_toroidal_on_axis=physics_variables.b_plasma_toroidal_on_axis, - rmajor=physics_variables.rmajor, - rminor=physics_variables.rminor, - n_plasma_profile_elements=physics_variables.n_plasma_profile_elements, + b_plasma_toroidal_on_axis=self.data.physics.b_plasma_toroidal_on_axis, + rmajor=self.data.physics.rmajor, + rminor=self.data.physics.rminor, + n_plasma_profile_elements=self.data.physics.n_plasma_profile_elements, ) ) @@ -425,7 +426,7 @@ def run(self): if self.data.pulse.i_pulsed_plant != 1: if self.data.times.i_t_current_ramp_up == 0: self.data.times.t_plant_pulse_plasma_current_ramp_up = ( - physics_variables.plasma_current / 5.0e5 + self.data.physics.plasma_current / 5.0e5 ) self.data.times.t_plant_pulse_coil_precharge = ( self.data.times.t_plant_pulse_plasma_current_ramp_up @@ -437,7 +438,7 @@ def run(self): elif self.data.times.pulsetimings == 0: # self.data.times.t_plant_pulse_coil_precharge is input self.data.times.t_plant_pulse_plasma_current_ramp_up = ( - physics_variables.plasma_current / 1.0e5 + self.data.physics.plasma_current / 1.0e5 ) self.data.times.t_plant_pulse_plasma_current_ramp_down = ( self.data.times.t_plant_pulse_plasma_current_ramp_up @@ -501,26 +502,26 @@ def run(self): # Pfirsch-Schlüter scaling for diamagnetic current self.data.current_drive.f_c_plasma_pfirsch_schluter_scene = ps_fraction_scene( - physics_variables.beta_total_vol_avg + self.data.physics.beta_total_vol_avg ) - if physics_variables.i_pfirsch_schluter_current == 1: + if self.data.physics.i_pfirsch_schluter_current == 1: self.data.current_drive.f_c_plasma_pfirsch_schluter = ( self.data.current_drive.f_c_plasma_pfirsch_schluter_scene ) self.plasma_bootstrap_current.run() - physics_variables.err242 = 0 + self.data.physics.err242 = 0 if ( self.data.current_drive.f_c_plasma_bootstrap > self.data.current_drive.f_c_plasma_bootstrap_max - ) and physics_variables.i_bootstrap_current != 0: + ) and self.data.physics.i_bootstrap_current != 0: self.data.current_drive.f_c_plasma_bootstrap = min( self.data.current_drive.f_c_plasma_bootstrap, self.data.current_drive.f_c_plasma_bootstrap_max, ) - physics_variables.err242 = 1 + self.data.physics.err242 = 1 self.data.current_drive.f_c_plasma_internal = ( self.data.current_drive.f_c_plasma_bootstrap @@ -533,24 +534,24 @@ def run(self): # or equal to the total fraction of the plasma current # produced by non-inductive means (which also includes # the current drive proportion) - physics_variables.err243 = 0 + self.data.physics.err243 = 0 if ( self.data.current_drive.f_c_plasma_internal - > physics_variables.f_c_plasma_non_inductive + > self.data.physics.f_c_plasma_non_inductive ): self.data.current_drive.f_c_plasma_internal = min( self.data.current_drive.f_c_plasma_internal, - physics_variables.f_c_plasma_non_inductive, + self.data.physics.f_c_plasma_non_inductive, ) - physics_variables.err243 = 1 + self.data.physics.err243 = 1 # Fraction of plasma current produced by inductive means - physics_variables.f_c_plasma_inductive = max( - 1.0e-10, (1.0e0 - physics_variables.f_c_plasma_non_inductive) + self.data.physics.f_c_plasma_inductive = max( + 1.0e-10, (1.0e0 - self.data.physics.f_c_plasma_non_inductive) ) # Fraction of plasma current produced by auxiliary current drive - physics_variables.f_c_plasma_auxiliary = ( - physics_variables.f_c_plasma_non_inductive + self.data.physics.f_c_plasma_auxiliary = ( + self.data.physics.f_c_plasma_non_inductive - self.data.current_drive.f_c_plasma_internal ) @@ -567,183 +568,187 @@ def run(self): fusion_reactions = reactions.FusionReactionRate(self.plasma_profile) fusion_reactions.deuterium_branching( - physics_variables.temp_plasma_ion_vol_avg_kev + self.data.physics.temp_plasma_ion_vol_avg_kev ) fusion_reactions.calculate_fusion_rates() fusion_reactions.set_physics_variables() # This neglects the power from the beam - physics_variables.p_plasma_dt_mw = ( - physics_variables.dt_power_density_plasma * physics_variables.vol_plasma + self.data.physics.p_plasma_dt_mw = ( + self.data.physics.dt_power_density_plasma * self.data.physics.vol_plasma ) - physics_variables.p_dhe3_total_mw = ( - physics_variables.dhe3_power_density * physics_variables.vol_plasma + self.data.physics.p_dhe3_total_mw = ( + self.data.physics.dhe3_power_density * self.data.physics.vol_plasma ) - physics_variables.p_dd_total_mw = ( - physics_variables.dd_power_density * physics_variables.vol_plasma + self.data.physics.p_dd_total_mw = ( + self.data.physics.dd_power_density * self.data.physics.vol_plasma ) # Calculate neutral beam slowing down effects # If ignited, then ignore beam fusion effects if (self.data.current_drive.c_beam_total != 0.0e0) and ( # noqa: RUF069 - physics_variables.i_plasma_ignited == 0 + self.data.physics.i_plasma_ignited == 0 ): ( - physics_variables.beta_beam, - physics_variables.nd_beam_ions_out, - physics_variables.p_beam_alpha_mw, + self.data.physics.beta_beam, + self.data.physics.nd_beam_ions_out, + self.data.physics.p_beam_alpha_mw, ) = reactions.beam_fusion( - physics_variables.beamfus0, - physics_variables.betbm0, - physics_variables.b_plasma_total, + self.data.physics.beamfus0, + self.data.physics.betbm0, + self.data.physics.b_plasma_total, self.data.current_drive.c_beam_total, - physics_variables.nd_plasma_electrons_vol_avg, - physics_variables.nd_plasma_fuel_ions_vol_avg, - physics_variables.dlamie, + self.data.physics.nd_plasma_electrons_vol_avg, + self.data.physics.nd_plasma_fuel_ions_vol_avg, + self.data.physics.dlamie, self.data.current_drive.e_beam_kev, - physics_variables.f_plasma_fuel_deuterium, - physics_variables.f_plasma_fuel_tritium, + self.data.physics.f_plasma_fuel_deuterium, + self.data.physics.f_plasma_fuel_tritium, self.data.current_drive.f_beam_tritium, - physics_variables.temp_plasma_electron_density_weighted_kev, - physics_variables.vol_plasma, - physics_variables.n_charge_plasma_effective_mass_weighted_vol_avg, + self.data.physics.temp_plasma_electron_density_weighted_kev, + self.data.physics.vol_plasma, + self.data.physics.n_charge_plasma_effective_mass_weighted_vol_avg, ) - physics_variables.fusden_total = ( - physics_variables.fusden_plasma + self.data.physics.fusden_total = ( + self.data.physics.fusden_plasma + 1.0e6 - * physics_variables.p_beam_alpha_mw + * self.data.physics.p_beam_alpha_mw / (constants.DT_ALPHA_ENERGY) - / physics_variables.vol_plasma + / self.data.physics.vol_plasma ) - physics_variables.fusden_alpha_total = ( - physics_variables.fusden_plasma_alpha + self.data.physics.fusden_alpha_total = ( + self.data.physics.fusden_plasma_alpha + 1.0e6 - * physics_variables.p_beam_alpha_mw + * self.data.physics.p_beam_alpha_mw / (constants.DT_ALPHA_ENERGY) - / physics_variables.vol_plasma + / self.data.physics.vol_plasma ) - physics_variables.p_dt_total_mw = ( - physics_variables.p_plasma_dt_mw + self.data.physics.p_dt_total_mw = ( + self.data.physics.p_plasma_dt_mw + (1.0 / (1.0 - constants.DT_NEUTRON_ENERGY_FRACTION)) - * physics_variables.p_beam_alpha_mw + * self.data.physics.p_beam_alpha_mw ) - physics_variables.p_beam_neutron_mw = physics_variables.p_beam_alpha_mw * ( + self.data.physics.p_beam_neutron_mw = self.data.physics.p_beam_alpha_mw * ( constants.DT_NEUTRON_ENERGY_FRACTION / (1 - constants.DT_NEUTRON_ENERGY_FRACTION) ) - physics_variables.p_beam_dt_mw = physics_variables.p_beam_alpha_mw * ( + self.data.physics.p_beam_dt_mw = self.data.physics.p_beam_alpha_mw * ( 1 / (1 - constants.DT_NEUTRON_ENERGY_FRACTION) ) else: # If no beams present then the total alpha rates and power are the same as # the plasma values - physics_variables.fusden_total = physics_variables.fusden_plasma - physics_variables.fusden_alpha_total = physics_variables.fusden_plasma_alpha - physics_variables.p_dt_total_mw = physics_variables.p_plasma_dt_mw + self.data.physics.fusden_total = self.data.physics.fusden_plasma + self.data.physics.fusden_alpha_total = self.data.physics.fusden_plasma_alpha + self.data.physics.p_dt_total_mw = self.data.physics.p_plasma_dt_mw - physics_variables.fusrat_total = ( - physics_variables.fusden_total * physics_variables.vol_plasma + self.data.physics.fusrat_total = ( + self.data.physics.fusden_total * self.data.physics.vol_plasma ) # Create some derived values and add beam contribution to fusion power ( - physics_variables.pden_neutron_total_mw, - physics_variables.p_plasma_alpha_mw, - physics_variables.p_alpha_total_mw, - physics_variables.p_plasma_neutron_mw, - physics_variables.p_neutron_total_mw, - physics_variables.p_non_alpha_charged_mw, - physics_variables.pden_alpha_total_mw, - physics_variables.f_pden_alpha_electron_mw, - physics_variables.f_pden_alpha_ions_mw, - physics_variables.p_charged_particle_mw, - physics_variables.p_fusion_total_mw, + self.data.physics.pden_neutron_total_mw, + self.data.physics.p_plasma_alpha_mw, + self.data.physics.p_alpha_total_mw, + self.data.physics.p_plasma_neutron_mw, + self.data.physics.p_neutron_total_mw, + self.data.physics.p_non_alpha_charged_mw, + self.data.physics.pden_alpha_total_mw, + self.data.physics.f_pden_alpha_electron_mw, + self.data.physics.f_pden_alpha_ions_mw, + self.data.physics.p_charged_particle_mw, + self.data.physics.p_fusion_total_mw, ) = reactions.set_fusion_powers( - physics_variables.f_alpha_electron, - physics_variables.f_alpha_ion, - physics_variables.p_beam_alpha_mw, - physics_variables.pden_non_alpha_charged_mw, - physics_variables.pden_plasma_neutron_mw, - physics_variables.vol_plasma, - physics_variables.pden_plasma_alpha_mw, - ) - - physics_variables.beta_fast_alpha = self.beta.fast_alpha_beta( - b_plasma_poloidal_average=physics_variables.b_plasma_surface_poloidal_average, - b_plasma_toroidal_on_axis=physics_variables.b_plasma_toroidal_on_axis, - nd_plasma_electrons_vol_avg=physics_variables.nd_plasma_electrons_vol_avg, - nd_plasma_fuel_ions_vol_avg=physics_variables.nd_plasma_fuel_ions_vol_avg, - nd_plasma_ions_total_vol_avg=physics_variables.nd_plasma_ions_total_vol_avg, - temp_plasma_electron_density_weighted_kev=physics_variables.temp_plasma_electron_density_weighted_kev, - temp_plasma_ion_density_weighted_kev=physics_variables.temp_plasma_ion_density_weighted_kev, - pden_alpha_total_mw=physics_variables.pden_alpha_total_mw, - pden_plasma_alpha_mw=physics_variables.pden_plasma_alpha_mw, - i_beta_fast_alpha=physics_variables.i_beta_fast_alpha, + self.data.physics.f_alpha_electron, + self.data.physics.f_alpha_ion, + self.data.physics.p_beam_alpha_mw, + self.data.physics.pden_non_alpha_charged_mw, + self.data.physics.pden_plasma_neutron_mw, + self.data.physics.vol_plasma, + self.data.physics.pden_plasma_alpha_mw, + self.data.physics.f_p_alpha_plasma_deposited, + ) + + self.data.physics.beta_fast_alpha = self.beta.fast_alpha_beta( + b_plasma_poloidal_average=self.data.physics.b_plasma_surface_poloidal_average, + b_plasma_toroidal_on_axis=self.data.physics.b_plasma_toroidal_on_axis, + nd_plasma_electrons_vol_avg=self.data.physics.nd_plasma_electrons_vol_avg, + nd_plasma_fuel_ions_vol_avg=self.data.physics.nd_plasma_fuel_ions_vol_avg, + nd_plasma_ions_total_vol_avg=self.data.physics.nd_plasma_ions_total_vol_avg, + temp_plasma_electron_density_weighted_kev=self.data.physics.temp_plasma_electron_density_weighted_kev, + temp_plasma_ion_density_weighted_kev=self.data.physics.temp_plasma_ion_density_weighted_kev, + pden_alpha_total_mw=self.data.physics.pden_alpha_total_mw, + pden_plasma_alpha_mw=self.data.physics.pden_plasma_alpha_mw, + i_beta_fast_alpha=self.data.physics.i_beta_fast_alpha, + f_plasma_fuel_deuterium=self.data.physics.f_plasma_fuel_deuterium, ) # Calculate ion/electron equilibration power - physics_variables.pden_ion_electron_equilibration_mw = rether( - physics_variables.alphan, - physics_variables.alphat, - physics_variables.nd_plasma_electrons_vol_avg, - physics_variables.dlamie, - physics_variables.temp_plasma_electron_vol_avg_kev, - physics_variables.temp_plasma_ion_vol_avg_kev, - physics_variables.n_charge_plasma_effective_mass_weighted_vol_avg, + self.data.physics.pden_ion_electron_equilibration_mw = rether( + self.data.physics.alphan, + self.data.physics.alphat, + self.data.physics.nd_plasma_electrons_vol_avg, + self.data.physics.dlamie, + self.data.physics.temp_plasma_electron_vol_avg_kev, + self.data.physics.temp_plasma_ion_vol_avg_kev, + self.data.physics.n_charge_plasma_effective_mass_weighted_vol_avg, ) # Calculate radiation power radpwrdata = physics_funcs.calculate_radiation_powers( self.plasma_profile, - physics_variables.nd_plasma_electron_on_axis, - physics_variables.rminor, - physics_variables.b_plasma_toroidal_on_axis, - physics_variables.aspect, - physics_variables.alphan, - physics_variables.alphat, - physics_variables.tbeta, - physics_variables.temp_plasma_electron_on_axis_kev, - physics_variables.f_sync_reflect, - physics_variables.rmajor, - physics_variables.kappa, - physics_variables.vol_plasma, + self.data.physics.nd_plasma_electron_on_axis, + self.data.physics.rminor, + self.data.physics.b_plasma_toroidal_on_axis, + self.data.physics.aspect, + self.data.physics.alphan, + self.data.physics.alphat, + self.data.physics.tbeta, + self.data.physics.temp_plasma_electron_on_axis_kev, + self.data.physics.f_sync_reflect, + self.data.physics.rmajor, + self.data.physics.kappa, + self.data.physics.vol_plasma, self.data, ) - physics_variables.pden_plasma_sync_mw = radpwrdata.pden_plasma_sync_mw - physics_variables.pden_plasma_core_rad_mw = radpwrdata.pden_plasma_core_rad_mw - physics_variables.pden_plasma_outer_rad_mw = radpwrdata.pden_plasma_outer_rad_mw - physics_variables.pden_plasma_rad_mw = radpwrdata.pden_plasma_rad_mw + self.data.physics.pden_plasma_sync_mw = radpwrdata.pden_plasma_sync_mw + self.data.physics.pden_plasma_core_rad_mw = radpwrdata.pden_plasma_core_rad_mw + self.data.physics.pden_plasma_outer_rad_mw = radpwrdata.pden_plasma_outer_rad_mw + self.data.physics.pden_plasma_rad_mw = radpwrdata.pden_plasma_rad_mw - physics_variables.p_plasma_sync_mw = ( - physics_variables.pden_plasma_sync_mw * physics_variables.vol_plasma + self.data.physics.p_plasma_sync_mw = ( + self.data.physics.pden_plasma_sync_mw * self.data.physics.vol_plasma ) - physics_variables.p_plasma_inner_rad_mw = ( - physics_variables.pden_plasma_core_rad_mw * physics_variables.vol_plasma + self.data.physics.p_plasma_inner_rad_mw = ( + self.data.physics.pden_plasma_core_rad_mw * self.data.physics.vol_plasma ) - physics_variables.p_plasma_outer_rad_mw = ( - physics_variables.pden_plasma_outer_rad_mw * physics_variables.vol_plasma + self.data.physics.p_plasma_outer_rad_mw = ( + self.data.physics.pden_plasma_outer_rad_mw * self.data.physics.vol_plasma ) - physics_variables.p_plasma_rad_mw = ( - physics_variables.pden_plasma_rad_mw * physics_variables.vol_plasma + self.data.physics.p_plasma_rad_mw = ( + self.data.physics.pden_plasma_rad_mw * self.data.physics.vol_plasma ) # Calculate ohmic power ( - physics_variables.pden_plasma_ohmic_mw, - physics_variables.p_plasma_ohmic_mw, - physics_variables.f_res_plasma_neo, - physics_variables.res_plasma, + self.data.physics.pden_plasma_ohmic_mw, + self.data.physics.p_plasma_ohmic_mw, + self.data.physics.f_res_plasma_neo, + self.data.physics.res_plasma, ) = self.plasma_ohmic_heating( - physics_variables.f_c_plasma_inductive, - physics_variables.kappa95, - physics_variables.plasma_current, - physics_variables.rmajor, - physics_variables.rminor, - physics_variables.temp_plasma_electron_density_weighted_kev, - physics_variables.vol_plasma, - physics_variables.n_charge_plasma_effective_vol_avg, + self.data.physics.f_c_plasma_inductive, + self.data.physics.kappa95, + self.data.physics.plasma_current, + self.data.physics.rmajor, + self.data.physics.rminor, + self.data.physics.temp_plasma_electron_density_weighted_kev, + self.data.physics.vol_plasma, + self.data.physics.n_charge_plasma_effective_vol_avg, + self.data.physics.plasma_res_factor, + self.data.physics.aspect, ) # Calculate L- to H-mode power threshold for different scalings @@ -754,70 +759,70 @@ def run(self): # which is assumed to be absorbed by the first wall pinj = ( self.data.current_drive.p_hcd_injected_total_mw - if physics_variables.i_plasma_ignited == 0 + if self.data.physics.i_plasma_ignited == 0 else 0.0 ) - physics_variables.p_plasma_separatrix_mw = ( + self.data.physics.p_plasma_separatrix_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, + f_p_alpha_plasma_deposited=self.data.physics.f_p_alpha_plasma_deposited, + p_alpha_total_mw=self.data.physics.p_alpha_total_mw, + p_non_alpha_charged_mw=self.data.physics.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, + p_plasma_ohmic_mw=self.data.physics.p_plasma_ohmic_mw, + p_plasma_rad_mw=self.data.physics.p_plasma_rad_mw, ) ) - physics_variables.p_plasma_separatrix_rmajor_mw = ( + self.data.physics.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, + p_plasma_separatrix_mw=self.data.physics.p_plasma_separatrix_mw, + rmajor=self.data.physics.rmajor, ) ) - physics_variables.p_div_bt_q_aspect_rmajor_mw = ( + self.data.physics.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, + p_plasma_separatrix_mw=self.data.physics.p_plasma_separatrix_mw, + b_plasma_toroidal_on_axis=self.data.physics.b_plasma_toroidal_on_axis, + q95=self.data.physics.q95, + aspect=self.data.physics.aspect, + rmajor=self.data.physics.rmajor, ) ) - physics_variables.pflux_plasma_surface_neutron_avg_mw = ( - physics_variables.p_neutron_total_mw / physics_variables.a_plasma_surface + self.data.physics.pflux_plasma_surface_neutron_avg_mw = ( + self.data.physics.p_neutron_total_mw / self.data.physics.a_plasma_surface ) # KLUDGE: Ensure p_plasma_separatrix_mw is continuously positive (physical, rather than # negative potential power), as required by other models (e.g. # Physics.calculate_density_limit()) - physics_variables.p_plasma_separatrix_mw /= 1 - np.exp( - -physics_variables.p_plasma_separatrix_mw + self.data.physics.p_plasma_separatrix_mw /= 1 - np.exp( + -self.data.physics.p_plasma_separatrix_mw ) # if double null configuration share the power - # over the upper and lower divertor, where physics_variables.f_p_div_lower gives + # over the upper and lower divertor, where self.data.physics.f_p_div_lower gives # the factor of power conducted to the lower divertor if self.data.divertor.n_divertors == 2: - physics_variables.p_div_lower_separatrix_mw = ( - physics_variables.f_p_div_lower - * physics_variables.p_plasma_separatrix_mw + self.data.physics.p_div_lower_separatrix_mw = ( + self.data.physics.f_p_div_lower + * self.data.physics.p_plasma_separatrix_mw ) - physics_variables.p_div_upper_separatrix_mw = ( - 1.0e0 - physics_variables.f_p_div_lower - ) * physics_variables.p_plasma_separatrix_mw - physics_variables.p_div_separatrix_max_mw = max( - physics_variables.p_div_lower_separatrix_mw, - physics_variables.p_div_upper_separatrix_mw, + self.data.physics.p_div_upper_separatrix_mw = ( + 1.0e0 - self.data.physics.f_p_div_lower + ) * self.data.physics.p_plasma_separatrix_mw + self.data.physics.p_div_separatrix_max_mw = max( + self.data.physics.p_div_lower_separatrix_mw, + self.data.physics.p_div_upper_separatrix_mw, ) # Resistive diffusion time = current penetration time ~ mu0.a^2/resistivity - physics_variables.t_plasma_res_diffusion = res_diff_time( - physics_variables.rmajor, - physics_variables.res_plasma, - physics_variables.kappa95, + self.data.physics.t_plasma_res_diffusion = res_diff_time( + self.data.physics.rmajor, + self.data.physics.res_plasma, + self.data.physics.kappa95, ) self.density_limit.run() @@ -825,151 +830,153 @@ def run(self): # Calculate transport losses and energy confinement time using the # chosen scaling law ( - physics_variables.pden_electron_transport_loss_mw, - physics_variables.pden_ion_transport_loss_mw, - physics_variables.t_electron_energy_confinement, - physics_variables.t_energy_confinement, - physics_variables.t_ion_energy_confinement, - physics_variables.p_plasma_loss_mw, + self.data.physics.pden_electron_transport_loss_mw, + self.data.physics.pden_ion_transport_loss_mw, + self.data.physics.t_electron_energy_confinement, + self.data.physics.t_energy_confinement, + self.data.physics.t_ion_energy_confinement, + self.data.physics.p_plasma_loss_mw, ) = self.confinement.calculate_confinement_time( - m_fuel_amu=physics_variables.m_fuel_amu, - p_alpha_total_mw=physics_variables.p_alpha_total_mw, - aspect=physics_variables.aspect, - b_plasma_toroidal_on_axis=physics_variables.b_plasma_toroidal_on_axis, - nd_plasma_ions_total_vol_avg=physics_variables.nd_plasma_ions_total_vol_avg, - nd_plasma_electrons_vol_avg=physics_variables.nd_plasma_electrons_vol_avg, - nd_plasma_electron_line=physics_variables.nd_plasma_electron_line, - eps=physics_variables.eps, - hfact=physics_variables.hfact, - i_confinement_time=physics_variables.i_confinement_time, - i_plasma_ignited=physics_variables.i_plasma_ignited, - kappa=physics_variables.kappa, - kappa95=physics_variables.kappa95, - p_non_alpha_charged_mw=physics_variables.p_non_alpha_charged_mw, + m_fuel_amu=self.data.physics.m_fuel_amu, + p_alpha_total_mw=self.data.physics.p_alpha_total_mw, + aspect=self.data.physics.aspect, + b_plasma_toroidal_on_axis=self.data.physics.b_plasma_toroidal_on_axis, + nd_plasma_ions_total_vol_avg=self.data.physics.nd_plasma_ions_total_vol_avg, + nd_plasma_electrons_vol_avg=self.data.physics.nd_plasma_electrons_vol_avg, + nd_plasma_electron_line=self.data.physics.nd_plasma_electron_line, + eps=self.data.physics.eps, + hfact=self.data.physics.hfact, + i_confinement_time=self.data.physics.i_confinement_time, + i_plasma_ignited=self.data.physics.i_plasma_ignited, + kappa=self.data.physics.kappa, + kappa95=self.data.physics.kappa95, + p_non_alpha_charged_mw=self.data.physics.p_non_alpha_charged_mw, p_hcd_injected_total_mw=self.data.current_drive.p_hcd_injected_total_mw, - plasma_current=physics_variables.plasma_current, - pden_plasma_core_rad_mw=physics_variables.pden_plasma_core_rad_mw, - rmajor=physics_variables.rmajor, - rminor=physics_variables.rminor, - temp_plasma_electron_density_weighted_kev=physics_variables.temp_plasma_electron_density_weighted_kev, - temp_plasma_ion_density_weighted_kev=physics_variables.temp_plasma_ion_density_weighted_kev, - q95=physics_variables.q95, - qstar=physics_variables.qstar, - vol_plasma=physics_variables.vol_plasma, - zeff=physics_variables.n_charge_plasma_effective_vol_avg, + plasma_current=self.data.physics.plasma_current, + pden_plasma_core_rad_mw=self.data.physics.pden_plasma_core_rad_mw, + rmajor=self.data.physics.rmajor, + rminor=self.data.physics.rminor, + temp_plasma_electron_density_weighted_kev=self.data.physics.temp_plasma_electron_density_weighted_kev, + temp_plasma_ion_density_weighted_kev=self.data.physics.temp_plasma_ion_density_weighted_kev, + q95=self.data.physics.q95, + qstar=self.data.physics.qstar, + vol_plasma=self.data.physics.vol_plasma, + zeff=self.data.physics.n_charge_plasma_effective_vol_avg, ) # Total transport power from scaling law (MW) - physics_variables.p_electron_transport_loss_mw = ( - physics_variables.pden_electron_transport_loss_mw - * physics_variables.vol_plasma + self.data.physics.p_electron_transport_loss_mw = ( + self.data.physics.pden_electron_transport_loss_mw + * self.data.physics.vol_plasma ) - physics_variables.p_ion_transport_loss_mw = ( - physics_variables.pden_ion_transport_loss_mw * physics_variables.vol_plasma + self.data.physics.p_ion_transport_loss_mw = ( + self.data.physics.pden_ion_transport_loss_mw * self.data.physics.vol_plasma ) # Calculate Volt-second requirements ( - physics_variables.vs_plasma_internal, - physics_variables.ind_plasma, - physics_variables.vs_plasma_burn_required, - physics_variables.vs_plasma_ramp_required, - physics_variables.vs_plasma_ind_ramp, - physics_variables.vs_plasma_res_ramp, - physics_variables.vs_plasma_total_required, - physics_variables.v_plasma_loop_burn, + self.data.physics.vs_plasma_internal, + self.data.physics.ind_plasma, + self.data.physics.vs_plasma_burn_required, + self.data.physics.vs_plasma_ramp_required, + self.data.physics.vs_plasma_ind_ramp, + self.data.physics.vs_plasma_res_ramp, + self.data.physics.vs_plasma_total_required, + self.data.physics.v_plasma_loop_burn, ) = self.inductance.calculate_volt_second_requirements( - physics_variables.csawth, - physics_variables.eps, - physics_variables.f_c_plasma_inductive, - physics_variables.ejima_coeff, - physics_variables.kappa, - physics_variables.rmajor, - physics_variables.res_plasma, - physics_variables.plasma_current, + self.data.physics.csawth, + self.data.physics.eps, + self.data.physics.f_c_plasma_inductive, + self.data.physics.ejima_coeff, + self.data.physics.kappa, + self.data.physics.rmajor, + self.data.physics.res_plasma, + self.data.physics.plasma_current, self.data.times.t_plant_pulse_fusion_ramp, self.data.times.t_plant_pulse_burn, - physics_variables.ind_plasma_internal_norm, + self.data.physics.ind_plasma_internal_norm, ) - physics_variables.e_plasma_magnetic_stored = ( - 0.5e0 * physics_variables.ind_plasma * physics_variables.plasma_current**2 + self.data.physics.e_plasma_magnetic_stored = ( + 0.5e0 * self.data.physics.ind_plasma * self.data.physics.plasma_current**2 ) # Calculate auxiliary physics related information sbar = 1.0e0 ( - physics_variables.burnup, - physics_variables.figmer, - physics_variables.fusrat, - physics_variables.molflow_plasma_fuelling_required, - physics_variables.rndfuel, - physics_variables.t_alpha_confinement, - physics_variables.f_alpha_energy_confinement, + self.data.physics.burnup, + self.data.physics.figmer, + self.data.physics.fusrat, + self.data.physics.molflow_plasma_fuelling_required, + self.data.physics.rndfuel, + self.data.physics.t_alpha_confinement, + self.data.physics.f_alpha_energy_confinement, ) = self.phyaux( - physics_variables.aspect, - physics_variables.nd_plasma_fuel_ions_vol_avg, - physics_variables.fusden_total, - physics_variables.fusden_alpha_total, - physics_variables.plasma_current, + self.data.physics.aspect, + self.data.physics.nd_plasma_fuel_ions_vol_avg, + self.data.physics.fusden_total, + self.data.physics.fusden_alpha_total, + self.data.physics.plasma_current, sbar, - physics_variables.nd_plasma_alphas_vol_avg, - physics_variables.t_energy_confinement, - physics_variables.vol_plasma, + self.data.physics.nd_plasma_alphas_vol_avg, + self.data.physics.t_energy_confinement, + self.data.physics.vol_plasma, + self.data.physics.burnup_in, + self.data.physics.tauratio, ) - physics_variables.ntau, physics_variables.nTtau = ( + self.data.physics.ntau, self.data.physics.nTtau = ( self.confinement.calculate_double_and_triple_product( - nd_plasma_electrons_vol_avg=physics_variables.nd_plasma_electrons_vol_avg, - t_energy_confinement=physics_variables.t_energy_confinement, - temp_plasma_electrons_vol_avg_kev=physics_variables.temp_plasma_electron_vol_avg_kev, + nd_plasma_electrons_vol_avg=self.data.physics.nd_plasma_electrons_vol_avg, + t_energy_confinement=self.data.physics.t_energy_confinement, + temp_plasma_electrons_vol_avg_kev=self.data.physics.temp_plasma_electron_vol_avg_kev, ) ) # Total transport power from scaling law (MW) - physics_variables.pscalingmw = ( - physics_variables.p_electron_transport_loss_mw - + physics_variables.p_ion_transport_loss_mw + self.data.physics.pscalingmw = ( + self.data.physics.p_electron_transport_loss_mw + + self.data.physics.p_ion_transport_loss_mw ) # ============================================================ # Calculate the target imbalances # find the total power into the targets - physics_variables.ptarmw = physics_variables.p_plasma_separatrix_mw * ( - 1.0e0 - physics_variables.rad_fraction_sol + self.data.physics.ptarmw = self.data.physics.p_plasma_separatrix_mw * ( + 1.0e0 - self.data.physics.rad_fraction_sol ) - # use physics_variables.f_p_div_lower to find deltarsep + # use self.data.physics.f_p_div_lower to find deltarsep # Parameters taken from double null machine # D. Brunner et al - physics_variables.lambdaio = 1.57e-3 + self.data.physics.lambdaio = 1.57e-3 # Issue #1559 Infinities in physics_module.drsep when running single null in a # double null machine # C W Ashe - if physics_variables.f_p_div_lower < 4.5e-5: - physics_variables.drsep = 1.5e-2 - elif physics_variables.f_p_div_lower > (1.0e0 - 4.5e-5): - physics_variables.drsep = -1.5e-2 + if self.data.physics.f_p_div_lower < 4.5e-5: + self.data.physics.drsep = 1.5e-2 + elif self.data.physics.f_p_div_lower > (1.0e0 - 4.5e-5): + self.data.physics.drsep = -1.5e-2 else: - physics_variables.drsep = ( + self.data.physics.drsep = ( -2.0e0 * 1.5e-3 - * math.atanh(2.0e0 * (physics_variables.f_p_div_lower - 0.5e0)) + * math.atanh(2.0e0 * (self.data.physics.f_p_div_lower - 0.5e0)) ) # Model Taken from D3-D paper for conventional divertor # Journal of Nuclear Materials # Volumes 290-293, March 2001, Pages 935-939 # Find the innner and outer lower target imbalance - physics_variables.fio = 0.16e0 + (0.16e0 - 0.41e0) * ( + self.data.physics.fio = 0.16e0 + (0.16e0 - 0.41e0) * ( 1.0e0 - ( 2.0e0 / ( 1.0e0 + np.exp( - -((physics_variables.drsep / physics_variables.lambdaio) ** 2) + -((self.data.physics.drsep / self.data.physics.lambdaio) ** 2) ) ) ) @@ -978,74 +985,74 @@ def run(self): # Double Null configuration # Find all the power fractions accross the targets # Taken from D3-D conventional divertor design - physics_variables.fli = ( - physics_variables.f_p_div_lower * physics_variables.fio + self.data.physics.fli = ( + self.data.physics.f_p_div_lower * self.data.physics.fio ) - physics_variables.flo = physics_variables.f_p_div_lower * ( - 1.0e0 - physics_variables.fio + self.data.physics.flo = self.data.physics.f_p_div_lower * ( + 1.0e0 - self.data.physics.fio ) - physics_variables.fui = ( - 1.0e0 - physics_variables.f_p_div_lower - ) * physics_variables.fio - physics_variables.fuo = (1.0e0 - physics_variables.f_p_div_lower) * ( - 1.0e0 - physics_variables.fio + self.data.physics.fui = ( + 1.0e0 - self.data.physics.f_p_div_lower + ) * self.data.physics.fio + self.data.physics.fuo = (1.0e0 - self.data.physics.f_p_div_lower) * ( + 1.0e0 - self.data.physics.fio ) # power into each target - physics_variables.plimw = physics_variables.fli * physics_variables.ptarmw - physics_variables.plomw = physics_variables.flo * physics_variables.ptarmw - physics_variables.puimw = physics_variables.fui * physics_variables.ptarmw - physics_variables.puomw = physics_variables.fuo * physics_variables.ptarmw + self.data.physics.plimw = self.data.physics.fli * self.data.physics.ptarmw + self.data.physics.plomw = self.data.physics.flo * self.data.physics.ptarmw + self.data.physics.puimw = self.data.physics.fui * self.data.physics.ptarmw + self.data.physics.puomw = self.data.physics.fuo * self.data.physics.ptarmw else: # Single null configuration - physics_variables.fli = physics_variables.fio - physics_variables.flo = 1.0e0 - physics_variables.fio + self.data.physics.fli = self.data.physics.fio + self.data.physics.flo = 1.0e0 - self.data.physics.fio # power into each target - physics_variables.plimw = physics_variables.fli * physics_variables.ptarmw - physics_variables.plomw = physics_variables.flo * physics_variables.ptarmw + self.data.physics.plimw = self.data.physics.fli * self.data.physics.ptarmw + self.data.physics.plomw = self.data.physics.flo * self.data.physics.ptarmw # Calculate some derived quantities that may not have been defined earlier - physics_variables.p_plasma_heating_total_mw = 1e6 * ( - physics_variables.f_p_alpha_plasma_deposited - * physics_variables.p_alpha_total_mw - + physics_variables.p_non_alpha_charged_mw - + physics_variables.p_plasma_ohmic_mw + self.data.physics.p_plasma_heating_total_mw = 1e6 * ( + self.data.physics.f_p_alpha_plasma_deposited + * self.data.physics.p_alpha_total_mw + + self.data.physics.p_non_alpha_charged_mw + + self.data.physics.p_plasma_ohmic_mw + self.data.current_drive.p_hcd_injected_total_mw ) - physics_variables.f_p_plasma_separatrix_rad = ( + self.data.physics.f_p_plasma_separatrix_rad = ( 1.0e6 - * physics_variables.p_plasma_rad_mw - / physics_variables.p_plasma_heating_total_mw + * self.data.physics.p_plasma_rad_mw + / self.data.physics.p_plasma_heating_total_mw ) - physics_variables.rad_fraction_total = ( - physics_variables.f_p_plasma_separatrix_rad - + (1.0e0 - physics_variables.f_p_plasma_separatrix_rad) - * physics_variables.rad_fraction_sol + self.data.physics.rad_fraction_total = ( + self.data.physics.f_p_plasma_separatrix_rad + + (1.0e0 - self.data.physics.f_p_plasma_separatrix_rad) + * self.data.physics.rad_fraction_sol ) - physics_variables.pradsolmw = ( - physics_variables.rad_fraction_sol * physics_variables.p_plasma_separatrix_mw + self.data.physics.pradsolmw = ( + self.data.physics.rad_fraction_sol * self.data.physics.p_plasma_separatrix_mw ) if 78 in numerics.icc: po.write( self.outfile, ( - f"reinke t and fz, physics = {physics_variables.temp_plasma_separatrix_kev} , {self.data.reinke.fzmin}" + f"reinke t and fz, physics = {self.data.physics.temp_plasma_separatrix_kev} , {self.data.reinke.fzmin}" ), ) fgw = ( - physics_variables.nd_plasma_electron_max_array[6] - / physics_variables.nd_plasma_electrons_vol_avg + self.data.physics.nd_plasma_electron_max_array[6] + / self.data.physics.nd_plasma_electrons_vol_avg ) # calculate separatrix temperature, if Reinke criterion is used - physics_variables.temp_plasma_separatrix_kev = reinke_tsep( - physics_variables.b_plasma_toroidal_on_axis, - physics_variables.p_plasma_separatrix_mw - / physics_variables.p_l_h_threshold_mw, - physics_variables.q95, - physics_variables.rmajor, - physics_variables.eps, + self.data.physics.temp_plasma_separatrix_kev = reinke_tsep( + self.data.physics.b_plasma_toroidal_on_axis, + self.data.physics.p_plasma_separatrix_mw + / self.data.physics.p_l_h_threshold_mw, + self.data.physics.q95, + self.data.physics.rmajor, + self.data.physics.eps, fgw, - physics_variables.kappa, + self.data.physics.kappa, self.data.reinke.lhat, ) @@ -1119,9 +1126,9 @@ def plasma_composition(self): charge. """ # Alpha ash portion - physics_variables.nd_plasma_alphas_vol_avg = ( - physics_variables.nd_plasma_electrons_vol_avg - * physics_variables.f_nd_alpha_electron + self.data.physics.nd_plasma_alphas_vol_avg = ( + self.data.physics.nd_plasma_electrons_vol_avg + * self.data.physics.f_nd_alpha_electron ) # ====================================================================== @@ -1132,33 +1139,33 @@ def plasma_composition(self): # Issue #557 Allow f_nd_protium_electrons impurity to be specified: # 'f_nd_protium_electrons' # This will override the calculated value which is a minimum. - if physics_variables.fusden_alpha_total < 1.0e-6: # not calculated yet... - physics_variables.nd_plasma_protons_vol_avg = max( - physics_variables.f_nd_protium_electrons - * physics_variables.nd_plasma_electrons_vol_avg, - physics_variables.nd_plasma_alphas_vol_avg - * (physics_variables.f_plasma_fuel_helium3 + 1.0e-3), + if self.data.physics.fusden_alpha_total < 1.0e-6: # not calculated yet... + self.data.physics.nd_plasma_protons_vol_avg = max( + self.data.physics.f_nd_protium_electrons + * self.data.physics.nd_plasma_electrons_vol_avg, + self.data.physics.nd_plasma_alphas_vol_avg + * (self.data.physics.f_plasma_fuel_helium3 + 1.0e-3), ) # rough estimate else: - physics_variables.nd_plasma_protons_vol_avg = max( - physics_variables.f_nd_protium_electrons - * physics_variables.nd_plasma_electrons_vol_avg, - physics_variables.nd_plasma_alphas_vol_avg - * physics_variables.proton_rate_density - / physics_variables.fusden_alpha_total, + self.data.physics.nd_plasma_protons_vol_avg = max( + self.data.physics.f_nd_protium_electrons + * self.data.physics.nd_plasma_electrons_vol_avg, + self.data.physics.nd_plasma_alphas_vol_avg + * self.data.physics.proton_rate_density + / self.data.physics.fusden_alpha_total, ) # ====================================================================== # Beam hot ion component # If ignited, prevent beam fusion effects - if physics_variables.i_plasma_ignited == 0: - physics_variables.nd_beam_ions = ( - physics_variables.nd_plasma_electrons_vol_avg - * physics_variables.f_nd_beam_electron + if self.data.physics.i_plasma_ignited == 0: + self.data.physics.nd_beam_ions = ( + self.data.physics.nd_plasma_electrons_vol_avg + * self.data.physics.f_nd_beam_electron ) else: - physics_variables.nd_beam_ions = 0.0 + self.data.physics.nd_beam_ions = 0.0 # ====================================================================== @@ -1168,11 +1175,11 @@ def plasma_composition(self): if self.data.impurity_radiation.impurity_arr_z[imp] > 2: znimp += impurity_radiation.zav_of_te( imp, - np.array([physics_variables.temp_plasma_electron_vol_avg_kev]), + np.array([self.data.physics.temp_plasma_electron_vol_avg_kev]), self.data, ).squeeze() * ( self.data.impurity_radiation.f_nd_impurity_electron_array[imp] - * physics_variables.nd_plasma_electrons_vol_avg + * self.data.physics.nd_plasma_electrons_vol_avg ) # ====================================================================== @@ -1180,10 +1187,10 @@ def plasma_composition(self): # Fuel portion - conserve charge neutrality # znfuel is the sum of Zi.ni for the three fuel ions znfuel = ( - physics_variables.nd_plasma_electrons_vol_avg - - 2.0 * physics_variables.nd_plasma_alphas_vol_avg - - physics_variables.nd_plasma_protons_vol_avg - - physics_variables.nd_beam_ions + self.data.physics.nd_plasma_electrons_vol_avg + - 2.0 * self.data.physics.nd_plasma_alphas_vol_avg + - self.data.physics.nd_plasma_protons_vol_avg + - self.data.physics.nd_beam_ions - znimp ) @@ -1194,8 +1201,8 @@ def plasma_composition(self): # = nD + nT + 2*nHe3 # So nd_plasma_fuel_ions_vol_avg = znfuel - nHe3 = znfuel # - f_plasma_fuel_helium3*nd_plasma_fuel_ions_vol_avg - physics_variables.nd_plasma_fuel_ions_vol_avg = znfuel / ( - 1.0 + physics_variables.f_plasma_fuel_helium3 + self.data.physics.nd_plasma_fuel_ions_vol_avg = znfuel / ( + 1.0 + self.data.physics.f_plasma_fuel_helium3 ) # ====================================================================== @@ -1205,61 +1212,61 @@ def plasma_composition(self): self.data.impurity_radiation.f_nd_impurity_electron_array[ impurity_radiation.element2index("H_", self.data) ] = ( - physics_variables.nd_plasma_protons_vol_avg + self.data.physics.nd_plasma_protons_vol_avg + ( - physics_variables.f_plasma_fuel_deuterium - + physics_variables.f_plasma_fuel_tritium + self.data.physics.f_plasma_fuel_deuterium + + self.data.physics.f_plasma_fuel_tritium ) - * physics_variables.nd_plasma_fuel_ions_vol_avg - + physics_variables.nd_beam_ions - ) / physics_variables.nd_plasma_electrons_vol_avg + * self.data.physics.nd_plasma_fuel_ions_vol_avg + + self.data.physics.nd_beam_ions + ) / self.data.physics.nd_plasma_electrons_vol_avg self.data.impurity_radiation.f_nd_impurity_electron_array[ impurity_radiation.element2index("He", self.data) ] = ( - physics_variables.f_plasma_fuel_helium3 - * physics_variables.nd_plasma_fuel_ions_vol_avg - / physics_variables.nd_plasma_electrons_vol_avg - + physics_variables.f_nd_alpha_electron + self.data.physics.f_plasma_fuel_helium3 + * self.data.physics.nd_plasma_fuel_ions_vol_avg + / self.data.physics.nd_plasma_electrons_vol_avg + + self.data.physics.f_nd_alpha_electron ) # ====================================================================== # Total impurity density - physics_variables.nd_plasma_impurities_vol_avg = 0.0 + self.data.physics.nd_plasma_impurities_vol_avg = 0.0 for imp in range(N_IMPURITIES): if self.data.impurity_radiation.impurity_arr_z[imp] > 2: - physics_variables.nd_plasma_impurities_vol_avg += ( + self.data.physics.nd_plasma_impurities_vol_avg += ( self.data.impurity_radiation.f_nd_impurity_electron_array[imp] - * physics_variables.nd_plasma_electrons_vol_avg + * self.data.physics.nd_plasma_electrons_vol_avg ) # ====================================================================== # Total ion density - physics_variables.nd_plasma_ions_total_vol_avg = ( - physics_variables.nd_plasma_fuel_ions_vol_avg - + physics_variables.nd_plasma_alphas_vol_avg - + physics_variables.nd_plasma_protons_vol_avg - + physics_variables.nd_beam_ions - + physics_variables.nd_plasma_impurities_vol_avg + self.data.physics.nd_plasma_ions_total_vol_avg = ( + self.data.physics.nd_plasma_fuel_ions_vol_avg + + self.data.physics.nd_plasma_alphas_vol_avg + + self.data.physics.nd_plasma_protons_vol_avg + + self.data.physics.nd_beam_ions + + self.data.physics.nd_plasma_impurities_vol_avg ) # ====================================================================== # Set some relative impurity density variables # for the benefit of other routines - physics_variables.f_nd_plasma_carbon_electron = ( + self.data.physics.f_nd_plasma_carbon_electron = ( self.data.impurity_radiation.f_nd_impurity_electron_array[ impurity_radiation.element2index("C_", self.data) ] ) - physics_variables.f_nd_plasma_oxygen_electron = ( + self.data.physics.f_nd_plasma_oxygen_electron = ( self.data.impurity_radiation.f_nd_impurity_electron_array[ impurity_radiation.element2index("O_", self.data) ] ) - physics_variables.f_nd_plasma_iron_argon_electron = ( + self.data.physics.f_nd_plasma_iron_argon_electron = ( self.data.impurity_radiation.f_nd_impurity_electron_array[ impurity_radiation.element2index("Fe", self.data) ] @@ -1273,13 +1280,13 @@ def plasma_composition(self): # Effective charge # Calculation should be sum(ni.Zi^2) / sum(ni.Zi), # but ne = sum(ni.Zi) through quasineutrality - physics_variables.n_charge_plasma_effective_vol_avg = 0.0 + self.data.physics.n_charge_plasma_effective_vol_avg = 0.0 for imp in range(N_IMPURITIES): - physics_variables.n_charge_plasma_effective_vol_avg += ( + self.data.physics.n_charge_plasma_effective_vol_avg += ( self.data.impurity_radiation.f_nd_impurity_electron_array[imp] * impurity_radiation.zav_of_te( imp, - np.array([physics_variables.temp_plasma_electron_vol_avg_kev]), + np.array([self.data.physics.temp_plasma_electron_vol_avg_kev]), self.data, ).squeeze() ** 2 @@ -1295,103 +1302,103 @@ def plasma_composition(self): # f_temp_plasma_electron_density_vol_avg now calculated in plasma_profiles, # after the very first call of plasma_composition; use old parabolic profile # estimate in this case. - if physics_variables.first_call == 1: + if self.data.physics.first_call == 1: pc = ( - (1.0 + physics_variables.alphan) - * (1.0 + physics_variables.alphat) - / (1.0 + physics_variables.alphan + physics_variables.alphat) + (1.0 + self.data.physics.alphan) + * (1.0 + self.data.physics.alphat) + / (1.0 + self.data.physics.alphan + self.data.physics.alphat) ) - physics_variables.first_call = 0 + self.data.physics.first_call = 0 else: - pc = physics_variables.f_temp_plasma_electron_density_vol_avg + pc = self.data.physics.f_temp_plasma_electron_density_vol_avg - physics_variables.f_alpha_electron = 0.88155 * np.exp( - -physics_variables.temp_plasma_electron_vol_avg_kev * pc / 67.4036 + self.data.physics.f_alpha_electron = 0.88155 * np.exp( + -self.data.physics.temp_plasma_electron_vol_avg_kev * pc / 67.4036 ) - physics_variables.f_alpha_ion = 1.0 - physics_variables.f_alpha_electron + self.data.physics.f_alpha_ion = 1.0 - self.data.physics.f_alpha_electron # ====================================================================== # Average atomic masses of injected fuel species - physics_variables.m_fuel_amu = ( - (constants.M_DEUTERON_AMU * physics_variables.f_plasma_fuel_deuterium) - + (constants.M_TRITON_AMU * physics_variables.f_plasma_fuel_tritium) - + (constants.M_HELION_AMU * physics_variables.f_plasma_fuel_helium3) + self.data.physics.m_fuel_amu = ( + (constants.M_DEUTERON_AMU * self.data.physics.f_plasma_fuel_deuterium) + + (constants.M_TRITON_AMU * self.data.physics.f_plasma_fuel_tritium) + + (constants.M_HELION_AMU * self.data.physics.f_plasma_fuel_helium3) ) # ====================================================================== # Average atomic masses of injected fuel species in the neutral beams # Only deuterium and tritium in the beams - physics_variables.m_beam_amu = ( + self.data.physics.m_beam_amu = ( constants.M_DEUTERON_AMU * (1.0 - self.data.current_drive.f_beam_tritium) ) + (constants.M_TRITON_AMU * self.data.current_drive.f_beam_tritium) # ====================================================================== # Average mass of all ions - physics_variables.m_ions_total_amu = ( + self.data.physics.m_ions_total_amu = ( ( - physics_variables.m_fuel_amu - * physics_variables.nd_plasma_fuel_ions_vol_avg + self.data.physics.m_fuel_amu + * self.data.physics.nd_plasma_fuel_ions_vol_avg ) - + (constants.M_ALPHA_AMU * physics_variables.nd_plasma_alphas_vol_avg) - + (physics_variables.nd_plasma_protons_vol_avg * constants.M_PROTON_AMU) - + (physics_variables.m_beam_amu * physics_variables.nd_beam_ions) + + (constants.M_ALPHA_AMU * self.data.physics.nd_plasma_alphas_vol_avg) + + (self.data.physics.nd_plasma_protons_vol_avg * constants.M_PROTON_AMU) + + (self.data.physics.m_beam_amu * self.data.physics.nd_beam_ions) ) for imp in range(N_IMPURITIES): if self.data.impurity_radiation.impurity_arr_z[imp] > 2: - physics_variables.m_ions_total_amu += ( - physics_variables.nd_plasma_electrons_vol_avg + self.data.physics.m_ions_total_amu += ( + self.data.physics.nd_plasma_electrons_vol_avg * self.data.impurity_radiation.f_nd_impurity_electron_array[imp] * self.data.impurity_radiation.m_impurity_amu_array[imp] ) - physics_variables.m_ions_total_amu /= ( - physics_variables.nd_plasma_ions_total_vol_avg + self.data.physics.m_ions_total_amu /= ( + self.data.physics.nd_plasma_ions_total_vol_avg ) # ====================================================================== # Mass weighted plasma effective charge # Sum of (Zi^2*n_i) / m_i - physics_variables.n_charge_plasma_effective_mass_weighted_vol_avg = ( + self.data.physics.n_charge_plasma_effective_mass_weighted_vol_avg = ( ( - physics_variables.f_plasma_fuel_deuterium - * physics_variables.nd_plasma_fuel_ions_vol_avg + self.data.physics.f_plasma_fuel_deuterium + * self.data.physics.nd_plasma_fuel_ions_vol_avg / constants.M_DEUTERON_AMU ) + ( - physics_variables.f_plasma_fuel_tritium - * physics_variables.nd_plasma_fuel_ions_vol_avg + self.data.physics.f_plasma_fuel_tritium + * self.data.physics.nd_plasma_fuel_ions_vol_avg / constants.M_TRITON_AMU ) + ( 4.0 - * physics_variables.f_plasma_fuel_helium3 - * physics_variables.nd_plasma_fuel_ions_vol_avg + * self.data.physics.f_plasma_fuel_helium3 + * self.data.physics.nd_plasma_fuel_ions_vol_avg / constants.M_HELION_AMU ) - + (4.0 * physics_variables.nd_plasma_alphas_vol_avg / constants.M_ALPHA_AMU) - + (physics_variables.nd_plasma_protons_vol_avg / constants.M_PROTON_AMU) + + (4.0 * self.data.physics.nd_plasma_alphas_vol_avg / constants.M_ALPHA_AMU) + + (self.data.physics.nd_plasma_protons_vol_avg / constants.M_PROTON_AMU) + ( (1.0 - self.data.current_drive.f_beam_tritium) - * physics_variables.nd_beam_ions + * self.data.physics.nd_beam_ions / constants.M_DEUTERON_AMU ) + ( self.data.current_drive.f_beam_tritium - * physics_variables.nd_beam_ions + * self.data.physics.nd_beam_ions / constants.M_TRITON_AMU ) - ) / physics_variables.nd_plasma_electrons_vol_avg + ) / self.data.physics.nd_plasma_electrons_vol_avg for imp in range(N_IMPURITIES): if self.data.impurity_radiation.impurity_arr_z[imp] > 2: - physics_variables.n_charge_plasma_effective_mass_weighted_vol_avg += ( + self.data.physics.n_charge_plasma_effective_mass_weighted_vol_avg += ( self.data.impurity_radiation.f_nd_impurity_electron_array[imp] * impurity_radiation.zav_of_te( imp, - np.array([physics_variables.temp_plasma_electron_vol_avg_kev]), + np.array([self.data.physics.temp_plasma_electron_vol_avg_kev]), self.data, ).squeeze() ** 2 @@ -1412,6 +1419,8 @@ def phyaux( nd_plasma_alphas_vol_avg: float, t_energy_confinement: float, vol_plasma: float, + burnup_in: float, + tauratio: float, ) -> tuple[float, float, float, float, float, float, float, float]: """Auxiliary physics quantities @@ -1435,6 +1444,10 @@ def phyaux( Global energy confinement time (s). vol_plasma : float Plasma volume (m3). + burnup_in: float + fractional plasma burnup user input + tauratio: float + ratio of He and pellet particle confinement times Returns ------- @@ -1478,14 +1491,14 @@ def phyaux( # initial fuel ion-pairs/m3 = burnt fuel ion-pairs/m3 + unburnt fuel-ion # pairs/m3 # Remember that unburnt fuel-ion pairs/m3 = 0.5 * unburnt fuel-ions/m3 - if physics_variables.burnup_in <= 1.0e-9: + if burnup_in <= 1.0e-9: burnup = ( nd_plasma_alphas_vol_avg / (nd_plasma_alphas_vol_avg + 0.5 * nd_plasma_fuel_ions_vol_avg) - / physics_variables.tauratio + / tauratio ) else: - burnup = physics_variables.burnup_in + burnup = burnup_in # Fuel burnup rate (reactions/second) (previously Amps) rndfuel = fusrat @@ -1515,6 +1528,8 @@ def plasma_ohmic_heating( temp_plasma_electron_density_weighted_kev: float, vol_plasma: float, zeff: float, + plasma_res_factor: float, + aspect: float, ) -> tuple[float, float, float, float]: """Calculate the ohmic heating power and related parameters. @@ -1536,6 +1551,10 @@ def plasma_ohmic_heating( Plasma volume (m^3). zeff : float Plasma effective charge. + plasma_res_factor: float + plasma resistivity pre-factor + aspect: float + aspect ratio Returns ------- @@ -1559,7 +1578,7 @@ def plasma_ohmic_heating( # Plasma resistance, from loop voltage calculation in ITER Physics Design # Guidelines: 1989 res_plasma = ( - physics_variables.plasma_res_factor + plasma_res_factor * 2.15e-9 * zeff * rmajor @@ -1580,8 +1599,7 @@ def plasma_ohmic_heating( # (possible if aspect ratio is too high) if res_plasma <= 0.0: logger.error( - f"Negative plasma resistance res_plasma. " - f"{res_plasma=} {physics_variables.aspect=}" + f"Negative plasma resistance res_plasma. {res_plasma=} {aspect=}" ) # Ohmic heating power per unit volume @@ -1662,7 +1680,7 @@ def calculate_effective_charge_ionisation_profiles(self): ).squeeze() ** 2 ) - physics_variables.n_charge_plasma_effective_profile = zeff_profile + self.data.physics.n_charge_plasma_effective_profile = zeff_profile # Assign the charge profiles of each species n_impurities = N_IMPURITIES @@ -1684,45 +1702,45 @@ def outplas(self): to a file, in a tidy format. """ # Dimensionless plasma parameters. See reference below. - physics_variables.nu_star = ( + self.data.physics.nu_star = ( 1 / constants.RMU0 - * (15.0e0 * constants.ELECTRON_CHARGE**4 * physics_variables.dlamie) + * (15.0e0 * constants.ELECTRON_CHARGE**4 * self.data.physics.dlamie) / (4.0e0 * np.pi**1.5e0 * constants.EPSILON0**2) - * physics_variables.vol_plasma**2 - * physics_variables.rmajor**2 - * physics_variables.b_plasma_toroidal_on_axis - * np.sqrt(physics_variables.eps) - * physics_variables.nd_plasma_electron_line**3 - * physics_variables.kappa - / (physics_variables.e_plasma_beta**2 * physics_variables.plasma_current) + * self.data.physics.vol_plasma**2 + * self.data.physics.rmajor**2 + * self.data.physics.b_plasma_toroidal_on_axis + * np.sqrt(self.data.physics.eps) + * self.data.physics.nd_plasma_electron_line**3 + * self.data.physics.kappa + / (self.data.physics.e_plasma_beta**2 * self.data.physics.plasma_current) ) - physics_variables.rho_star = np.sqrt( + self.data.physics.rho_star = np.sqrt( 2.0e0 * constants.PROTON_MASS - * physics_variables.m_ions_total_amu - * physics_variables.e_plasma_beta + * self.data.physics.m_ions_total_amu + * self.data.physics.e_plasma_beta / ( 3.0e0 - * physics_variables.vol_plasma - * physics_variables.nd_plasma_electron_line + * self.data.physics.vol_plasma + * self.data.physics.nd_plasma_electron_line ) ) / ( constants.ELECTRON_CHARGE - * physics_variables.b_plasma_toroidal_on_axis - * physics_variables.eps - * physics_variables.rmajor + * self.data.physics.b_plasma_toroidal_on_axis + * self.data.physics.eps + * self.data.physics.rmajor ) - physics_variables.beta_mcdonald = ( + self.data.physics.beta_mcdonald = ( 4.0e0 / 3.0e0 * constants.RMU0 - * physics_variables.e_plasma_beta + * self.data.physics.e_plasma_beta / ( - physics_variables.vol_plasma - * physics_variables.b_plasma_toroidal_on_axis**2 + self.data.physics.vol_plasma + * self.data.physics.b_plasma_toroidal_on_axis**2 ) ) @@ -1748,19 +1766,19 @@ def outplas(self): self.outfile, "Deuterium fuel fraction", "(f_plasma_fuel_deuterium)", - physics_variables.f_plasma_fuel_deuterium, + self.data.physics.f_plasma_fuel_deuterium, ) po.ovarrf( self.outfile, "Tritium fuel fraction", "(f_plasma_fuel_tritium)", - physics_variables.f_plasma_fuel_tritium, + self.data.physics.f_plasma_fuel_tritium, ) po.ovarrf( self.outfile, "3-Helium fuel fraction", "(f_plasma_fuel_helium3)", - physics_variables.f_plasma_fuel_helium3, + self.data.physics.f_plasma_fuel_helium3, ) po.oblnkl(self.outfile) po.ocmmnt(self.outfile, "----------------------------") @@ -1769,21 +1787,21 @@ def outplas(self): self.outfile, "Fusion rate: total (reactions/sec)", "(fusrat_total)", - physics_variables.fusrat_total, + self.data.physics.fusrat_total, "OP ", ) po.ovarre( self.outfile, "Fusion rate density: total (reactions/m³/sec)", "(fusden_total)", - physics_variables.fusden_total, + self.data.physics.fusden_total, "OP ", ) po.ovarre( self.outfile, "Fusion rate density: plasma (reactions/m³/sec)", "(fusden_plasma)", - physics_variables.fusden_plasma, + self.data.physics.fusden_plasma, "OP ", ) @@ -1800,78 +1818,78 @@ def outplas(self): self.outfile, "Total fusion power (MW)", "(p_fusion_total_mw)", - physics_variables.p_fusion_total_mw, + self.data.physics.p_fusion_total_mw, "OP ", ) po.ovarre( self.outfile, "D-T fusion power: total (MW)", "(p_dt_total_mw)", - physics_variables.p_dt_total_mw, + self.data.physics.p_dt_total_mw, "OP ", ) - for i in range(len(physics_variables.fusrat_plasma_dt_profile)): + for i in range(len(self.data.physics.fusrat_plasma_dt_profile)): po.ovarre( self.mfile, f"DT fusion rate at point {i}", f"fusrat_plasma_dt_profile{i}", - physics_variables.fusrat_plasma_dt_profile[i], + self.data.physics.fusrat_plasma_dt_profile[i], ) - for i in range(len(physics_variables.fusrat_plasma_dd_triton_profile)): + for i in range(len(self.data.physics.fusrat_plasma_dd_triton_profile)): po.ovarre( self.mfile, f"D-D -> T fusion rate at point {i}", f"fusrat_plasma_dd_triton_profile{i}", - physics_variables.fusrat_plasma_dd_triton_profile[i], + self.data.physics.fusrat_plasma_dd_triton_profile[i], ) - for i in range(len(physics_variables.fusrat_plasma_dd_helion_profile)): + for i in range(len(self.data.physics.fusrat_plasma_dd_helion_profile)): po.ovarre( self.mfile, f"D-D -> 3He fusion rate at point {i}", f"fusrat_plasma_dd_helion_profile{i}", - physics_variables.fusrat_plasma_dd_helion_profile[i], + self.data.physics.fusrat_plasma_dd_helion_profile[i], ) - for i in range(len(physics_variables.fusrat_plasma_dhe3_profile)): + for i in range(len(self.data.physics.fusrat_plasma_dhe3_profile)): po.ovarre( self.mfile, f"D-3He fusion rate at point {i}", f"fusrat_plasma_dhe3_profile{i}", - physics_variables.fusrat_plasma_dhe3_profile[i], + self.data.physics.fusrat_plasma_dhe3_profile[i], ) po.ovarre( self.outfile, "D-T fusion power: plasma (MW)", "(p_plasma_dt_mw)", - physics_variables.p_plasma_dt_mw, + self.data.physics.p_plasma_dt_mw, "OP ", ) po.ovarre( self.outfile, "D-T fusion power: beam (MW)", "(p_beam_dt_mw)", - physics_variables.p_beam_dt_mw, + self.data.physics.p_beam_dt_mw, "OP ", ) po.ovarre( self.outfile, "D-D fusion power (MW)", "(p_dd_total_mw)", - physics_variables.p_dd_total_mw, + self.data.physics.p_dd_total_mw, "OP ", ) po.ovarre( self.outfile, "D-D branching ratio for tritium producing reactions", "(f_dd_branching_trit)", - physics_variables.f_dd_branching_trit, + self.data.physics.f_dd_branching_trit, "OP ", ) po.ovarre( self.outfile, "D-He3 fusion power (MW)", "(p_dhe3_total_mw)", - physics_variables.p_dhe3_total_mw, + self.data.physics.p_dhe3_total_mw, "OP ", ) @@ -1882,63 +1900,63 @@ def outplas(self): self.outfile, "Alpha rate density: total (particles/m³/sec)", "(fusden_alpha_total)", - physics_variables.fusden_alpha_total, + self.data.physics.fusden_alpha_total, "OP ", ) po.ovarre( self.outfile, "Alpha rate density: plasma (particles/m³/sec)", "(fusden_plasma_alpha)", - physics_variables.fusden_plasma_alpha, + self.data.physics.fusden_plasma_alpha, "OP ", ) po.ovarre( self.outfile, "Alpha power: total (MW)", "(p_alpha_total_mw)", - physics_variables.p_alpha_total_mw, + self.data.physics.p_alpha_total_mw, "OP ", ) po.ovarre( self.outfile, "Alpha power density: total (MW/m³)", "(pden_alpha_total_mw)", - physics_variables.pden_alpha_total_mw, + self.data.physics.pden_alpha_total_mw, "OP ", ) po.ovarre( self.outfile, "Alpha power: plasma only (MW)", "(p_plasma_alpha_mw)", - physics_variables.p_plasma_alpha_mw, + self.data.physics.p_plasma_alpha_mw, "OP ", ) po.ovarre( self.outfile, "Alpha power density: plasma (MW/m³)", "(pden_plasma_alpha_mw)", - physics_variables.pden_plasma_alpha_mw, + self.data.physics.pden_plasma_alpha_mw, "OP ", ) po.ovarre( self.outfile, "Alpha power: beam-plasma (MW)", "(p_beam_alpha_mw)", - physics_variables.p_beam_alpha_mw, + self.data.physics.p_beam_alpha_mw, "OP ", ) po.ovarre( self.outfile, "Alpha power per unit volume transferred to electrons (MW/m³)", "(f_pden_alpha_electron_mw)", - physics_variables.f_pden_alpha_electron_mw, + self.data.physics.f_pden_alpha_electron_mw, "OP ", ) po.ovarre( self.outfile, "Alpha power per unit volume transferred to ions (MW/m³)", "(f_pden_alpha_ions_mw)", - physics_variables.f_pden_alpha_ions_mw, + self.data.physics.f_pden_alpha_ions_mw, "OP ", ) @@ -1949,35 +1967,35 @@ def outplas(self): self.outfile, "Neutron power: total (MW)", "(p_neutron_total_mw)", - physics_variables.p_neutron_total_mw, + self.data.physics.p_neutron_total_mw, "OP ", ) po.ovarre( self.outfile, "Neutron power density: total (MW/m³)", "(pden_neutron_total_mw)", - physics_variables.pden_neutron_total_mw, + self.data.physics.pden_neutron_total_mw, "OP ", ) po.ovarre( self.outfile, "Neutron power: plasma only (MW)", "(p_plasma_neutron_mw)", - physics_variables.p_plasma_neutron_mw, + self.data.physics.p_plasma_neutron_mw, "OP ", ) po.ovarre( self.outfile, "Neutron power density: plasma (MW/m³)", "(pden_plasma_neutron_mw)", - physics_variables.pden_plasma_neutron_mw, + self.data.physics.pden_plasma_neutron_mw, "OP ", ) po.ovarre( self.outfile, "Neutron power: beam-plasma (MW)", "(p_beam_neutron_mw)", - physics_variables.p_beam_neutron_mw, + self.data.physics.p_beam_neutron_mw, "OP ", ) po.oblnkl(self.outfile) @@ -1985,7 +2003,7 @@ def outplas(self): self.outfile, "Average neutron flux at plasma surface (MW/m²)", "(pflux_plasma_surface_neutron_avg_mw)", - physics_variables.pflux_plasma_surface_neutron_avg_mw, + self.data.physics.pflux_plasma_surface_neutron_avg_mw, "OP ", ) po.oblnkl(self.outfile) @@ -1997,21 +2015,21 @@ def outplas(self): self.outfile, "Charged particle power (p, 3He, T) (excluding alphas) (MW)", "(p_non_alpha_charged_mw)", - physics_variables.p_non_alpha_charged_mw, + self.data.physics.p_non_alpha_charged_mw, "OP ", ) po.ovarre( self.outfile, "Charged particle power density (p, 3He, T) (excluding alphas) (MW)", "(pden_non_alpha_charged_mw)", - physics_variables.pden_non_alpha_charged_mw, + self.data.physics.pden_non_alpha_charged_mw, "OP ", ) po.ovarre( self.outfile, "Total charged particle power (including alphas) (MW)", "(p_charged_particle_mw)", - physics_variables.p_charged_particle_mw, + self.data.physics.p_charged_particle_mw, "OP ", ) po.oblnkl(self.outfile) @@ -2021,21 +2039,21 @@ def outplas(self): self.outfile, "Plasma total synchrotron radiation power (Pₛₙ) (MW)", "(p_plasma_sync_mw)", - physics_variables.p_plasma_sync_mw, + self.data.physics.p_plasma_sync_mw, "OP ", ) po.ovarre( self.outfile, "Plasma total synchrotron radiation power density (MW/m³)", "(pden_plasma_sync_mw)", - physics_variables.pden_plasma_sync_mw, + self.data.physics.pden_plasma_sync_mw, "OP ", ) po.ovarrf( self.outfile, "Synchrotron wall reflectivity factor", "(f_sync_reflect)", - physics_variables.f_sync_reflect, + self.data.physics.f_sync_reflect, ) po.oblnkl(self.outfile) po.ovarre( @@ -2054,14 +2072,14 @@ def outplas(self): self.outfile, "Plasma total radiation power from core region (MW) (Pᵧ,ᵢₙₙₑᵣ)", "(p_plasma_inner_rad_mw)", - physics_variables.p_plasma_inner_rad_mw, + self.data.physics.p_plasma_inner_rad_mw, "OP ", ) po.ovarre( self.outfile, "Plasma total radiation power from edge region (MW) (Pᵧ,ₒᵤₜₑᵣ)", "(p_plasma_outer_rad_mw)", - physics_variables.p_plasma_outer_rad_mw, + self.data.physics.p_plasma_outer_rad_mw, "OP ", ) @@ -2070,7 +2088,7 @@ def outplas(self): self.outfile, "SOL radiation power as imposed by f_rad (MW)", "(psolradmw)", - physics_variables.psolradmw, + self.data.physics.psolradmw, "OP ", ) @@ -2079,14 +2097,14 @@ def outplas(self): "Plasma total radiation power from inside last closed flux surface " "(Pᵧ) (MW)", "(p_plasma_rad_mw)", - physics_variables.p_plasma_rad_mw, + self.data.physics.p_plasma_rad_mw, "OP ", ) po.ovarre( self.outfile, "Separatrix radiation fraction (fᵧ)", "(f_p_plasma_separatrix_rad)", - physics_variables.f_p_plasma_separatrix_rad, + self.data.physics.f_p_plasma_separatrix_rad, "OP ", ) @@ -2096,21 +2114,21 @@ def outplas(self): self.outfile, "Power incident on the divertor targets (MW)", "(ptarmw)", - physics_variables.ptarmw, + self.data.physics.ptarmw, "OP ", ) po.ovarre( self.outfile, "Fraction of power to the lower divertor", "(f_p_div_lower)", - physics_variables.f_p_div_lower, + self.data.physics.f_p_div_lower, "IP ", ) po.ovarre( self.outfile, "Outboard side heat flux decay length (m)", "(lambdaio)", - physics_variables.lambdaio, + self.data.physics.lambdaio, "OP ", ) if self.data.divertor.n_divertors == 2: @@ -2118,7 +2136,7 @@ def outplas(self): self.outfile, "Midplane seperation of the two magnetic closed flux surfaces (m)", "(drsep)", - physics_variables.drsep, + self.data.physics.drsep, "OP ", ) @@ -2126,21 +2144,21 @@ def outplas(self): self.outfile, "Fraction of power on the inner targets", "(fio)", - physics_variables.fio, + self.data.physics.fio, "OP ", ) po.ovarre( self.outfile, "Fraction of power incident on the lower inner target", "(fLI)", - physics_variables.fli, + self.data.physics.fli, "OP ", ) po.ovarre( self.outfile, "Fraction of power incident on the lower outer target", "(fLO)", - physics_variables.flo, + self.data.physics.flo, "OP ", ) if self.data.divertor.n_divertors == 2: @@ -2148,14 +2166,14 @@ def outplas(self): self.outfile, "Fraction of power incident on the upper inner target", "(fUI)", - physics_variables.fui, + self.data.physics.fui, "OP ", ) po.ovarre( self.outfile, "Fraction of power incident on the upper outer target", "(fUO)", - physics_variables.fuo, + self.data.physics.fuo, "OP ", ) @@ -2163,14 +2181,14 @@ def outplas(self): self.outfile, "Power incident on the lower inner target (MW)", "(pLImw)", - physics_variables.plimw, + self.data.physics.plimw, "OP ", ) po.ovarre( self.outfile, "Power incident on the lower outer target (MW)", "(pLOmw)", - physics_variables.plomw, + self.data.physics.plomw, "OP ", ) if self.data.divertor.n_divertors == 2: @@ -2178,14 +2196,14 @@ def outplas(self): self.outfile, "Power incident on the upper innner target (MW)", "(pUImw)", - physics_variables.puimw, + self.data.physics.puimw, "OP ", ) po.ovarre( self.outfile, "Power incident on the upper outer target (MW)", "(pUOmw)", - physics_variables.puomw, + self.data.physics.puomw, "OP ", ) @@ -2194,42 +2212,42 @@ def outplas(self): self.outfile, "Ohmic heating power (MW)", "(p_plasma_ohmic_mw)", - physics_variables.p_plasma_ohmic_mw, + self.data.physics.p_plasma_ohmic_mw, "OP ", ) po.ovarrf( self.outfile, "Fraction of alpha power deposited in plasma", "(f_p_alpha_plasma_deposited)", - physics_variables.f_p_alpha_plasma_deposited, + self.data.physics.f_p_alpha_plasma_deposited, "IP", ) po.ovarrf( self.outfile, "Fraction of alpha power to electrons", "(f_alpha_electron)", - physics_variables.f_alpha_electron, + self.data.physics.f_alpha_electron, "OP ", ) po.ovarrf( self.outfile, "Fraction of alpha power to ions", "(f_alpha_ion)", - physics_variables.f_alpha_ion, + self.data.physics.f_alpha_ion, "OP ", ) po.ovarre( self.outfile, "Ion transport (MW)", "(p_ion_transport_loss_mw)", - physics_variables.p_ion_transport_loss_mw, + self.data.physics.p_ion_transport_loss_mw, "OP ", ) po.ovarre( self.outfile, "Electron transport (MW)", "(p_electron_transport_loss_mw)", - physics_variables.p_electron_transport_loss_mw, + self.data.physics.p_electron_transport_loss_mw, "OP ", ) po.ovarre( @@ -2246,13 +2264,13 @@ def outplas(self): self.data.current_drive.p_hcd_injected_electrons_mw, "OP ", ) - if physics_variables.i_plasma_ignited == 1: + if self.data.physics.i_plasma_ignited == 1: po.ocmmnt(self.outfile, " (Injected power only used for start-up phase)") self.exhaust.output() if self.data.stellarator.istell == 0: - self.plasma_transition.output_l_h_threshold_powers() + self.plasma_transition.output() self.confinement.output_confinement_time_info() @@ -2274,21 +2292,21 @@ def outplas(self): self.outfile, "Normalized plasma pressure beta as defined by McDonald et al", "(beta_mcdonald)", - physics_variables.beta_mcdonald, + self.data.physics.beta_mcdonald, "OP ", ) po.ovarre( self.outfile, "Normalized ion Larmor radius", "(rho_star)", - physics_variables.rho_star, + self.data.physics.rho_star, "OP ", ) po.ovarre( self.outfile, "Normalized collisionality", "(nu_star)", - physics_variables.nu_star, + self.data.physics.nu_star, "OP ", ) @@ -2304,27 +2322,27 @@ def outplas(self): self.outfile, "Ratio of He and pellet particle confinement times", "(tauratio)", - physics_variables.tauratio, + self.data.physics.tauratio, ) po.ovarre( self.outfile, "Fuelling rate (nucleus-pairs/s)", "(molflow_plasma_fuelling_required)", - physics_variables.molflow_plasma_fuelling_required, + self.data.physics.molflow_plasma_fuelling_required, "OP ", ) po.ovarre( self.outfile, "Fuel burn-up rate (reactions/s)", "(rndfuel)", - physics_variables.rndfuel, + self.data.physics.rndfuel, "OP ", ) po.ovarrf( self.outfile, "Burn-up fraction", "(burnup)", - physics_variables.burnup, + self.data.physics.burnup, "OP ", ) @@ -2357,26 +2375,26 @@ def output_temperature_density_profile_info(self) -> None: self.outfile, "Number of radial points in plasma profiles", "(n_plasma_profile_elements)", - physics_variables.n_plasma_profile_elements, + self.data.physics.n_plasma_profile_elements, ) po.ovarin( self.outfile, "Plasma profile model selected", "(i_plasma_pedestal)", - physics_variables.i_plasma_pedestal, + self.data.physics.i_plasma_pedestal, ) po.ocmmnt( self.outfile, f"Plasma profile model selected: " - f"{PlasmaProfileShapeType(physics_variables.i_plasma_pedestal).description}", + f"{PlasmaProfileShapeType(self.data.physics.i_plasma_pedestal).description}", ) if ( - PlasmaProfileShapeType(physics_variables.i_plasma_pedestal) + PlasmaProfileShapeType(self.data.physics.i_plasma_pedestal) == PlasmaProfileShapeType.PEDESTAL_PROFILE ) and ( - physics_variables.nd_plasma_electron_on_axis - < physics_variables.nd_plasma_pedestal_electron + self.data.physics.nd_plasma_electron_on_axis + < self.data.physics.nd_plasma_pedestal_electron ): logger.error("Central density is less than pedestal density") po.oblnkl(self.outfile) @@ -2386,39 +2404,39 @@ def output_temperature_density_profile_info(self) -> None: self.outfile, "Temperature profile index (αₜ)", "(alphat)", - physics_variables.alphat, + self.data.physics.alphat, ) po.ovarrf( self.outfile, "Temperature profile index beta (βₜ)", "(tbeta)", - physics_variables.tbeta, + self.data.physics.tbeta, ) po.oblnkl(self.outfile) if ( - PlasmaProfileShapeType(physics_variables.i_plasma_pedestal) + PlasmaProfileShapeType(self.data.physics.i_plasma_pedestal) == PlasmaProfileShapeType.PEDESTAL_PROFILE ): po.ovarrf( self.outfile, "Temperature pedestal r/a location (ρₜ,pedestal)", "(radius_plasma_pedestal_temp_norm)", - physics_variables.radius_plasma_pedestal_temp_norm, + self.data.physics.radius_plasma_pedestal_temp_norm, ) po.ovarrf( self.outfile, "Electron temperature pedestal height (Tₑ,pedestal) (keV)", "(temp_plasma_pedestal_kev)", - physics_variables.temp_plasma_pedestal_kev, + self.data.physics.temp_plasma_pedestal_kev, ) if 78 in numerics.icc: po.ovarrf( self.outfile, "Electron temperature at separatrix (Tₑ,ₛₑₚ) (keV)", "(temp_plasma_separatrix_kev)", - physics_variables.temp_plasma_separatrix_kev, + self.data.physics.temp_plasma_separatrix_kev, "OP ", ) else: @@ -2426,7 +2444,7 @@ def output_temperature_density_profile_info(self) -> None: self.outfile, "Electron temperature at separatrix (Tₑ,ₛₑₚ) (keV)", "(temp_plasma_separatrix_kev)", - physics_variables.temp_plasma_separatrix_kev, + self.data.physics.temp_plasma_separatrix_kev, ) po.oblnkl(self.outfile) @@ -2434,27 +2452,27 @@ def output_temperature_density_profile_info(self) -> None: self.outfile, "Volume averaged electron temperature (⟨Tₑ⟩) (keV)", "(temp_plasma_electron_vol_avg_kev)", - physics_variables.temp_plasma_electron_vol_avg_kev, + self.data.physics.temp_plasma_electron_vol_avg_kev, ) po.ovarrf( self.outfile, "Electron temperature on axis (Tₑ₀) (keV)", "(temp_plasma_electron_on_axis_kev)", - physics_variables.temp_plasma_electron_on_axis_kev, + self.data.physics.temp_plasma_electron_on_axis_kev, "OP ", ) po.ovarrf( self.outfile, "Volume averaged density weighted electron temperature (⟨Tₑ⟩ₙ) (keV)", "(temp_plasma_electron_density_weighted_kev)", - physics_variables.temp_plasma_electron_density_weighted_kev, + self.data.physics.temp_plasma_electron_density_weighted_kev, "OP ", ) po.ovarrf( self.outfile, "Ratio of electron density weighted to volume averaged temperature", "(f_temp_plasma_electron_density_vol_avg)", - physics_variables.f_temp_plasma_electron_density_vol_avg, + self.data.physics.f_temp_plasma_electron_density_vol_avg, "OP ", ) po.oblnkl(self.outfile) @@ -2462,7 +2480,7 @@ def output_temperature_density_profile_info(self) -> None: self.outfile, "Ratio of ion to electron volume-averaged temperature", "(f_temp_plasma_ion_electron)", - physics_variables.f_temp_plasma_ion_electron, + self.data.physics.f_temp_plasma_ion_electron, "IP ", ) po.oblnkl(self.outfile) @@ -2470,13 +2488,13 @@ def output_temperature_density_profile_info(self) -> None: self.outfile, "Volume averaged ion temperature (⟨Tᵢ⟩) (keV)", "(temp_plasma_ion_vol_avg_kev)", - physics_variables.temp_plasma_ion_vol_avg_kev, + self.data.physics.temp_plasma_ion_vol_avg_kev, ) po.ovarrf( self.outfile, "Ion temperature on axis (Tᵢ₀) (keV)", "(temp_plasma_ion_on_axis_kev)", - physics_variables.temp_plasma_ion_on_axis_kev, + self.data.physics.temp_plasma_ion_on_axis_kev, "OP ", ) po.oblnkl(self.outfile) @@ -2487,25 +2505,25 @@ def output_temperature_density_profile_info(self) -> None: self.outfile, "Density profile factor (αₙ)", "(alphan)", - physics_variables.alphan, + self.data.physics.alphan, ) po.oblnkl(self.outfile) if ( - PlasmaProfileShapeType(physics_variables.i_plasma_pedestal) + PlasmaProfileShapeType(self.data.physics.i_plasma_pedestal) == PlasmaProfileShapeType.PEDESTAL_PROFILE ): po.ovarrf( self.outfile, "Density pedestal r/a location (ρₙ,pedestal)", "(radius_plasma_pedestal_density_norm)", - physics_variables.radius_plasma_pedestal_density_norm, + self.data.physics.radius_plasma_pedestal_density_norm, ) - if physics_variables.f_nd_plasma_pedestal_greenwald >= 0e0: + if self.data.physics.f_nd_plasma_pedestal_greenwald >= 0e0: po.ovarre( self.outfile, "Electron density pedestal height (nₑ_pedestal) (/m³)", "(nd_plasma_pedestal_electron)", - physics_variables.nd_plasma_pedestal_electron, + self.data.physics.nd_plasma_pedestal_electron, "OP ", ) else: @@ -2513,26 +2531,26 @@ def output_temperature_density_profile_info(self) -> None: self.outfile, "Electron density pedestal height (nₑ_pedestal) (/m³)", "(nd_plasma_pedestal_electron)", - physics_variables.nd_plasma_pedestal_electron, + self.data.physics.nd_plasma_pedestal_electron, ) # must be assigned to their exisiting values# fgwped_out = ( - physics_variables.nd_plasma_pedestal_electron - / physics_variables.nd_plasma_electron_max_array[6] + self.data.physics.nd_plasma_pedestal_electron + / self.data.physics.nd_plasma_electron_max_array[6] ) fgwsep_out = ( - physics_variables.nd_plasma_separatrix_electron - / physics_variables.nd_plasma_electron_max_array[6] + self.data.physics.nd_plasma_separatrix_electron + / self.data.physics.nd_plasma_electron_max_array[6] ) - if physics_variables.f_nd_plasma_pedestal_greenwald >= 0e0: - physics_variables.f_nd_plasma_pedestal_greenwald = ( - physics_variables.nd_plasma_pedestal_electron - / physics_variables.nd_plasma_electron_max_array[6] + if self.data.physics.f_nd_plasma_pedestal_greenwald >= 0e0: + self.data.physics.f_nd_plasma_pedestal_greenwald = ( + self.data.physics.nd_plasma_pedestal_electron + / self.data.physics.nd_plasma_electron_max_array[6] ) - if physics_variables.f_nd_plasma_separatrix_greenwald >= 0e0: - physics_variables.f_nd_plasma_separatrix_greenwald = ( - physics_variables.nd_plasma_separatrix_electron - / physics_variables.nd_plasma_electron_max_array[6] + if self.data.physics.f_nd_plasma_separatrix_greenwald >= 0e0: + self.data.physics.f_nd_plasma_separatrix_greenwald = ( + self.data.physics.nd_plasma_separatrix_electron + / self.data.physics.nd_plasma_electron_max_array[6] ) po.ovarre( @@ -2545,7 +2563,7 @@ def output_temperature_density_profile_info(self) -> None: self.outfile, "Electron density at separatrix (nₑ,ₛₑₚ) (/m³)", "(nd_plasma_separatrix_electron)", - physics_variables.nd_plasma_separatrix_electron, + self.data.physics.nd_plasma_separatrix_electron, ) po.ovarre( self.outfile, @@ -2559,20 +2577,20 @@ def output_temperature_density_profile_info(self) -> None: self.outfile, "Volume averaged electron number density (⟨nₑ⟩) (/m³)", "(nd_plasma_electrons_vol_avg)", - physics_variables.nd_plasma_electrons_vol_avg, + self.data.physics.nd_plasma_electrons_vol_avg, ) po.ovarre( self.outfile, "Electron number density on axis (nₑ₀) (/m³)", "(nd_plasma_electron_on_axis)", - physics_variables.nd_plasma_electron_on_axis, + self.data.physics.nd_plasma_electron_on_axis, "OP ", ) po.ovarre( self.outfile, "Line-averaged electron number density (ñₑ) (/m³)", "(nd_plasma_electron_line)", - physics_variables.nd_plasma_electron_line, + self.data.physics.nd_plasma_electron_line, "OP ", ) if self.data.stellarator.istell == 0: @@ -2580,8 +2598,8 @@ def output_temperature_density_profile_info(self) -> None: self.outfile, "Greenwald fraction (f_GW)", "(dnla_gw)", - physics_variables.nd_plasma_electron_line - / physics_variables.nd_plasma_electron_max_array[6], + self.data.physics.nd_plasma_electron_line + / self.data.physics.nd_plasma_electron_max_array[6], "OP ", ) po.oblnkl(self.outfile) @@ -2589,48 +2607,48 @@ def output_temperature_density_profile_info(self) -> None: self.outfile, "Total ion volume averaged number density (⟨nᵢ⟩) (/m³)", "(nd_plasma_ions_total_vol_avg)", - physics_variables.nd_plasma_ions_total_vol_avg, + self.data.physics.nd_plasma_ions_total_vol_avg, "OP ", ) po.ovarre( self.outfile, "Fuel ion volume averaged number density (⟨n_fuel⟩) (/m³)", "(nd_plasma_fuel_ions_vol_avg)", - physics_variables.nd_plasma_fuel_ions_vol_avg, + self.data.physics.nd_plasma_fuel_ions_vol_avg, "OP ", ) po.ovarre( self.outfile, "Total impurity volume averaged number density with Z > 2 (⟨nᵢₘₚ⟩) (/m³)", "(nd_plasma_impurities_vol_avg)", - physics_variables.nd_plasma_impurities_vol_avg, + self.data.physics.nd_plasma_impurities_vol_avg, "OP ", ) po.ovarre( self.outfile, "Thermalised alpha volume averaged number density (⟨n_alpha⟩) (/m³)", "(nd_plasma_alphas_vol_avg)", - physics_variables.nd_plasma_alphas_vol_avg, + self.data.physics.nd_plasma_alphas_vol_avg, "OP ", ) po.ovarre( self.outfile, "Thermalised alpha to electron number density ratio (⟨n_alpha⟩/⟨nₑ⟩)", "(f_nd_alpha_electron)", - physics_variables.f_nd_alpha_electron, + self.data.physics.f_nd_alpha_electron, ) po.ovarre( self.outfile, "Proton volume averaged number density (⟨nₚ⟩) (/m³)", "(nd_plasma_protons_vol_avg)", - physics_variables.nd_plasma_protons_vol_avg, + self.data.physics.nd_plasma_protons_vol_avg, "OP ", ) po.ovarre( self.outfile, "Proton to electron volume averaged number density ratio (⟨nₚ⟩/⟨nₑ⟩)", "(f_nd_protium_electrons)", - physics_variables.f_nd_protium_electrons, + self.data.physics.f_nd_protium_electrons, "OP ", ) po.oblnkl(self.outfile) @@ -2638,14 +2656,14 @@ def output_temperature_density_profile_info(self) -> None: self.outfile, "Hot beam ion volume averaged number density (⟨n_beam⟩) (/m³)", "(nd_beam_ions)", - physics_variables.nd_beam_ions, + self.data.physics.nd_beam_ions, "OP ", ) po.ovarre( self.outfile, "Hot beam ion to electron number density ratio (⟨n_beam⟩/⟨nₑ⟩)", "(f_nd_beam_electron)", - physics_variables.f_nd_beam_electron, + self.data.physics.f_nd_beam_electron, "OP ", ) po.oblnkl(self.outfile) @@ -2657,53 +2675,53 @@ def output_temperature_density_profile_info(self) -> None: self.outfile, "Pressure profile index (αₚ)", "(alphap)", - physics_variables.alphap, + self.data.physics.alphap, ) po.oblnkl(self.outfile) po.ovarre( self.outfile, "Plasma thermal pressure on axis (p₀) (Pa)", "(pres_plasma_thermal_on_axis)", - physics_variables.pres_plasma_thermal_on_axis, + self.data.physics.pres_plasma_thermal_on_axis, "OP ", ) po.ovarre( self.outfile, "Volume averaged plasma thermal pressure (⟨p⟩) (Pa)", "(pres_plasma_thermal_vol_avg)", - physics_variables.pres_plasma_thermal_vol_avg, + self.data.physics.pres_plasma_thermal_vol_avg, "OP ", ) # As array output is not currently supported, each element is output as a float # instance # Output plasma pressure profiles to mfile - for i in range(len(physics_variables.pres_plasma_thermal_total_profile)): + for i in range(len(self.data.physics.pres_plasma_thermal_total_profile)): po.ovarre( self.mfile, f"Total plasma pressure at point {i}", f"(pres_plasma_thermal_total_profile{i})", - physics_variables.pres_plasma_thermal_total_profile[i], + self.data.physics.pres_plasma_thermal_total_profile[i], ) - for i in range(len(physics_variables.pres_plasma_electron_profile)): + for i in range(len(self.data.physics.pres_plasma_electron_profile)): po.ovarre( self.mfile, f"Total plasma electron pressure at point {i}", f"(pres_plasma_electron_profile{i})", - physics_variables.pres_plasma_electron_profile[i], + self.data.physics.pres_plasma_electron_profile[i], ) - for i in range(len(physics_variables.pres_plasma_ion_total_profile)): + for i in range(len(self.data.physics.pres_plasma_ion_total_profile)): po.ovarre( self.mfile, f"Total plasma ion pressure at point {i}", f"(pres_plasma_ion_total_profile{i})", - physics_variables.pres_plasma_ion_total_profile[i], + self.data.physics.pres_plasma_ion_total_profile[i], ) - for i in range(len(physics_variables.pres_plasma_fuel_profile)): + for i in range(len(self.data.physics.pres_plasma_fuel_profile)): po.ovarre( self.mfile, f"Total plasma fuel pressure at point {i}", f"(pres_plasma_fuel_profile{i})", - physics_variables.pres_plasma_fuel_profile[i], + self.data.physics.pres_plasma_fuel_profile[i], ) po.oblnkl(self.outfile) po.ocmmnt(self.outfile, "----------------------------") @@ -2745,7 +2763,7 @@ def output_temperature_density_profile_info(self) -> None: self.data.impurity_radiation.f_nd_impurity_electrons[imp], ) if self.data.impurity_radiation.f_nd_impurity_electrons[imp] != 0.0: # noqa: RUF069 - for i in range(physics_variables.n_plasma_profile_elements): + for i in range(self.data.physics.n_plasma_profile_elements): po.ovarre( self.mfile, str1 + f" at point {i}", @@ -2760,20 +2778,20 @@ def output_temperature_density_profile_info(self) -> None: self.outfile, "Volume averaged plasma effective charge (⟨Zₑ⟩)", "(n_charge_plasma_effective_vol_avg)", - physics_variables.n_charge_plasma_effective_vol_avg, + self.data.physics.n_charge_plasma_effective_vol_avg, "OP ", ) - for i in range(len(physics_variables.n_charge_plasma_effective_profile)): + for i in range(len(self.data.physics.n_charge_plasma_effective_profile)): po.ovarre( self.mfile, "Effective charge at point", f"(n_charge_plasma_effective_profile{i})", - physics_variables.n_charge_plasma_effective_profile[i], + self.data.physics.n_charge_plasma_effective_profile[i], "OP ", ) for imp in range(N_IMPURITIES): - for i in range(physics_variables.n_plasma_profile_elements): + for i in range(self.data.physics.n_plasma_profile_elements): po.ovarre( self.mfile, "Impurity charge at point", @@ -2786,7 +2804,7 @@ def output_temperature_density_profile_info(self) -> None: self.outfile, "Volume averaged mass-weighted plasma effective charge (⟨Zₑ⟩ₘ)", "(n_charge_plasma_effective_mass_weighted_vol_avg)", - physics_variables.n_charge_plasma_effective_mass_weighted_vol_avg, + self.data.physics.n_charge_plasma_effective_mass_weighted_vol_avg, "OP ", ) po.oblnkl(self.outfile) @@ -2799,56 +2817,56 @@ def output_temperature_density_profile_info(self) -> None: self.outfile, "Average mass of all ions (amu)", "(m_ions_total_amu)", - physics_variables.m_ions_total_amu, + self.data.physics.m_ions_total_amu, "OP ", ) po.ovarre( self.outfile, "Total mass of all ions in plasma (kg)", "(m_plasma_ions_total)", - physics_variables.m_plasma_ions_total, + self.data.physics.m_plasma_ions_total, "OP ", ) po.ovarre( self.outfile, "Average mass of all fuel ions (amu)", "(m_fuel_amu)", - physics_variables.m_fuel_amu, + self.data.physics.m_fuel_amu, "OP ", ) po.ovarre( self.outfile, "Total mass of all fuel ions in plasma (kg)", "(m_plasma_fuel_ions)", - physics_variables.m_plasma_fuel_ions, + self.data.physics.m_plasma_fuel_ions, "OP ", ) po.ovarre( self.outfile, "Average mass of all beam ions (amu)", "(m_beam_amu)", - physics_variables.m_beam_amu, + self.data.physics.m_beam_amu, "OP ", ) po.ovarre( self.outfile, "Total mass of all alpha particles in plasma (kg)", "(m_plasma_alpha)", - physics_variables.m_plasma_alpha, + self.data.physics.m_plasma_alpha, "OP ", ) po.ovarre( self.outfile, "Total mass of all electrons in plasma (kg)", "(m_plasma_electron)", - physics_variables.m_plasma_electron, + self.data.physics.m_plasma_electron, "OP ", ) po.ovarre( self.outfile, "Total mass of the plasma (kg)", "(m_plasma)", - physics_variables.m_plasma, + self.data.physics.m_plasma, "OP ", ) @@ -2860,13 +2878,13 @@ def output_temperature_density_profile_info(self) -> None: self.outfile, "Critical ballooning parameter value", "(alpha_crit)", - physics_variables.alpha_crit, + self.data.physics.alpha_crit, ) po.ovarre( self.outfile, "Critical electron density at separatrix (/m3)", "(nd_plasma_separatrix_electron_eich_max)", - physics_variables.nd_plasma_separatrix_electron_eich_max, + self.data.physics.nd_plasma_separatrix_electron_eich_max, ) @staticmethod @@ -2996,7 +3014,7 @@ class BetaNormMaxModel(IntEnum): WESSON = (1, "Wesson Scaling") ORIGINAL_SCALING = (2, "Original Scaling") MENARD = (3, "Menard Scaling") - THLOREUS = (4, "Thloreus Scaling") + THOLERUS = (4, "tholerus Scaling") STAMBAUGH = (5, "Stambaugh Scaling") def __new__(cls, value: int, full_name: str): @@ -3044,20 +3062,25 @@ def output(self): """This model doesn't have any output""" @staticmethod - def get_beta_norm_max_value(model: BetaNormMaxModel) -> float: + def get_beta_norm_max_value( + model: BetaNormMaxModel, physics_data: PhysicsData + ) -> float: """Get the beta norm max value (β_N_max) for the specified model. Parameters ---------- model: BetaNormMaxModel : + + physics_data: PhysicsData + data structure object containing physics data """ model_map = { - BetaNormMaxModel.USER_INPUT: physics_variables.beta_norm_max, - BetaNormMaxModel.WESSON: physics_variables.beta_norm_max_wesson, - BetaNormMaxModel.ORIGINAL_SCALING: physics_variables.beta_norm_max_original_scaling, - BetaNormMaxModel.MENARD: physics_variables.beta_norm_max_menard, - BetaNormMaxModel.THLOREUS: physics_variables.beta_norm_max_thloreus, - BetaNormMaxModel.STAMBAUGH: physics_variables.beta_norm_max_stambaugh, + BetaNormMaxModel.USER_INPUT: physics_data.beta_norm_max, + BetaNormMaxModel.WESSON: physics_data.beta_norm_max_wesson, + BetaNormMaxModel.ORIGINAL_SCALING: physics_data.beta_norm_max_original_scaling, + BetaNormMaxModel.MENARD: physics_data.beta_norm_max_menard, + BetaNormMaxModel.THOLERUS: physics_data.beta_norm_max_tholerus, + BetaNormMaxModel.STAMBAUGH: physics_data.beta_norm_max_stambaugh, } return model_map[model] @@ -3075,99 +3098,101 @@ def run(self): # ----------------------------------------------------- # Normalised beta from Troyon beta limit - physics_variables.beta_norm_total = self.calculate_normalised_beta( - beta=physics_variables.beta_total_vol_avg, - rminor=physics_variables.rminor, - c_plasma=physics_variables.plasma_current, - b_field=physics_variables.b_plasma_toroidal_on_axis, + self.data.physics.beta_norm_total = self.calculate_normalised_beta( + beta=self.data.physics.beta_total_vol_avg, + rminor=self.data.physics.rminor, + c_plasma=self.data.physics.plasma_current, + b_field=self.data.physics.b_plasma_toroidal_on_axis, ) # Define beta_norm_max calculations - physics_variables.beta_norm_max_wesson = self.calculate_beta_norm_max_wesson( - ind_plasma_internal_norm=physics_variables.ind_plasma_internal_norm + self.data.physics.beta_norm_max_wesson = self.calculate_beta_norm_max_wesson( + ind_plasma_internal_norm=self.data.physics.ind_plasma_internal_norm ) # Original scaling law - physics_variables.beta_norm_max_original_scaling = ( - self.calculate_beta_norm_max_original(eps=physics_variables.eps) + self.data.physics.beta_norm_max_original_scaling = ( + self.calculate_beta_norm_max_original(eps=self.data.physics.eps) ) # J. Menard scaling law - physics_variables.beta_norm_max_menard = self.calculate_beta_norm_max_menard( - eps=physics_variables.eps + self.data.physics.beta_norm_max_menard = self.calculate_beta_norm_max_menard( + eps=self.data.physics.eps ) # E. Tholerus scaling law - physics_variables.beta_norm_max_thloreus = self.calculate_beta_norm_max_thloreus( - c_beta=physics_variables.c_beta, - pres_plasma_on_axis=physics_variables.pres_plasma_thermal_on_axis, - pres_plasma_vol_avg=physics_variables.pres_plasma_thermal_vol_avg, + self.data.physics.beta_norm_max_tholerus = self.calculate_beta_norm_max_tholerus( + c_beta=self.data.physics.c_beta, + pres_plasma_on_axis=self.data.physics.pres_plasma_thermal_on_axis, + pres_plasma_vol_avg=self.data.physics.pres_plasma_thermal_vol_avg, ) # R. D. Stambaugh scaling law - physics_variables.beta_norm_max_stambaugh = ( + self.data.physics.beta_norm_max_stambaugh = ( self.calculate_beta_norm_max_stambaugh( f_c_plasma_bootstrap=self.data.current_drive.f_c_plasma_bootstrap, - kappa=physics_variables.kappa, - aspect=physics_variables.aspect, + kappa=self.data.physics.kappa, + aspect=self.data.physics.aspect, ) ) # Calculate beta_norm_max based on i_beta_norm_max try: - model = BetaNormMaxModel(int(physics_variables.i_beta_norm_max)) - physics_variables.beta_norm_max = self.get_beta_norm_max_value(model) + model = BetaNormMaxModel(int(self.data.physics.i_beta_norm_max)) + self.data.physics.beta_norm_max = self.get_beta_norm_max_value( + model, self.data.physics + ) except ValueError: raise ProcessValueError( "Illegal value of i_beta_norm_max", - i_beta_norm_max=physics_variables.i_beta_norm_max, + i_beta_norm_max=self.data.physics.i_beta_norm_max, ) from None # calculate_beta_limit() returns the beta_vol_avg_max for beta - physics_variables.beta_vol_avg_max = self.calculate_beta_limit_from_norm( - b_plasma_toroidal_on_axis=physics_variables.b_plasma_toroidal_on_axis, - beta_norm_max=physics_variables.beta_norm_max, - plasma_current=physics_variables.plasma_current, - rminor=physics_variables.rminor, + self.data.physics.beta_vol_avg_max = self.calculate_beta_limit_from_norm( + b_plasma_toroidal_on_axis=self.data.physics.b_plasma_toroidal_on_axis, + beta_norm_max=self.data.physics.beta_norm_max, + plasma_current=self.data.physics.plasma_current, + rminor=self.data.physics.rminor, ) - physics_variables.beta_toroidal_vol_avg = ( - physics_variables.beta_total_vol_avg - * physics_variables.b_plasma_total**2 - / physics_variables.b_plasma_toroidal_on_axis**2 + self.data.physics.beta_toroidal_vol_avg = ( + self.data.physics.beta_total_vol_avg + * self.data.physics.b_plasma_total**2 + / self.data.physics.b_plasma_toroidal_on_axis**2 ) - # Calculate physics_variables.beta poloidal [-] - physics_variables.beta_poloidal_vol_avg = self.calculate_poloidal_beta( - b_plasma_total=physics_variables.b_plasma_total, - b_plasma_poloidal_average=physics_variables.b_plasma_surface_poloidal_average, - beta=physics_variables.beta_total_vol_avg, + # Calculate self.data.physics.beta poloidal [-] + self.data.physics.beta_poloidal_vol_avg = self.calculate_poloidal_beta( + b_plasma_total=self.data.physics.b_plasma_total, + b_plasma_poloidal_average=self.data.physics.b_plasma_surface_poloidal_average, + beta=self.data.physics.beta_total_vol_avg, ) - physics_variables.beta_thermal_vol_avg = ( - physics_variables.beta_total_vol_avg - - physics_variables.beta_fast_alpha - - physics_variables.beta_beam + self.data.physics.beta_thermal_vol_avg = ( + self.data.physics.beta_total_vol_avg + - self.data.physics.beta_fast_alpha + - self.data.physics.beta_beam ) - physics_variables.beta_poloidal_eps = ( - physics_variables.beta_poloidal_vol_avg * physics_variables.eps + self.data.physics.beta_poloidal_eps = ( + self.data.physics.beta_poloidal_vol_avg * self.data.physics.eps ) - physics_variables.beta_thermal_poloidal_vol_avg = ( - physics_variables.beta_thermal_vol_avg + self.data.physics.beta_thermal_poloidal_vol_avg = ( + self.data.physics.beta_thermal_vol_avg * ( - physics_variables.b_plasma_total - / physics_variables.b_plasma_surface_poloidal_average + self.data.physics.b_plasma_total + / self.data.physics.b_plasma_surface_poloidal_average ) ** 2 ) - physics_variables.beta_thermal_toroidal_vol_avg = ( - physics_variables.beta_thermal_vol_avg + self.data.physics.beta_thermal_toroidal_vol_avg = ( + self.data.physics.beta_thermal_vol_avg * ( - physics_variables.b_plasma_total - / physics_variables.b_plasma_toroidal_on_axis + self.data.physics.b_plasma_total + / self.data.physics.b_plasma_toroidal_on_axis ) ** 2 ) @@ -3176,60 +3201,60 @@ def run(self): # Mirror the pressure profiles to match the doubled toroidal field profile pres_profile_total = np.concatenate([ - physics_variables.pres_plasma_thermal_total_profile[::-1], - physics_variables.pres_plasma_thermal_total_profile, + self.data.physics.pres_plasma_thermal_total_profile[::-1], + self.data.physics.pres_plasma_thermal_total_profile, ]) - physics_variables.beta_thermal_toroidal_profile = np.array([ + self.data.physics.beta_thermal_toroidal_profile = np.array([ self.calculate_plasma_beta( pres_plasma=pres_profile_total[i], - b_field=physics_variables.b_plasma_toroidal_profile[i], + b_field=self.data.physics.b_plasma_toroidal_profile[i], ) - for i in range(len(physics_variables.b_plasma_toroidal_profile)) + for i in range(len(self.data.physics.b_plasma_toroidal_profile)) ]) # ======================================================= - physics_variables.beta_norm_thermal = self.calculate_normalised_beta( - beta=physics_variables.beta_thermal_vol_avg, - rminor=physics_variables.rminor, - c_plasma=physics_variables.plasma_current, - b_field=physics_variables.b_plasma_toroidal_on_axis, + self.data.physics.beta_norm_thermal = self.calculate_normalised_beta( + beta=self.data.physics.beta_thermal_vol_avg, + rminor=self.data.physics.rminor, + c_plasma=self.data.physics.plasma_current, + b_field=self.data.physics.b_plasma_toroidal_on_axis, ) - physics_variables.beta_norm_toroidal = ( - physics_variables.beta_norm_total + self.data.physics.beta_norm_toroidal = ( + self.data.physics.beta_norm_total * ( - physics_variables.b_plasma_total - / physics_variables.b_plasma_toroidal_on_axis + self.data.physics.b_plasma_total + / self.data.physics.b_plasma_toroidal_on_axis ) ** 2 ) - physics_variables.beta_norm_poloidal = ( - physics_variables.beta_norm_total + self.data.physics.beta_norm_poloidal = ( + self.data.physics.beta_norm_total * ( - physics_variables.b_plasma_total - / physics_variables.b_plasma_surface_poloidal_average + self.data.physics.b_plasma_total + / self.data.physics.b_plasma_surface_poloidal_average ) ** 2 ) - physics_variables.f_beta_alpha_beam_thermal = ( - physics_variables.beta_fast_alpha + physics_variables.beta_beam - ) / physics_variables.beta_thermal_vol_avg + self.data.physics.f_beta_alpha_beam_thermal = ( + self.data.physics.beta_fast_alpha + self.data.physics.beta_beam + ) / self.data.physics.beta_thermal_vol_avg # Plasma thermal energy derived from the thermal beta - physics_variables.e_plasma_beta_thermal = self.calculate_plasma_energy_from_beta( - beta=physics_variables.beta_thermal_vol_avg, - b_field=physics_variables.b_plasma_total, - vol_plasma=physics_variables.vol_plasma, + self.data.physics.e_plasma_beta_thermal = self.calculate_plasma_energy_from_beta( + beta=self.data.physics.beta_thermal_vol_avg, + b_field=self.data.physics.b_plasma_total, + vol_plasma=self.data.physics.vol_plasma, ) # Plasma thermal energy derived from the total beta - physics_variables.e_plasma_beta = self.calculate_plasma_energy_from_beta( - beta=physics_variables.beta_total_vol_avg, - b_field=physics_variables.b_plasma_total, - vol_plasma=physics_variables.vol_plasma, + self.data.physics.e_plasma_beta = self.calculate_plasma_energy_from_beta( + beta=self.data.physics.beta_total_vol_avg, + b_field=self.data.physics.b_plasma_total, + vol_plasma=self.data.physics.vol_plasma, ) @staticmethod @@ -3342,7 +3367,7 @@ def calculate_beta_norm_max_menard(eps: float) -> float: @staticmethod @nb.njit(cache=True) - def calculate_beta_norm_max_thloreus( + def calculate_beta_norm_max_tholerus( c_beta: float, pres_plasma_on_axis: float, pres_plasma_vol_avg: float ) -> float: """Calculate the E. Tholerus normalized beta upper limit. @@ -3592,6 +3617,7 @@ def fast_alpha_beta( pden_alpha_total_mw: float, pden_plasma_alpha_mw: float, i_beta_fast_alpha: int, + f_plasma_fuel_deuterium: float, ) -> float: """Calculate the fast alpha beta (β_fast_alpha) component. @@ -3620,6 +3646,8 @@ def fast_alpha_beta( Alpha power per unit volume just from plasma (MW/m³). i_beta_fast_alpha : int Switch for fast alpha pressure method. + f_plasma_fuel_deuterium: float + Plasma deuterium fuel fraction Returns ------- @@ -3644,7 +3672,7 @@ def fast_alpha_beta( """ # Determine average fast alpha density - if physics_variables.f_plasma_fuel_deuterium < 1.0: + if f_plasma_fuel_deuterium < 1.0: beta_thermal = ( 2.0 * constants.RMU0 @@ -3713,45 +3741,45 @@ def output_beta_information(self): self.outfile, "Beta component for limits", "(i_beta_component)", - physics_variables.i_beta_component, + self.data.physics.i_beta_component, ) po.ocmmnt( self.outfile, f"Beta component model selected for limit: " - f"{BetaComponentLimits(physics_variables.i_beta_component).full_name} ", + f"{BetaComponentLimits(self.data.physics.i_beta_component).full_name} ", ) po.oblnkl(self.outfile) - if physics_variables.i_beta_component == BetaComponentLimits.TOTAL: + if self.data.physics.i_beta_component == BetaComponentLimits.TOTAL: po.ovarrf( self.outfile, "Upper limit on volume averaged total beta (⟨β⟩<)", "(beta_vol_avg_max)", - physics_variables.beta_vol_avg_max, + self.data.physics.beta_vol_avg_max, "OP ", ) - elif physics_variables.i_beta_component == BetaComponentLimits.THERMAL: + elif self.data.physics.i_beta_component == BetaComponentLimits.THERMAL: po.ovarrf( self.outfile, "Upper limit on volume averaged thermal beta (⟨βₜₕ⟩<)", "(beta_vol_avg_max)", - physics_variables.beta_vol_avg_max, + self.data.physics.beta_vol_avg_max, "OP ", ) - elif physics_variables.i_beta_component == BetaComponentLimits.THERMAL_AND_BEAM: + elif self.data.physics.i_beta_component == BetaComponentLimits.THERMAL_AND_BEAM: po.ovarrf( self.outfile, "Upper limit on volume averaged thermal + NB beta (⟨βₜₕ+βₙᵦ⟩<)", "(beta_vol_avg_max)", - physics_variables.beta_vol_avg_max, + self.data.physics.beta_vol_avg_max, "OP ", ) - elif physics_variables.i_beta_component == BetaComponentLimits.TOROIDAL: + elif self.data.physics.i_beta_component == BetaComponentLimits.TOROIDAL: po.ovarrf( self.outfile, "Upper limit on volume averaged toroidal beta (⟨βₜ⟩<)", "(beta_vol_avg_max)", - physics_variables.beta_vol_avg_max, + self.data.physics.beta_vol_avg_max, "OP ", ) @@ -3759,22 +3787,22 @@ def output_beta_information(self): self.outfile, "Volume averaged total plasma beta (⟨β⟩)", "(beta_total_vol_avg)", - physics_variables.beta_total_vol_avg, + self.data.physics.beta_total_vol_avg, ) - if physics_variables.i_beta_component == BetaComponentLimits.TOTAL: + if self.data.physics.i_beta_component == BetaComponentLimits.TOTAL: po.ovarrf( self.outfile, "Lower limit on volume averaged total beta (⟨β⟩>)", "(beta_vol_avg_min)", - physics_variables.beta_vol_avg_min, + self.data.physics.beta_vol_avg_min, "IP", ) - elif physics_variables.i_beta_component == BetaComponentLimits.THERMAL: + elif self.data.physics.i_beta_component == BetaComponentLimits.THERMAL: po.ovarrf( self.outfile, "Lower limit on volume averaged thermal beta (⟨βₜₕ⟩>)", "(beta_vol_avg_min)", - physics_variables.beta_vol_avg_min, + self.data.physics.beta_vol_avg_min, "IP", ) else: @@ -3782,7 +3810,7 @@ def output_beta_information(self): self.outfile, "Lower limit on volume averaged thermal + NB beta (⟨βₜₕ+βₙᵦ⟩>)", "(beta_vol_avg_min)", - physics_variables.beta_vol_avg_min, + self.data.physics.beta_vol_avg_min, "IP", ) po.ovarre( @@ -3796,43 +3824,43 @@ def output_beta_information(self): self.outfile, "Volume averaged poloidal beta (⟨βₚ⟩)", "(beta_poloidal_vol_avg)", - physics_variables.beta_poloidal_vol_avg, + self.data.physics.beta_poloidal_vol_avg, "OP ", ) po.ovarre( self.outfile, "Volume averaged toroidal beta (⟨βₜ⟩)", "(beta_toroidal_vol_avg)", - physics_variables.beta_toroidal_vol_avg, + self.data.physics.beta_toroidal_vol_avg, "OP ", ) - for i in range(len(physics_variables.beta_thermal_toroidal_profile)): + for i in range(len(self.data.physics.beta_thermal_toroidal_profile)): po.ovarre( self.mfile, f"Beta toroidal profile at point {i}", f"beta_thermal_toroidal_profile{i}", - physics_variables.beta_thermal_toroidal_profile[i], + self.data.physics.beta_thermal_toroidal_profile[i], ) po.ovarre( self.outfile, "Fast alpha beta (β_alpha)", "(beta_fast_alpha)", - physics_variables.beta_fast_alpha, + self.data.physics.beta_fast_alpha, "OP ", ) po.ovarre( self.outfile, "Neutral Beam ion beta (β_beam)", "(beta_beam)", - physics_variables.beta_beam, + self.data.physics.beta_beam, "OP ", ) po.ovarre( self.outfile, "Ratio of fast alpha and beam beta to thermal beta", "(f_beta_alpha_beam_thermal)", - physics_variables.f_beta_alpha_beam_thermal, + self.data.physics.f_beta_alpha_beam_thermal, "OP ", ) @@ -3840,21 +3868,21 @@ def output_beta_information(self): self.outfile, "Volume averaged thermal beta (⟨βₜₕ⟩)", "(beta_thermal_vol_avg)", - physics_variables.beta_thermal_vol_avg, + self.data.physics.beta_thermal_vol_avg, "OP ", ) po.ovarre( self.outfile, "Thermal poloidal beta (⟨βₚₜₕ⟩)", "(beta_thermal_poloidal_vol_avg)", - physics_variables.beta_thermal_poloidal_vol_avg, + self.data.physics.beta_thermal_poloidal_vol_avg, "OP ", ) po.ovarre( self.outfile, "Thermal toroidal beta (⟨βₜₕ⟩)", "(beta_thermal_toroidal_vol_avg)", - physics_variables.beta_thermal_toroidal_vol_avg, + self.data.physics.beta_thermal_toroidal_vol_avg, "OP ", ) @@ -3862,14 +3890,14 @@ def output_beta_information(self): self.outfile, "Poloidal beta and inverse aspect ratio (βₚε)", "(beta_poloidal_eps)", - physics_variables.beta_poloidal_eps, + self.data.physics.beta_poloidal_eps, "OP ", ) po.ovarrf( self.outfile, "Poloidal beta and inverse aspect ratio upper limit (βₚε_max)", "(beta_poloidal_eps_max)", - physics_variables.beta_poloidal_eps_max, + self.data.physics.beta_poloidal_eps_max, ) po.osubhd(self.outfile, "Normalised Beta (βₙ) Information :") @@ -3877,25 +3905,25 @@ def output_beta_information(self): self.outfile, "Maximum normalised beta model", "(i_beta_norm_max)", - physics_variables.i_beta_norm_max, + self.data.physics.i_beta_norm_max, ) po.ocmmnt( self.outfile, f"Maximum normalised beta model selected: " - f"{BetaNormMaxModel(physics_variables.i_beta_norm_max).full_name} ", + f"{BetaNormMaxModel(self.data.physics.i_beta_norm_max).full_name} ", ) po.oblnkl(self.outfile) if self.data.stellarator.istell == 0: if ( - BetaNormMaxModel(physics_variables.i_beta_norm_max) + BetaNormMaxModel(self.data.physics.i_beta_norm_max) != BetaNormMaxModel.USER_INPUT ): po.ovarrf( self.outfile, "Beta g coefficient (βₙ<)", "(beta_norm_max)", - physics_variables.beta_norm_max, + self.data.physics.beta_norm_max, "OP ", ) else: @@ -3903,20 +3931,20 @@ def output_beta_information(self): self.outfile, "Beta g coefficient (βₙ<)", "(beta_norm_max)", - physics_variables.beta_norm_max, + self.data.physics.beta_norm_max, ) po.ovarrf( self.outfile, "Normalised total beta (βₙ)", "(beta_norm_total)", - physics_variables.beta_norm_total, + self.data.physics.beta_norm_total, "OP ", ) po.ovarrf( self.outfile, "Normalised thermal beta (βₙₜₕ)", "(beta_norm_thermal) ", - physics_variables.beta_norm_thermal, + self.data.physics.beta_norm_thermal, "OP ", ) @@ -3924,7 +3952,7 @@ def output_beta_information(self): self.outfile, "Normalised toroidal beta (βₙₜ)", "(beta_norm_toroidal) ", - physics_variables.beta_norm_toroidal, + self.data.physics.beta_norm_toroidal, "OP ", ) @@ -3932,7 +3960,7 @@ def output_beta_information(self): self.outfile, "Normalised poloidal beta (βₙₚ)", "(beta_norm_poloidal) ", - physics_variables.beta_norm_poloidal, + self.data.physics.beta_norm_poloidal, "OP ", ) @@ -3941,35 +3969,35 @@ def output_beta_information(self): self.outfile, "J. Wesson normalised beta upper limit (βₙ<)", "(beta_norm_max_wesson) ", - physics_variables.beta_norm_max_wesson, + self.data.physics.beta_norm_max_wesson, "OP ", ) po.ovarrf( self.outfile, "Original normalised beta upper limit (βₙ<)", "(beta_norm_max_original_scaling) ", - physics_variables.beta_norm_max_original_scaling, + self.data.physics.beta_norm_max_original_scaling, "OP ", ) po.ovarrf( self.outfile, "J. Menard normalised beta upper limit (βₙ<)", "(beta_norm_max_menard) ", - physics_variables.beta_norm_max_menard, + self.data.physics.beta_norm_max_menard, "OP ", ) po.ovarrf( self.outfile, - "E. Thloreus normalised beta upper limit (βₙ<)", - "(beta_norm_max_thloreus) ", - physics_variables.beta_norm_max_thloreus, + "E. tholerus normalised beta upper limit (βₙ<)", + "(beta_norm_max_tholerus) ", + self.data.physics.beta_norm_max_tholerus, "OP ", ) po.ovarrf( self.outfile, "R. Stambaugh normalised beta upper limit (βₙ<)", "(beta_norm_max_stambaugh) ", - physics_variables.beta_norm_max_stambaugh, + self.data.physics.beta_norm_max_stambaugh, "OP ", ) @@ -3978,7 +4006,7 @@ def output_beta_information(self): self.outfile, "Plasma thermal energy derived from thermal beta (J)", "(e_plasma_beta_thermal) ", - physics_variables.e_plasma_beta_thermal, + self.data.physics.e_plasma_beta_thermal, "OP", ) @@ -3986,7 +4014,7 @@ def output_beta_information(self): self.outfile, "Plasma thermal energy derived from the total beta (J)", "(e_plasma_beta)", - physics_variables.e_plasma_beta, + self.data.physics.e_plasma_beta, "OP", ) @@ -4013,13 +4041,16 @@ def full_name(self): return self._full_name_ -class PlasmaInductance: +class PlasmaInductance(Model): """Class to hold plasma inductance calculations for plasma processing.""" def __init__(self): self.outfile = constants.NOUT self.mfile = constants.MFILE + def output(self): + """This model has no output""" + def run(self): """Calculate plasma inductance parameters. @@ -4029,39 +4060,38 @@ def run(self): If an illegal value of i_ind_plasma_internal_norm is provided. """ - physics_variables.ind_plasma_internal_norm_wesson = ( - self.calculate_internal_inductance_wesson(alphaj=physics_variables.alphaj) + self.data.physics.ind_plasma_internal_norm_wesson = ( + self.calculate_internal_inductance_wesson(alphaj=self.data.physics.alphaj) ) # Spherical Tokamak relation for internal inductance # Menard et al. (2016), Nuclear Fusion, 56, 106023 - physics_variables.ind_plasma_internal_norm_menard = ( - self.calculate_internal_inductance_menard(kappa=physics_variables.kappa) + self.data.physics.ind_plasma_internal_norm_menard = ( + self.calculate_internal_inductance_menard(kappa=self.data.physics.kappa) ) - physics_variables.ind_plasma_internal_norm_iter_3 = self.calculate_normalised_internal_inductance_iter_3( - b_plasma_poloidal_vol_avg=physics_variables.b_plasma_surface_poloidal_average, - c_plasma=physics_variables.plasma_current, - vol_plasma=physics_variables.vol_plasma, - rmajor=physics_variables.rmajor, + self.data.physics.ind_plasma_internal_norm_iter_3 = self.calculate_normalised_internal_inductance_iter_3( + b_plasma_poloidal_vol_avg=self.data.physics.b_plasma_surface_poloidal_average, + c_plasma=self.data.physics.plasma_current, + vol_plasma=self.data.physics.vol_plasma, + rmajor=self.data.physics.rmajor, ) # Calculate ind_plasma_internal_norm based on i_ind_plasma_internal_norm try: model = IndInternalNormModel( - int(physics_variables.i_ind_plasma_internal_norm) + int(self.data.physics.i_ind_plasma_internal_norm) ) - physics_variables.ind_plasma_internal_norm = ( + self.data.physics.ind_plasma_internal_norm = ( self.get_ind_internal_norm_value(model) ) except ValueError: raise ProcessValueError( "Illegal value of i_ind_plasma_internal_norm", - i_ind_plasma_internal_norm=physics_variables.i_ind_plasma_internal_norm, + i_ind_plasma_internal_norm=self.data.physics.i_ind_plasma_internal_norm, ) from None - @staticmethod - def get_ind_internal_norm_value(model: IndInternalNormModel) -> float: + def get_ind_internal_norm_value(self, model: IndInternalNormModel) -> float: """Get the normalised internal inductance (l_i) for the specified model. Parameters @@ -4069,9 +4099,9 @@ def get_ind_internal_norm_value(model: IndInternalNormModel) -> float: model: IndInternalNormModel : """ model_map = { - IndInternalNormModel.USER_INPUT: physics_variables.ind_plasma_internal_norm, - IndInternalNormModel.WESSON: physics_variables.ind_plasma_internal_norm_wesson, - IndInternalNormModel.MENARD: physics_variables.ind_plasma_internal_norm_menard, + IndInternalNormModel.USER_INPUT: self.data.physics.ind_plasma_internal_norm, + IndInternalNormModel.WESSON: self.data.physics.ind_plasma_internal_norm_wesson, + IndInternalNormModel.MENARD: self.data.physics.ind_plasma_internal_norm_menard, } return model_map[model] @@ -4323,7 +4353,7 @@ def output_volt_second_information(self): self.outfile, "Total plasma volt-seconds required for pulse (Wb)", "(vs_plasma_total_required)", - physics_variables.vs_plasma_total_required, + self.data.physics.vs_plasma_total_required, "OP ", ) po.oblnkl(self.outfile) @@ -4331,42 +4361,42 @@ def output_volt_second_information(self): self.outfile, "Total plasma inductive flux consumption for plasma current ramp-up (Wb)", "(vs_plasma_ind_ramp)", - physics_variables.vs_plasma_ind_ramp, + self.data.physics.vs_plasma_ind_ramp, "OP ", ) po.ovarre( self.outfile, "Plasma resistive flux consumption for plasma current ramp-up (Wb)", "(vs_plasma_res_ramp)", - physics_variables.vs_plasma_res_ramp, + self.data.physics.vs_plasma_res_ramp, "OP ", ) po.ovarre( self.outfile, "Total flux consumption for plasma current ramp-up (Wb)", "(vs_plasma_ramp_required)", - physics_variables.vs_plasma_ramp_required, + self.data.physics.vs_plasma_ramp_required, "OP ", ) po.ovarrf( self.outfile, "Ejima coefficient (Cₑⱼᵢₘₐ)", "(ejima_coeff)", - physics_variables.ejima_coeff, + self.data.physics.ejima_coeff, ) po.oblnkl(self.outfile) po.ovarre( self.outfile, "Internal plasma V-s", "(vs_plasma_internal)", - physics_variables.vs_plasma_internal, + self.data.physics.vs_plasma_internal, ) po.ovarre( self.outfile, "Plasma volt-seconds needed for flat-top (heat + burn times) (Wb)", "(vs_plasma_burn_required)", - physics_variables.vs_plasma_burn_required, + self.data.physics.vs_plasma_burn_required, "OP ", ) @@ -4374,21 +4404,21 @@ def output_volt_second_information(self): self.outfile, "Plasma loop voltage during burn (Vₗₒₒₚ) (V)", "(v_plasma_loop_burn)", - physics_variables.v_plasma_loop_burn, + self.data.physics.v_plasma_loop_burn, "OP ", ) po.ovarrf( self.outfile, "Coefficient for sawtooth effects on burn V-s requirement", "(csawth)", - physics_variables.csawth, + self.data.physics.csawth, ) po.oblnkl(self.outfile) po.ovarre( self.outfile, "Plasma resistance (Ω) (ohm)", "(res_plasma)", - physics_variables.res_plasma, + self.data.physics.res_plasma, "OP ", ) @@ -4396,21 +4426,21 @@ def output_volt_second_information(self): self.outfile, "Plasma resistive diffusion time (τᵣₑₛ) (s)", "(t_plasma_res_diffusion)", - physics_variables.t_plasma_res_diffusion, + self.data.physics.t_plasma_res_diffusion, "OP ", ) po.ovarre( self.outfile, "Plasma inductance (H)", "(ind_plasma)", - physics_variables.ind_plasma, + self.data.physics.ind_plasma, "OP ", ) po.ovarre( self.outfile, "Plasma magnetic energy stored (J)", "(e_plasma_magnetic_stored)", - physics_variables.e_plasma_magnetic_stored, + self.data.physics.e_plasma_magnetic_stored, "OP ", ) po.oblnkl(self.outfile) @@ -4419,18 +4449,18 @@ def output_volt_second_information(self): self.outfile, "Normalised internal inductance model used", "(i_ind_plasma_internal_norm)", - physics_variables.i_ind_plasma_internal_norm, + self.data.physics.i_ind_plasma_internal_norm, ) po.ocmmnt( self.outfile, f"Normalised internal inductance model selected: " - f"{IndInternalNormModel(physics_variables.i_ind_plasma_internal_norm).full_name} ", + f"{IndInternalNormModel(self.data.physics.i_ind_plasma_internal_norm).full_name} ", ) po.ovarrf( self.outfile, "Plasma normalised internal inductance (lᵢ)", "(ind_plasma_internal_norm)", - physics_variables.ind_plasma_internal_norm, + self.data.physics.ind_plasma_internal_norm, "OP ", ) po.oblnkl(self.outfile) @@ -4440,21 +4470,21 @@ def output_volt_second_information(self): self.outfile, "J. Wesson plasma normalised internal inductance", "(ind_plasma_internal_norm_wesson)", - physics_variables.ind_plasma_internal_norm_wesson, + self.data.physics.ind_plasma_internal_norm_wesson, "OP ", ) po.ovarrf( self.outfile, "J. Menard plasma normalised internal inductance", "(ind_plasma_internal_norm_menard)", - physics_variables.ind_plasma_internal_norm_menard, + self.data.physics.ind_plasma_internal_norm_menard, "OP ", ) po.ovarrf( self.outfile, "ITER lᵢ(3) plasma normalised internal inductance", "(ind_plasma_internal_norm_iter_3)", - physics_variables.ind_plasma_internal_norm_iter_3, + self.data.physics.ind_plasma_internal_norm_iter_3, "OP ", ) @@ -4480,12 +4510,12 @@ def run(self): # Debye length calculation # --------------------------- - physics_variables.len_plasma_debye_electron_vol_avg = self.calculate_debye_length( - temp_plasma_species_kev=physics_variables.temp_plasma_electron_vol_avg_kev, - nd_plasma_species=physics_variables.nd_plasma_electrons_vol_avg, + self.data.physics.len_plasma_debye_electron_vol_avg = self.calculate_debye_length( + temp_plasma_species_kev=self.data.physics.temp_plasma_electron_vol_avg_kev, + nd_plasma_species=self.data.physics.nd_plasma_electrons_vol_avg, ) - physics_variables.len_plasma_debye_electron_profile = ( + self.data.physics.len_plasma_debye_electron_profile = ( self.calculate_debye_length( temp_plasma_species_kev=self.plasma_profile.teprofile.profile_y, nd_plasma_species=self.plasma_profile.neprofile.profile_y, @@ -4496,7 +4526,7 @@ def run(self): # Particle relativistic speeds # ============================ - physics_variables.vel_plasma_electron_profile = ( + self.data.physics.vel_plasma_electron_profile = ( self.calculate_relativistic_particle_speed( e_kinetic=self.plasma_profile.teprofile.profile_y * constants.KILOELECTRON_VOLT, @@ -4504,69 +4534,69 @@ def run(self): ) ) - physics_variables.vel_plasma_electron_vol_avg = ( + self.data.physics.vel_plasma_electron_vol_avg = ( self.calculate_relativistic_particle_speed( - e_kinetic=physics_variables.temp_plasma_electron_vol_avg_kev + e_kinetic=self.data.physics.temp_plasma_electron_vol_avg_kev * constants.KILOELECTRON_VOLT, mass=constants.ELECTRON_MASS, ) ) - physics_variables.vel_plasma_deuteron_profile = ( + self.data.physics.vel_plasma_deuteron_profile = ( self.calculate_relativistic_particle_speed( e_kinetic=self.plasma_profile.teprofile.profile_y * constants.KILOELECTRON_VOLT - * physics_variables.f_temp_plasma_ion_electron, + * self.data.physics.f_temp_plasma_ion_electron, mass=constants.DEUTERON_MASS, ) ) - physics_variables.vel_plasma_deuteron_vol_avg = ( + self.data.physics.vel_plasma_deuteron_vol_avg = ( self.calculate_relativistic_particle_speed( - e_kinetic=physics_variables.temp_plasma_electron_vol_avg_kev + e_kinetic=self.data.physics.temp_plasma_electron_vol_avg_kev * constants.KILOELECTRON_VOLT - * physics_variables.f_temp_plasma_ion_electron, + * self.data.physics.f_temp_plasma_ion_electron, mass=constants.DEUTERON_MASS, ) ) - physics_variables.vel_plasma_triton_profile = ( + self.data.physics.vel_plasma_triton_profile = ( self.calculate_relativistic_particle_speed( e_kinetic=self.plasma_profile.teprofile.profile_y * constants.KILOELECTRON_VOLT - * physics_variables.f_temp_plasma_ion_electron, + * self.data.physics.f_temp_plasma_ion_electron, mass=constants.TRITON_MASS, ) ) - physics_variables.vel_plasma_triton_vol_avg = ( + self.data.physics.vel_plasma_triton_vol_avg = ( self.calculate_relativistic_particle_speed( - e_kinetic=physics_variables.temp_plasma_electron_vol_avg_kev + e_kinetic=self.data.physics.temp_plasma_electron_vol_avg_kev * constants.KILOELECTRON_VOLT - * physics_variables.f_temp_plasma_ion_electron, + * self.data.physics.f_temp_plasma_ion_electron, mass=constants.TRITON_MASS, ) ) - physics_variables.vel_plasma_alpha_thermal_profile = ( + self.data.physics.vel_plasma_alpha_thermal_profile = ( self.calculate_relativistic_particle_speed( e_kinetic=self.plasma_profile.teprofile.profile_y * constants.KILOELECTRON_VOLT - * physics_variables.f_temp_plasma_ion_electron, + * self.data.physics.f_temp_plasma_ion_electron, mass=constants.ALPHA_MASS, ) ) - physics_variables.vel_plasma_alpha_thermal_vol_avg = ( + self.data.physics.vel_plasma_alpha_thermal_vol_avg = ( self.calculate_relativistic_particle_speed( - e_kinetic=physics_variables.temp_plasma_electron_vol_avg_kev + e_kinetic=self.data.physics.temp_plasma_electron_vol_avg_kev * constants.KILOELECTRON_VOLT - * physics_variables.f_temp_plasma_ion_electron, + * self.data.physics.f_temp_plasma_ion_electron, mass=constants.ALPHA_MASS, ) ) - physics_variables.vel_plasma_alpha_birth = ( + self.data.physics.vel_plasma_alpha_birth = ( self.calculate_relativistic_particle_speed( e_kinetic=constants.DT_ALPHA_ENERGY, mass=constants.ALPHA_MASS, @@ -4577,13 +4607,13 @@ def run(self): # Plasma frequencies # ============================ - physics_variables.freq_plasma_electron_vol_avg = self.calculate_plasma_frequency( - nd_particle=physics_variables.nd_plasma_electrons_vol_avg, + self.data.physics.freq_plasma_electron_vol_avg = self.calculate_plasma_frequency( + nd_particle=self.data.physics.nd_plasma_electrons_vol_avg, m_particle=constants.ELECTRON_MASS, z_particle=1.0, ) - physics_variables.freq_plasma_electron_profile = self.calculate_plasma_frequency( + self.data.physics.freq_plasma_electron_profile = self.calculate_plasma_frequency( nd_particle=self.plasma_profile.neprofile.profile_y, m_particle=constants.ELECTRON_MASS, z_particle=1.0, @@ -4593,49 +4623,49 @@ def run(self): # Larmor frequencies # ============================ - physics_variables.freq_plasma_larmor_toroidal_electron_vol_avg = ( + self.data.physics.freq_plasma_larmor_toroidal_electron_vol_avg = ( self.calculate_larmor_frequency( - b_field=physics_variables.b_plasma_toroidal_on_axis, + b_field=self.data.physics.b_plasma_toroidal_on_axis, m_particle=constants.ELECTRON_MASS, z_particle=1.0, ) ) - physics_variables.freq_plasma_larmor_toroidal_electron_profile = ( + self.data.physics.freq_plasma_larmor_toroidal_electron_profile = ( self.calculate_larmor_frequency( - b_field=physics_variables.b_plasma_toroidal_profile, + b_field=self.data.physics.b_plasma_toroidal_profile, m_particle=constants.ELECTRON_MASS, z_particle=1.0, ) ) - physics_variables.freq_plasma_larmor_toroidal_deuteron_vol_avg = ( + self.data.physics.freq_plasma_larmor_toroidal_deuteron_vol_avg = ( self.calculate_larmor_frequency( - b_field=physics_variables.b_plasma_toroidal_on_axis, + b_field=self.data.physics.b_plasma_toroidal_on_axis, m_particle=constants.DEUTERON_MASS, z_particle=1.0, ) ) - physics_variables.freq_plasma_larmor_toroidal_deuteron_profile = ( + self.data.physics.freq_plasma_larmor_toroidal_deuteron_profile = ( self.calculate_larmor_frequency( - b_field=physics_variables.b_plasma_toroidal_profile, + b_field=self.data.physics.b_plasma_toroidal_profile, m_particle=constants.DEUTERON_MASS, z_particle=1.0, ) ) - physics_variables.freq_plasma_larmor_toroidal_triton_vol_avg = ( + self.data.physics.freq_plasma_larmor_toroidal_triton_vol_avg = ( self.calculate_larmor_frequency( - b_field=physics_variables.b_plasma_toroidal_on_axis, + b_field=self.data.physics.b_plasma_toroidal_on_axis, m_particle=constants.TRITON_MASS, z_particle=1.0, ) ) - physics_variables.freq_plasma_larmor_toroidal_triton_profile = ( + self.data.physics.freq_plasma_larmor_toroidal_triton_profile = ( self.calculate_larmor_frequency( - b_field=physics_variables.b_plasma_toroidal_profile, + b_field=self.data.physics.b_plasma_toroidal_profile, m_particle=constants.TRITON_MASS, z_particle=1.0, ) @@ -4645,17 +4675,17 @@ def run(self): # Upper hybrid frequencies # ============================ - physics_variables.freq_plasma_upper_hybrid_vol_avg = self.calculate_upper_hybrid_frequency( - freq_plasma=physics_variables.freq_plasma_electron_vol_avg, - freq_larmor=physics_variables.freq_plasma_larmor_toroidal_electron_vol_avg, + self.data.physics.freq_plasma_upper_hybrid_vol_avg = self.calculate_upper_hybrid_frequency( + freq_plasma=self.data.physics.freq_plasma_electron_vol_avg, + freq_larmor=self.data.physics.freq_plasma_larmor_toroidal_electron_vol_avg, ) - physics_variables.freq_plasma_upper_hybrid_profile = self.calculate_upper_hybrid_frequency( + self.data.physics.freq_plasma_upper_hybrid_profile = self.calculate_upper_hybrid_frequency( freq_plasma=np.concatenate([ - physics_variables.freq_plasma_electron_profile[::-1], - physics_variables.freq_plasma_electron_profile, + self.data.physics.freq_plasma_electron_profile[::-1], + self.data.physics.freq_plasma_electron_profile, ]), - freq_larmor=physics_variables.freq_plasma_larmor_toroidal_electron_profile, + freq_larmor=self.data.physics.freq_plasma_larmor_toroidal_electron_profile, ) # ============================ @@ -4665,35 +4695,35 @@ def run(self): # Since isotropic (v⟂)² = 2(v)² for a Maxwellian distribution, # we can use the total velocity to calculate the Larmor radius for an isotropic # profile - physics_variables.radius_plasma_deuteron_toroidal_larmor_isotropic_vol_avg = self.calculate_larmor_radius( - vel_perp=np.sqrt(2 * physics_variables.vel_plasma_deuteron_vol_avg**2), - freq_larmor=physics_variables.freq_plasma_larmor_toroidal_deuteron_vol_avg + self.data.physics.radius_plasma_deuteron_toroidal_larmor_isotropic_vol_avg = self.calculate_larmor_radius( + vel_perp=np.sqrt(2 * self.data.physics.vel_plasma_deuteron_vol_avg**2), + freq_larmor=self.data.physics.freq_plasma_larmor_toroidal_deuteron_vol_avg * (2 * np.pi), ) # Since isotropic (v⟂)² = 2(v)² for a Maxwellian distribution, # we can use the total velocity to calculate the Larmor radius for an isotropic # profile - physics_variables.radius_plasma_deuteron_toroidal_larmor_isotropic_profile = self.calculate_larmor_radius( + self.data.physics.radius_plasma_deuteron_toroidal_larmor_isotropic_profile = self.calculate_larmor_radius( vel_perp=np.sqrt( 2 * np.concatenate([ - physics_variables.vel_plasma_deuteron_profile[::-1], - physics_variables.vel_plasma_deuteron_profile, + self.data.physics.vel_plasma_deuteron_profile[::-1], + self.data.physics.vel_plasma_deuteron_profile, ]) ** 2 ), - freq_larmor=physics_variables.freq_plasma_larmor_toroidal_deuteron_profile + freq_larmor=self.data.physics.freq_plasma_larmor_toroidal_deuteron_profile * (2 * np.pi), ) # Since isotropic (v⟂)² = 2(v)² for a Maxwellian distribution, # we can use the total velocity to calculate the Larmor radius for an isotropic # profile - physics_variables.radius_plasma_triton_toroidal_larmor_isotropic_vol_avg = ( + self.data.physics.radius_plasma_triton_toroidal_larmor_isotropic_vol_avg = ( self.calculate_larmor_radius( - vel_perp=np.sqrt(2 * physics_variables.vel_plasma_triton_vol_avg**2), - freq_larmor=physics_variables.freq_plasma_larmor_toroidal_triton_vol_avg + vel_perp=np.sqrt(2 * self.data.physics.vel_plasma_triton_vol_avg**2), + freq_larmor=self.data.physics.freq_plasma_larmor_toroidal_triton_vol_avg * (2 * np.pi), ) ) @@ -4701,17 +4731,17 @@ def run(self): # Since isotropic (v⟂)² = 2(v)² for a Maxwellian distribution, # we can use the total velocity to calculate the Larmor radius for an isotropic # profile - physics_variables.radius_plasma_triton_toroidal_larmor_isotropic_profile = ( + self.data.physics.radius_plasma_triton_toroidal_larmor_isotropic_profile = ( self.calculate_larmor_radius( vel_perp=np.sqrt( 2 * np.concatenate([ - physics_variables.vel_plasma_triton_profile[::-1], - physics_variables.vel_plasma_triton_profile, + self.data.physics.vel_plasma_triton_profile[::-1], + self.data.physics.vel_plasma_triton_profile, ]) ** 2 ), - freq_larmor=physics_variables.freq_plasma_larmor_toroidal_triton_profile + freq_larmor=self.data.physics.freq_plasma_larmor_toroidal_triton_profile * (2 * np.pi), ) ) @@ -4720,9 +4750,9 @@ def run(self): # Coulomb logarithm # ============================ - physics_variables.plasma_coulomb_log_electron_electron_vol_avg = ( + self.data.physics.plasma_coulomb_log_electron_electron_vol_avg = ( self.calculate_coulomb_log_from_impact( - impact_param_max=physics_variables.len_plasma_debye_electron_vol_avg, + impact_param_max=self.data.physics.len_plasma_debye_electron_vol_avg, impact_param_min=max( self.calculate_classical_distance_of_closest_approach( charge1=1, @@ -4732,8 +4762,8 @@ def run(self): mass2=constants.ELECTRON_MASS, ), vel_relative=self.calculate_average_relative_velocity( - velocity_1=physics_variables.vel_plasma_electron_vol_avg, - velocity_2=physics_variables.vel_plasma_electron_vol_avg, + velocity_1=self.data.physics.vel_plasma_electron_vol_avg, + velocity_2=self.data.physics.vel_plasma_electron_vol_avg, ), ), self.calculate_debroglie_wavelength( @@ -4742,17 +4772,17 @@ def run(self): mass2=constants.ELECTRON_MASS, ), velocity=self.calculate_average_relative_velocity( - velocity_1=physics_variables.vel_plasma_electron_vol_avg, - velocity_2=physics_variables.vel_plasma_electron_vol_avg, + velocity_1=self.data.physics.vel_plasma_electron_vol_avg, + velocity_2=self.data.physics.vel_plasma_electron_vol_avg, ), ), ), ) ) - physics_variables.plasma_coulomb_log_electron_electron_profile = np.array([ + self.data.physics.plasma_coulomb_log_electron_electron_profile = np.array([ self.calculate_coulomb_log_from_impact( - impact_param_max=physics_variables.len_plasma_debye_electron_profile[i], + impact_param_max=self.data.physics.len_plasma_debye_electron_profile[i], impact_param_min=max( self.calculate_classical_distance_of_closest_approach( charge1=1, @@ -4762,8 +4792,8 @@ def run(self): mass2=constants.ELECTRON_MASS, ), vel_relative=self.calculate_average_relative_velocity( - velocity_1=physics_variables.vel_plasma_electron_profile[i], - velocity_2=physics_variables.vel_plasma_electron_profile[i], + velocity_1=self.data.physics.vel_plasma_electron_profile[i], + velocity_2=self.data.physics.vel_plasma_electron_profile[i], ), ), self.calculate_debroglie_wavelength( @@ -4772,18 +4802,18 @@ def run(self): mass2=constants.ELECTRON_MASS, ), velocity=self.calculate_average_relative_velocity( - velocity_1=physics_variables.vel_plasma_electron_profile[i], - velocity_2=physics_variables.vel_plasma_electron_profile[i], + velocity_1=self.data.physics.vel_plasma_electron_profile[i], + velocity_2=self.data.physics.vel_plasma_electron_profile[i], ), ), ), ) - for i in range(len(physics_variables.len_plasma_debye_electron_profile)) + for i in range(len(self.data.physics.len_plasma_debye_electron_profile)) ]) - physics_variables.plasma_coulomb_log_electron_deuteron_vol_avg = ( + self.data.physics.plasma_coulomb_log_electron_deuteron_vol_avg = ( self.calculate_coulomb_log_from_impact( - impact_param_max=physics_variables.len_plasma_debye_electron_vol_avg, + impact_param_max=self.data.physics.len_plasma_debye_electron_vol_avg, impact_param_min=max( self.calculate_classical_distance_of_closest_approach( charge1=1, @@ -4793,8 +4823,8 @@ def run(self): mass2=constants.DEUTERON_MASS, ), vel_relative=self.calculate_average_relative_velocity( - velocity_1=physics_variables.vel_plasma_electron_vol_avg, - velocity_2=physics_variables.vel_plasma_deuteron_vol_avg, + velocity_1=self.data.physics.vel_plasma_electron_vol_avg, + velocity_2=self.data.physics.vel_plasma_deuteron_vol_avg, ), ), self.calculate_debroglie_wavelength( @@ -4803,17 +4833,17 @@ def run(self): mass2=constants.DEUTERON_MASS, ), velocity=self.calculate_average_relative_velocity( - velocity_1=physics_variables.vel_plasma_electron_vol_avg, - velocity_2=physics_variables.vel_plasma_deuteron_vol_avg, + velocity_1=self.data.physics.vel_plasma_electron_vol_avg, + velocity_2=self.data.physics.vel_plasma_deuteron_vol_avg, ), ), ), ) ) - physics_variables.plasma_coulomb_log_electron_deuteron_profile = np.array([ + self.data.physics.plasma_coulomb_log_electron_deuteron_profile = np.array([ self.calculate_coulomb_log_from_impact( - impact_param_max=physics_variables.len_plasma_debye_electron_profile[i], + impact_param_max=self.data.physics.len_plasma_debye_electron_profile[i], impact_param_min=max( self.calculate_classical_distance_of_closest_approach( charge1=1, @@ -4823,8 +4853,8 @@ def run(self): mass2=constants.ELECTRON_MASS, ), vel_relative=self.calculate_average_relative_velocity( - velocity_1=physics_variables.vel_plasma_deuteron_profile[i], - velocity_2=physics_variables.vel_plasma_electron_profile[i], + velocity_1=self.data.physics.vel_plasma_deuteron_profile[i], + velocity_2=self.data.physics.vel_plasma_electron_profile[i], ), ), self.calculate_debroglie_wavelength( @@ -4833,18 +4863,18 @@ def run(self): mass2=constants.ELECTRON_MASS, ), velocity=self.calculate_average_relative_velocity( - velocity_1=physics_variables.vel_plasma_deuteron_profile[i], - velocity_2=physics_variables.vel_plasma_electron_profile[i], + velocity_1=self.data.physics.vel_plasma_deuteron_profile[i], + velocity_2=self.data.physics.vel_plasma_electron_profile[i], ), ), ), ) - for i in range(len(physics_variables.len_plasma_debye_electron_profile)) + for i in range(len(self.data.physics.len_plasma_debye_electron_profile)) ]) - physics_variables.plasma_coulomb_log_electron_triton_vol_avg = ( + self.data.physics.plasma_coulomb_log_electron_triton_vol_avg = ( self.calculate_coulomb_log_from_impact( - impact_param_max=physics_variables.len_plasma_debye_electron_vol_avg, + impact_param_max=self.data.physics.len_plasma_debye_electron_vol_avg, impact_param_min=max( self.calculate_classical_distance_of_closest_approach( charge1=1, @@ -4854,8 +4884,8 @@ def run(self): mass2=constants.TRITON_MASS, ), vel_relative=self.calculate_average_relative_velocity( - velocity_1=physics_variables.vel_plasma_electron_vol_avg, - velocity_2=physics_variables.vel_plasma_triton_vol_avg, + velocity_1=self.data.physics.vel_plasma_electron_vol_avg, + velocity_2=self.data.physics.vel_plasma_triton_vol_avg, ), ), self.calculate_debroglie_wavelength( @@ -4864,17 +4894,17 @@ def run(self): mass2=constants.TRITON_MASS, ), velocity=self.calculate_average_relative_velocity( - velocity_1=physics_variables.vel_plasma_electron_vol_avg, - velocity_2=physics_variables.vel_plasma_triton_vol_avg, + velocity_1=self.data.physics.vel_plasma_electron_vol_avg, + velocity_2=self.data.physics.vel_plasma_triton_vol_avg, ), ), ), ) ) - physics_variables.plasma_coulomb_log_electron_triton_profile = np.array([ + self.data.physics.plasma_coulomb_log_electron_triton_profile = np.array([ self.calculate_coulomb_log_from_impact( - impact_param_max=physics_variables.len_plasma_debye_electron_profile[i], + impact_param_max=self.data.physics.len_plasma_debye_electron_profile[i], impact_param_min=max( self.calculate_classical_distance_of_closest_approach( charge1=1, @@ -4884,8 +4914,8 @@ def run(self): mass2=constants.ELECTRON_MASS, ), vel_relative=self.calculate_average_relative_velocity( - velocity_1=physics_variables.vel_plasma_triton_profile[i], - velocity_2=physics_variables.vel_plasma_electron_profile[i], + velocity_1=self.data.physics.vel_plasma_triton_profile[i], + velocity_2=self.data.physics.vel_plasma_electron_profile[i], ), ), self.calculate_debroglie_wavelength( @@ -4894,18 +4924,18 @@ def run(self): mass2=constants.ELECTRON_MASS, ), velocity=self.calculate_average_relative_velocity( - velocity_1=physics_variables.vel_plasma_triton_profile[i], - velocity_2=physics_variables.vel_plasma_electron_profile[i], + velocity_1=self.data.physics.vel_plasma_triton_profile[i], + velocity_2=self.data.physics.vel_plasma_electron_profile[i], ), ), ), ) - for i in range(len(physics_variables.len_plasma_debye_electron_profile)) + for i in range(len(self.data.physics.len_plasma_debye_electron_profile)) ]) - physics_variables.plasma_coulomb_log_deuteron_triton_vol_avg = ( + self.data.physics.plasma_coulomb_log_deuteron_triton_vol_avg = ( self.calculate_coulomb_log_from_impact( - impact_param_max=physics_variables.len_plasma_debye_electron_vol_avg, + impact_param_max=self.data.physics.len_plasma_debye_electron_vol_avg, impact_param_min=max( self.calculate_classical_distance_of_closest_approach( charge1=1, @@ -4915,8 +4945,8 @@ def run(self): mass2=constants.TRITON_MASS, ), vel_relative=self.calculate_average_relative_velocity( - velocity_1=physics_variables.vel_plasma_deuteron_vol_avg, - velocity_2=physics_variables.vel_plasma_triton_vol_avg, + velocity_1=self.data.physics.vel_plasma_deuteron_vol_avg, + velocity_2=self.data.physics.vel_plasma_triton_vol_avg, ), ), self.calculate_debroglie_wavelength( @@ -4925,17 +4955,17 @@ def run(self): mass2=constants.TRITON_MASS, ), velocity=self.calculate_average_relative_velocity( - velocity_1=physics_variables.vel_plasma_deuteron_vol_avg, - velocity_2=physics_variables.vel_plasma_triton_vol_avg, + velocity_1=self.data.physics.vel_plasma_deuteron_vol_avg, + velocity_2=self.data.physics.vel_plasma_triton_vol_avg, ), ), ), ) ) - physics_variables.plasma_coulomb_log_deuteron_triton_profile = np.array([ + self.data.physics.plasma_coulomb_log_deuteron_triton_profile = np.array([ self.calculate_coulomb_log_from_impact( - impact_param_max=physics_variables.len_plasma_debye_electron_profile[i], + impact_param_max=self.data.physics.len_plasma_debye_electron_profile[i], impact_param_min=max( self.calculate_classical_distance_of_closest_approach( charge1=1, @@ -4945,8 +4975,8 @@ def run(self): mass2=constants.DEUTERON_MASS, ), vel_relative=self.calculate_average_relative_velocity( - velocity_1=physics_variables.vel_plasma_triton_profile[i], - velocity_2=physics_variables.vel_plasma_deuteron_profile[i], + velocity_1=self.data.physics.vel_plasma_triton_profile[i], + velocity_2=self.data.physics.vel_plasma_deuteron_profile[i], ), ), self.calculate_debroglie_wavelength( @@ -4955,17 +4985,17 @@ def run(self): mass2=constants.DEUTERON_MASS, ), velocity=self.calculate_average_relative_velocity( - velocity_1=physics_variables.vel_plasma_triton_profile[i], - velocity_2=physics_variables.vel_plasma_deuteron_profile[i], + velocity_1=self.data.physics.vel_plasma_triton_profile[i], + velocity_2=self.data.physics.vel_plasma_deuteron_profile[i], ), ), ), ) - for i in range(len(physics_variables.len_plasma_debye_electron_profile)) + for i in range(len(self.data.physics.len_plasma_debye_electron_profile)) ]) - physics_variables.plasma_coulomb_log_electron_alpha_thermal_vol_avg = self.calculate_coulomb_log_from_impact( - impact_param_max=physics_variables.len_plasma_debye_electron_vol_avg, + self.data.physics.plasma_coulomb_log_electron_alpha_thermal_vol_avg = self.calculate_coulomb_log_from_impact( + impact_param_max=self.data.physics.len_plasma_debye_electron_vol_avg, impact_param_min=max( self.calculate_classical_distance_of_closest_approach( charge1=1, @@ -4975,8 +5005,8 @@ def run(self): mass2=constants.ALPHA_MASS, ), vel_relative=self.calculate_average_relative_velocity( - velocity_1=physics_variables.vel_plasma_electron_vol_avg, - velocity_2=physics_variables.vel_plasma_alpha_thermal_vol_avg, + velocity_1=self.data.physics.vel_plasma_electron_vol_avg, + velocity_2=self.data.physics.vel_plasma_alpha_thermal_vol_avg, ), ), self.calculate_debroglie_wavelength( @@ -4985,16 +5015,16 @@ def run(self): mass2=constants.ALPHA_MASS, ), velocity=self.calculate_average_relative_velocity( - velocity_1=physics_variables.vel_plasma_electron_vol_avg, - velocity_2=physics_variables.vel_plasma_alpha_thermal_vol_avg, + velocity_1=self.data.physics.vel_plasma_electron_vol_avg, + velocity_2=self.data.physics.vel_plasma_alpha_thermal_vol_avg, ), ), ), ) - physics_variables.plasma_coulomb_log_electron_alpha_thermal_profile = np.array([ + self.data.physics.plasma_coulomb_log_electron_alpha_thermal_profile = np.array([ self.calculate_coulomb_log_from_impact( - impact_param_max=physics_variables.len_plasma_debye_electron_profile[i], + impact_param_max=self.data.physics.len_plasma_debye_electron_profile[i], impact_param_min=max( self.calculate_classical_distance_of_closest_approach( charge1=1, @@ -5004,8 +5034,8 @@ def run(self): mass2=constants.ALPHA_MASS, ), vel_relative=self.calculate_average_relative_velocity( - velocity_1=physics_variables.vel_plasma_electron_profile[i], - velocity_2=physics_variables.vel_plasma_alpha_thermal_profile[ + velocity_1=self.data.physics.vel_plasma_electron_profile[i], + velocity_2=self.data.physics.vel_plasma_alpha_thermal_profile[ i ], ), @@ -5016,112 +5046,112 @@ def run(self): mass2=constants.ALPHA_MASS, ), velocity=self.calculate_average_relative_velocity( - velocity_1=physics_variables.vel_plasma_electron_profile[i], - velocity_2=physics_variables.vel_plasma_alpha_thermal_profile[ + velocity_1=self.data.physics.vel_plasma_electron_profile[i], + velocity_2=self.data.physics.vel_plasma_alpha_thermal_profile[ i ], ), ), ), ) - for i in range(len(physics_variables.len_plasma_debye_electron_profile)) + for i in range(len(self.data.physics.len_plasma_debye_electron_profile)) ]) # ============================ # Collision times # ============================ - physics_variables.t_plasma_electron_electron_collision_vol_avg = self.calculate_electron_electron_collision_time( - temp_plasma_electron_kev=physics_variables.temp_plasma_electron_vol_avg_kev, - nd_plasma_electrons=physics_variables.nd_plasma_electrons_vol_avg, - plasma_coulomb_log_electron_electron=physics_variables.plasma_coulomb_log_electron_electron_vol_avg, + self.data.physics.t_plasma_electron_electron_collision_vol_avg = self.calculate_electron_electron_collision_time( + temp_plasma_electron_kev=self.data.physics.temp_plasma_electron_vol_avg_kev, + nd_plasma_electrons=self.data.physics.nd_plasma_electrons_vol_avg, + plasma_coulomb_log_electron_electron=self.data.physics.plasma_coulomb_log_electron_electron_vol_avg, ) - physics_variables.t_plasma_electron_electron_collision_profile = self.calculate_electron_electron_collision_time( + self.data.physics.t_plasma_electron_electron_collision_profile = self.calculate_electron_electron_collision_time( temp_plasma_electron_kev=self.plasma_profile.teprofile.profile_y, nd_plasma_electrons=self.plasma_profile.neprofile.profile_y, - plasma_coulomb_log_electron_electron=physics_variables.plasma_coulomb_log_electron_electron_profile, + plasma_coulomb_log_electron_electron=self.data.physics.plasma_coulomb_log_electron_electron_profile, ) - physics_variables.t_plasma_electron_deuteron_collision_vol_avg = self.calculate_electron_ion_collision_time( - temp_plasma_electron_kev=physics_variables.temp_plasma_electron_vol_avg_kev, + self.data.physics.t_plasma_electron_deuteron_collision_vol_avg = self.calculate_electron_ion_collision_time( + temp_plasma_electron_kev=self.data.physics.temp_plasma_electron_vol_avg_kev, nd_plasma_ions=( - physics_variables.nd_plasma_electrons_vol_avg - * physics_variables.f_plasma_fuel_deuterium + self.data.physics.nd_plasma_electrons_vol_avg + * self.data.physics.f_plasma_fuel_deuterium * ( - physics_variables.nd_plasma_fuel_ions_vol_avg - / physics_variables.nd_plasma_electrons_vol_avg + self.data.physics.nd_plasma_fuel_ions_vol_avg + / self.data.physics.nd_plasma_electrons_vol_avg ) ), - plasma_coulomb_log_electron_ion=physics_variables.plasma_coulomb_log_electron_deuteron_vol_avg, + plasma_coulomb_log_electron_ion=self.data.physics.plasma_coulomb_log_electron_deuteron_vol_avg, n_charge_ion=1, ) - physics_variables.t_plasma_electron_deuteron_collision_profile = self.calculate_electron_ion_collision_time( + self.data.physics.t_plasma_electron_deuteron_collision_profile = self.calculate_electron_ion_collision_time( temp_plasma_electron_kev=self.plasma_profile.teprofile.profile_y, nd_plasma_ions=( self.plasma_profile.neprofile.profile_y - * physics_variables.f_plasma_fuel_deuterium + * self.data.physics.f_plasma_fuel_deuterium * ( - physics_variables.nd_plasma_fuel_ions_vol_avg - / physics_variables.nd_plasma_electrons_vol_avg + self.data.physics.nd_plasma_fuel_ions_vol_avg + / self.data.physics.nd_plasma_electrons_vol_avg ) ), - plasma_coulomb_log_electron_ion=physics_variables.plasma_coulomb_log_electron_deuteron_profile, + plasma_coulomb_log_electron_ion=self.data.physics.plasma_coulomb_log_electron_deuteron_profile, n_charge_ion=1, ) - physics_variables.t_plasma_electron_triton_collision_vol_avg = self.calculate_electron_ion_collision_time( - temp_plasma_electron_kev=physics_variables.temp_plasma_electron_vol_avg_kev, + self.data.physics.t_plasma_electron_triton_collision_vol_avg = self.calculate_electron_ion_collision_time( + temp_plasma_electron_kev=self.data.physics.temp_plasma_electron_vol_avg_kev, nd_plasma_ions=( - physics_variables.nd_plasma_electrons_vol_avg - * physics_variables.f_plasma_fuel_tritium + self.data.physics.nd_plasma_electrons_vol_avg + * self.data.physics.f_plasma_fuel_tritium * ( - physics_variables.nd_plasma_fuel_ions_vol_avg - / physics_variables.nd_plasma_electrons_vol_avg + self.data.physics.nd_plasma_fuel_ions_vol_avg + / self.data.physics.nd_plasma_electrons_vol_avg ) ), - plasma_coulomb_log_electron_ion=physics_variables.plasma_coulomb_log_electron_triton_vol_avg, + plasma_coulomb_log_electron_ion=self.data.physics.plasma_coulomb_log_electron_triton_vol_avg, n_charge_ion=1, ) - physics_variables.t_plasma_electron_triton_collision_profile = self.calculate_electron_ion_collision_time( + self.data.physics.t_plasma_electron_triton_collision_profile = self.calculate_electron_ion_collision_time( temp_plasma_electron_kev=self.plasma_profile.teprofile.profile_y, nd_plasma_ions=( self.plasma_profile.neprofile.profile_y - * physics_variables.f_plasma_fuel_tritium + * self.data.physics.f_plasma_fuel_tritium * ( - physics_variables.nd_plasma_fuel_ions_vol_avg - / physics_variables.nd_plasma_electrons_vol_avg + self.data.physics.nd_plasma_fuel_ions_vol_avg + / self.data.physics.nd_plasma_electrons_vol_avg ) ), - plasma_coulomb_log_electron_ion=physics_variables.plasma_coulomb_log_electron_triton_profile, + plasma_coulomb_log_electron_ion=self.data.physics.plasma_coulomb_log_electron_triton_profile, n_charge_ion=1, ) - physics_variables.t_plasma_electron_alpha_thermal_collision_vol_avg = self.calculate_electron_ion_collision_time( - temp_plasma_electron_kev=physics_variables.temp_plasma_electron_vol_avg_kev, + self.data.physics.t_plasma_electron_alpha_thermal_collision_vol_avg = self.calculate_electron_ion_collision_time( + temp_plasma_electron_kev=self.data.physics.temp_plasma_electron_vol_avg_kev, nd_plasma_ions=( - physics_variables.nd_plasma_electrons_vol_avg + self.data.physics.nd_plasma_electrons_vol_avg * ( - physics_variables.nd_plasma_alphas_vol_avg - / physics_variables.nd_plasma_electrons_vol_avg + self.data.physics.nd_plasma_alphas_vol_avg + / self.data.physics.nd_plasma_electrons_vol_avg ) ), - plasma_coulomb_log_electron_ion=physics_variables.plasma_coulomb_log_electron_alpha_thermal_vol_avg, + plasma_coulomb_log_electron_ion=self.data.physics.plasma_coulomb_log_electron_alpha_thermal_vol_avg, n_charge_ion=2, ) - physics_variables.t_plasma_electron_alpha_thermal_collision_profile = self.calculate_electron_ion_collision_time( + self.data.physics.t_plasma_electron_alpha_thermal_collision_profile = self.calculate_electron_ion_collision_time( temp_plasma_electron_kev=self.plasma_profile.teprofile.profile_y, nd_plasma_ions=( self.plasma_profile.neprofile.profile_y * ( - physics_variables.nd_plasma_alphas_vol_avg - / physics_variables.nd_plasma_electrons_vol_avg + self.data.physics.nd_plasma_alphas_vol_avg + / self.data.physics.nd_plasma_electrons_vol_avg ) ), - plasma_coulomb_log_electron_ion=physics_variables.plasma_coulomb_log_electron_alpha_thermal_profile, + plasma_coulomb_log_electron_ion=self.data.physics.plasma_coulomb_log_electron_alpha_thermal_profile, n_charge_ion=2, ) @@ -5129,97 +5159,97 @@ def run(self): # Collision frequencies # ============================ - physics_variables.freq_plasma_electron_electron_collision_vol_avg = ( - 1 / physics_variables.t_plasma_electron_electron_collision_vol_avg + self.data.physics.freq_plasma_electron_electron_collision_vol_avg = ( + 1 / self.data.physics.t_plasma_electron_electron_collision_vol_avg ) - physics_variables.freq_plasma_electron_electron_collision_profile = ( - 1 / physics_variables.t_plasma_electron_electron_collision_profile + self.data.physics.freq_plasma_electron_electron_collision_profile = ( + 1 / self.data.physics.t_plasma_electron_electron_collision_profile ) - physics_variables.freq_plasma_electron_deuteron_collision_vol_avg = ( - 1 / physics_variables.t_plasma_electron_deuteron_collision_vol_avg + self.data.physics.freq_plasma_electron_deuteron_collision_vol_avg = ( + 1 / self.data.physics.t_plasma_electron_deuteron_collision_vol_avg ) - physics_variables.freq_plasma_electron_deuteron_collision_profile = ( - 1 / physics_variables.t_plasma_electron_deuteron_collision_profile + self.data.physics.freq_plasma_electron_deuteron_collision_profile = ( + 1 / self.data.physics.t_plasma_electron_deuteron_collision_profile ) - physics_variables.freq_plasma_electron_triton_collision_vol_avg = ( - 1 / physics_variables.t_plasma_electron_triton_collision_vol_avg + self.data.physics.freq_plasma_electron_triton_collision_vol_avg = ( + 1 / self.data.physics.t_plasma_electron_triton_collision_vol_avg ) - physics_variables.freq_plasma_electron_triton_collision_profile = ( - 1 / physics_variables.t_plasma_electron_triton_collision_profile + self.data.physics.freq_plasma_electron_triton_collision_profile = ( + 1 / self.data.physics.t_plasma_electron_triton_collision_profile ) - physics_variables.freq_plasma_electron_alpha_thermal_collision_vol_avg = ( - 1 / physics_variables.t_plasma_electron_alpha_thermal_collision_vol_avg + self.data.physics.freq_plasma_electron_alpha_thermal_collision_vol_avg = ( + 1 / self.data.physics.t_plasma_electron_alpha_thermal_collision_vol_avg ) - physics_variables.freq_plasma_electron_alpha_thermal_collision_profile = ( - 1 / physics_variables.t_plasma_electron_alpha_thermal_collision_profile + self.data.physics.freq_plasma_electron_alpha_thermal_collision_profile = ( + 1 / self.data.physics.t_plasma_electron_alpha_thermal_collision_profile ) # ============================ # Mean free paths # ============================ - physics_variables.len_plasma_electron_electron_mean_free_path_vol_avg = ( - physics_variables.t_plasma_electron_electron_collision_vol_avg - * physics_variables.vel_plasma_electron_vol_avg + self.data.physics.len_plasma_electron_electron_mean_free_path_vol_avg = ( + self.data.physics.t_plasma_electron_electron_collision_vol_avg + * self.data.physics.vel_plasma_electron_vol_avg ) - physics_variables.len_plasma_electron_electron_mean_free_path_profile = ( - physics_variables.t_plasma_electron_electron_collision_profile - * physics_variables.vel_plasma_electron_profile + self.data.physics.len_plasma_electron_electron_mean_free_path_profile = ( + self.data.physics.t_plasma_electron_electron_collision_profile + * self.data.physics.vel_plasma_electron_profile ) - physics_variables.len_plasma_electron_deuteron_mean_free_path_vol_avg = ( - physics_variables.t_plasma_electron_deuteron_collision_vol_avg - * physics_variables.vel_plasma_electron_vol_avg + self.data.physics.len_plasma_electron_deuteron_mean_free_path_vol_avg = ( + self.data.physics.t_plasma_electron_deuteron_collision_vol_avg + * self.data.physics.vel_plasma_electron_vol_avg ) - physics_variables.len_plasma_electron_deuteron_mean_free_path_profile = ( - physics_variables.t_plasma_electron_deuteron_collision_profile - * physics_variables.vel_plasma_electron_profile + self.data.physics.len_plasma_electron_deuteron_mean_free_path_profile = ( + self.data.physics.t_plasma_electron_deuteron_collision_profile + * self.data.physics.vel_plasma_electron_profile ) - physics_variables.len_plasma_electron_triton_mean_free_path_vol_avg = ( - physics_variables.t_plasma_electron_triton_collision_vol_avg - * physics_variables.vel_plasma_electron_vol_avg + self.data.physics.len_plasma_electron_triton_mean_free_path_vol_avg = ( + self.data.physics.t_plasma_electron_triton_collision_vol_avg + * self.data.physics.vel_plasma_electron_vol_avg ) - physics_variables.len_plasma_electron_triton_mean_free_path_profile = ( - physics_variables.t_plasma_electron_triton_collision_profile - * physics_variables.vel_plasma_electron_profile + self.data.physics.len_plasma_electron_triton_mean_free_path_profile = ( + self.data.physics.t_plasma_electron_triton_collision_profile + * self.data.physics.vel_plasma_electron_profile ) - physics_variables.len_plasma_electron_alpha_thermal_mean_free_path_vol_avg = ( - physics_variables.t_plasma_electron_alpha_thermal_collision_vol_avg - * physics_variables.vel_plasma_electron_vol_avg + self.data.physics.len_plasma_electron_alpha_thermal_mean_free_path_vol_avg = ( + self.data.physics.t_plasma_electron_alpha_thermal_collision_vol_avg + * self.data.physics.vel_plasma_electron_vol_avg ) - physics_variables.len_plasma_electron_alpha_thermal_mean_free_path_profile = ( - physics_variables.t_plasma_electron_alpha_thermal_collision_profile - * physics_variables.vel_plasma_electron_profile + self.data.physics.len_plasma_electron_alpha_thermal_mean_free_path_profile = ( + self.data.physics.t_plasma_electron_alpha_thermal_collision_profile + * self.data.physics.vel_plasma_electron_profile ) # ============================ # Spitzer slow down time # ============================ - physics_variables.t_plasma_electron_alpha_spitzer_slow_vol_avg = self.calculate_spitzer_ion_slowing_down_time( + self.data.physics.t_plasma_electron_alpha_spitzer_slow_vol_avg = self.calculate_spitzer_ion_slowing_down_time( m_ion=constants.ALPHA_MASS, - plasma_coulomb_log_electron_ion=physics_variables.plasma_coulomb_log_electron_alpha_thermal_vol_avg, - temp_plasma_electrons_kev=physics_variables.temp_plasma_electron_vol_avg_kev, - nd_plasma_electrons=physics_variables.nd_plasma_electrons_vol_avg, + plasma_coulomb_log_electron_ion=self.data.physics.plasma_coulomb_log_electron_alpha_thermal_vol_avg, + temp_plasma_electrons_kev=self.data.physics.temp_plasma_electron_vol_avg_kev, + nd_plasma_electrons=self.data.physics.nd_plasma_electrons_vol_avg, n_charge_ion=2, ) - physics_variables.t_plasma_electron_alpha_spitzer_slow_profile = self.calculate_spitzer_ion_slowing_down_time( + self.data.physics.t_plasma_electron_alpha_spitzer_slow_profile = self.calculate_spitzer_ion_slowing_down_time( m_ion=constants.ALPHA_MASS, - plasma_coulomb_log_electron_ion=physics_variables.plasma_coulomb_log_electron_alpha_thermal_profile, + plasma_coulomb_log_electron_ion=self.data.physics.plasma_coulomb_log_electron_alpha_thermal_profile, temp_plasma_electrons_kev=self.plasma_profile.teprofile.profile_y, nd_plasma_electrons=self.plasma_profile.neprofile.profile_y, n_charge_ion=2, @@ -5229,15 +5259,15 @@ def run(self): # Resistivites # ============================ - physics_variables.res_plasma_fuel_spitzer_vol_avg = self.calculate_spitzer_resistivity( + self.data.physics.res_plasma_fuel_spitzer_vol_avg = self.calculate_spitzer_resistivity( n_charge=1, - electron_ion_coulomb_log=physics_variables.plasma_coulomb_log_electron_deuteron_vol_avg, - temp_plasma_electron_kev=physics_variables.temp_plasma_electron_vol_avg_kev, + electron_ion_coulomb_log=self.data.physics.plasma_coulomb_log_electron_deuteron_vol_avg, + temp_plasma_electron_kev=self.data.physics.temp_plasma_electron_vol_avg_kev, ) - physics_variables.res_plasma_fuel_spitzer_profile = self.calculate_spitzer_resistivity( + self.data.physics.res_plasma_fuel_spitzer_profile = self.calculate_spitzer_resistivity( n_charge=1, - electron_ion_coulomb_log=physics_variables.plasma_coulomb_log_electron_deuteron_profile, + electron_ion_coulomb_log=self.data.physics.plasma_coulomb_log_electron_deuteron_profile, temp_plasma_electron_kev=self.plasma_profile.teprofile.profile_y, ) @@ -5693,15 +5723,15 @@ def output_detailed_physics(self): self.outfile, "Plasma volume averaged electron Debye length (⟨λ_D⟩) (m)", "(len_plasma_debye_electron_vol_avg)", - physics_variables.len_plasma_debye_electron_vol_avg, + self.data.physics.len_plasma_debye_electron_vol_avg, "OP ", ) - for i in range(len(physics_variables.len_plasma_debye_electron_profile)): + for i in range(len(self.data.physics.len_plasma_debye_electron_profile)): po.ovarre( self.mfile, f"Plasma electron Debye length at point {i}", f"(len_plasma_debye_electron_profile{i})", - physics_variables.len_plasma_debye_electron_profile[i], + self.data.physics.len_plasma_debye_electron_profile[i], ) po.osubhd(self.outfile, "Larmor radii:") @@ -5710,19 +5740,19 @@ def output_detailed_physics(self): self.outfile, "Volume averaged deuteron isotropic toroidal Larmor radius (m)", "(radius_plasma_deuteron_toroidal_larmor_isotropic_vol_avg)", - physics_variables.radius_plasma_deuteron_toroidal_larmor_isotropic_vol_avg, + self.data.physics.radius_plasma_deuteron_toroidal_larmor_isotropic_vol_avg, ) for i in range( len( - physics_variables.radius_plasma_deuteron_toroidal_larmor_isotropic_profile + self.data.physics.radius_plasma_deuteron_toroidal_larmor_isotropic_profile ) ): po.ovarre( self.mfile, f"Plasma deuteron isotropic Larmor radius at point {i}", f"(radius_plasma_deuteron_toroidal_larmor_isotropic_profile{i})", - physics_variables.radius_plasma_deuteron_toroidal_larmor_isotropic_profile[ + self.data.physics.radius_plasma_deuteron_toroidal_larmor_isotropic_profile[ i ], ) @@ -5731,17 +5761,17 @@ def output_detailed_physics(self): self.outfile, "Volume averaged triton isotropic toroidal Larmor radius (m)", "(radius_plasma_triton_toroidal_larmor_isotropic_vol_avg)", - physics_variables.radius_plasma_triton_toroidal_larmor_isotropic_vol_avg, + self.data.physics.radius_plasma_triton_toroidal_larmor_isotropic_vol_avg, ) for i in range( - len(physics_variables.radius_plasma_triton_toroidal_larmor_isotropic_profile) + len(self.data.physics.radius_plasma_triton_toroidal_larmor_isotropic_profile) ): po.ovarre( self.mfile, f"Plasma triton isotropic Larmor radius at point {i}", f"(radius_plasma_triton_toroidal_larmor_isotropic_profile{i})", - physics_variables.radius_plasma_triton_toroidal_larmor_isotropic_profile[ + self.data.physics.radius_plasma_triton_toroidal_larmor_isotropic_profile[ i ], ) @@ -5752,63 +5782,63 @@ def output_detailed_physics(self): self.outfile, "Volume averaged electron thermal velocity (m/s)", "(vel_plasma_electron_vol_avg)", - physics_variables.vel_plasma_electron_vol_avg, + self.data.physics.vel_plasma_electron_vol_avg, ) - for i in range(len(physics_variables.vel_plasma_electron_profile)): + for i in range(len(self.data.physics.vel_plasma_electron_profile)): po.ovarre( self.mfile, f"Plasma electron thermal velocity at point {i}", f"(vel_plasma_electron_profile{i})", - physics_variables.vel_plasma_electron_profile[i], + self.data.physics.vel_plasma_electron_profile[i], ) po.ovarre( self.outfile, "Volume averaged deuteron thermal velocity (m/s)", "(vel_plasma_deuteron_vol_avg)", - physics_variables.vel_plasma_deuteron_vol_avg, + self.data.physics.vel_plasma_deuteron_vol_avg, ) - for i in range(len(physics_variables.vel_plasma_deuteron_profile)): + for i in range(len(self.data.physics.vel_plasma_deuteron_profile)): po.ovarre( self.mfile, f"Plasma deuteron thermal velocity at point {i}", f"(vel_plasma_deuteron_profile{i})", - physics_variables.vel_plasma_deuteron_profile[i], + self.data.physics.vel_plasma_deuteron_profile[i], ) po.ovarre( self.outfile, "Volume averaged triton thermal velocity (m/s)", "(vel_plasma_triton_vol_avg)", - physics_variables.vel_plasma_triton_vol_avg, + self.data.physics.vel_plasma_triton_vol_avg, ) - for i in range(len(physics_variables.vel_plasma_triton_profile)): + for i in range(len(self.data.physics.vel_plasma_triton_profile)): po.ovarre( self.mfile, f"Plasma triton thermal velocity at point {i}", f"(vel_plasma_triton_profile{i})", - physics_variables.vel_plasma_triton_profile[i], + self.data.physics.vel_plasma_triton_profile[i], ) po.ovarre( self.outfile, "Volume averaged alpha thermal velocity (m/s)", "(vel_plasma_alpha_thermal_vol_avg)", - physics_variables.vel_plasma_alpha_thermal_vol_avg, + self.data.physics.vel_plasma_alpha_thermal_vol_avg, ) - for i in range(len(physics_variables.vel_plasma_alpha_thermal_profile)): + for i in range(len(self.data.physics.vel_plasma_alpha_thermal_profile)): po.ovarre( self.mfile, f"Plasma alpha thermal velocity at point {i}", f"(vel_plasma_alpha_thermal_profile{i})", - physics_variables.vel_plasma_alpha_thermal_profile[i], + self.data.physics.vel_plasma_alpha_thermal_profile[i], ) po.ovarre( self.outfile, "Plasma alpha birth velocity (m/s)", "(vel_plasma_alpha_birth)", - physics_variables.vel_plasma_alpha_birth, + self.data.physics.vel_plasma_alpha_birth, ) po.osubhd(self.outfile, "Frequencies:") @@ -5817,81 +5847,81 @@ def output_detailed_physics(self): self.outfile, "Volume averaged electron plasma frequency (ωₚₑ) (Hz)", "(freq_plasma_electron_vol_avg)", - physics_variables.freq_plasma_electron_vol_avg, + self.data.physics.freq_plasma_electron_vol_avg, ) - for i in range(len(physics_variables.freq_plasma_electron_profile)): + for i in range(len(self.data.physics.freq_plasma_electron_profile)): po.ovarre( self.mfile, f"Plasma electron frequency at point {i}", f"(freq_plasma_electron_profile{i})", - physics_variables.freq_plasma_electron_profile[i], + self.data.physics.freq_plasma_electron_profile[i], ) po.ovarre( self.outfile, "Volume averaged electron toroidal Larmor frequency (ωc) (Hz)", "(freq_plasma_larmor_toroidal_electron_vol_avg)", - physics_variables.freq_plasma_larmor_toroidal_electron_vol_avg, + self.data.physics.freq_plasma_larmor_toroidal_electron_vol_avg, ) for i in range( - len(physics_variables.freq_plasma_larmor_toroidal_electron_profile) + len(self.data.physics.freq_plasma_larmor_toroidal_electron_profile) ): po.ovarre( self.mfile, f"Plasma electron toroidal Larmor frequency at point {i}", f"(freq_plasma_larmor_toroidal_electron_profile{i})", - physics_variables.freq_plasma_larmor_toroidal_electron_profile[i], + self.data.physics.freq_plasma_larmor_toroidal_electron_profile[i], ) po.ovarre( self.outfile, "Volume averaged deuteron toroidal Larmor frequency (ωc) (Hz)", "(freq_plasma_larmor_toroidal_deuteron_vol_avg)", - physics_variables.freq_plasma_larmor_toroidal_deuteron_vol_avg, + self.data.physics.freq_plasma_larmor_toroidal_deuteron_vol_avg, ) for i in range( - len(physics_variables.freq_plasma_larmor_toroidal_deuteron_profile) + len(self.data.physics.freq_plasma_larmor_toroidal_deuteron_profile) ): po.ovarre( self.mfile, f"Plasma deuteron toroidal Larmor frequency at point {i}", f"(freq_plasma_larmor_toroidal_deuteron_profile{i})", - physics_variables.freq_plasma_larmor_toroidal_deuteron_profile[i], + self.data.physics.freq_plasma_larmor_toroidal_deuteron_profile[i], ) po.ovarre( self.outfile, "Volume averaged triton toroidal Larmor frequency (ωc) (Hz)", "(freq_plasma_larmor_toroidal_triton_vol_avg)", - physics_variables.freq_plasma_larmor_toroidal_triton_vol_avg, + self.data.physics.freq_plasma_larmor_toroidal_triton_vol_avg, ) for i in range( - len(physics_variables.freq_plasma_larmor_toroidal_triton_profile) + len(self.data.physics.freq_plasma_larmor_toroidal_triton_profile) ): po.ovarre( self.mfile, f"Plasma triton toroidal Larmor frequency at point {i}", f"(freq_plasma_larmor_toroidal_triton_profile{i})", - physics_variables.freq_plasma_larmor_toroidal_triton_profile[i], + self.data.physics.freq_plasma_larmor_toroidal_triton_profile[i], ) po.ovarre( self.outfile, "Volume averaged electron upper hybrid frequency (ωₕ) (Hz)", "(freq_plasma_upper_hybrid_vol_avg)", - physics_variables.freq_plasma_upper_hybrid_vol_avg, + self.data.physics.freq_plasma_upper_hybrid_vol_avg, ) - for i in range(len(physics_variables.freq_plasma_upper_hybrid_profile)): + for i in range(len(self.data.physics.freq_plasma_upper_hybrid_profile)): po.ovarre( self.mfile, f"Plasma upper hybrid frequency at point {i}", f"(freq_plasma_upper_hybrid_profile{i})", - physics_variables.freq_plasma_upper_hybrid_profile[i], + self.data.physics.freq_plasma_upper_hybrid_profile[i], ) po.osubhd(self.outfile, "Coulomb Logarithms:") @@ -5900,90 +5930,90 @@ def output_detailed_physics(self): self.outfile, "Volume averaged electron-electron Coulomb log (Λₑₑ)", "(plasma_coulomb_log_electron_electron_vol_avg)", - physics_variables.plasma_coulomb_log_electron_electron_vol_avg, + self.data.physics.plasma_coulomb_log_electron_electron_vol_avg, "OP ", ) for i in range( - len(physics_variables.plasma_coulomb_log_electron_electron_profile) + len(self.data.physics.plasma_coulomb_log_electron_electron_profile) ): po.ovarre( self.mfile, f"Electron-electron Coulomb log at point {i}", f"(plasma_coulomb_log_electron_electron_profile{i})", - physics_variables.plasma_coulomb_log_electron_electron_profile[i], + self.data.physics.plasma_coulomb_log_electron_electron_profile[i], ) po.ovarrf( self.outfile, "Volume averaged electron-deuteron Coulomb log (ΛₑD)", "(plasma_coulomb_log_electron_deuteron_vol_avg)", - physics_variables.plasma_coulomb_log_electron_deuteron_vol_avg, + self.data.physics.plasma_coulomb_log_electron_deuteron_vol_avg, "OP ", ) for i in range( - len(physics_variables.plasma_coulomb_log_electron_deuteron_profile) + len(self.data.physics.plasma_coulomb_log_electron_deuteron_profile) ): po.ovarre( self.mfile, f"Electron-deuteron Coulomb log at point {i}", f"(plasma_coulomb_log_electron_deuteron_profile{i})", - physics_variables.plasma_coulomb_log_electron_deuteron_profile[i], + self.data.physics.plasma_coulomb_log_electron_deuteron_profile[i], ) po.ovarrf( self.outfile, "Volume averaged electron-triton Coulomb log (ΛₑT)", "(plasma_coulomb_log_electron_triton_vol_avg)", - physics_variables.plasma_coulomb_log_electron_triton_vol_avg, + self.data.physics.plasma_coulomb_log_electron_triton_vol_avg, "OP ", ) for i in range( - len(physics_variables.plasma_coulomb_log_electron_triton_profile) + len(self.data.physics.plasma_coulomb_log_electron_triton_profile) ): po.ovarre( self.mfile, f"Electron-triton Coulomb log at point {i}", f"(plasma_coulomb_log_electron_triton_profile{i})", - physics_variables.plasma_coulomb_log_electron_triton_profile[i], + self.data.physics.plasma_coulomb_log_electron_triton_profile[i], ) po.ovarrf( self.outfile, "Volume averaged deuteron-triton Coulomb log (Λ_DT)", "(plasma_coulomb_log_deuteron_triton_vol_avg)", - physics_variables.plasma_coulomb_log_deuteron_triton_vol_avg, + self.data.physics.plasma_coulomb_log_deuteron_triton_vol_avg, "OP ", ) for i in range( - len(physics_variables.plasma_coulomb_log_deuteron_triton_profile) + len(self.data.physics.plasma_coulomb_log_deuteron_triton_profile) ): po.ovarre( self.mfile, f"Deuteron-triton Coulomb log at point {i}", f"(plasma_coulomb_log_deuteron_triton_profile{i})", - physics_variables.plasma_coulomb_log_deuteron_triton_profile[i], + self.data.physics.plasma_coulomb_log_deuteron_triton_profile[i], ) po.ovarrf( self.outfile, "Volume averaged electron-alpha thermal Coulomb log (Λₑαₜₕ)", "(plasma_coulomb_log_electron_alpha_thermal_vol_avg)", - physics_variables.plasma_coulomb_log_electron_alpha_thermal_vol_avg, + self.data.physics.plasma_coulomb_log_electron_alpha_thermal_vol_avg, "OP ", ) for i in range( - len(physics_variables.plasma_coulomb_log_electron_alpha_thermal_profile) + len(self.data.physics.plasma_coulomb_log_electron_alpha_thermal_profile) ): po.ovarre( self.mfile, f"Electron-alpha thermal Coulomb log at point {i}", f"(plasma_coulomb_log_electron_alpha_thermal_profile{i})", - physics_variables.plasma_coulomb_log_electron_alpha_thermal_profile[i], + self.data.physics.plasma_coulomb_log_electron_alpha_thermal_profile[i], ) po.osubhd(self.outfile, "Collision Times:") @@ -5992,72 +6022,72 @@ def output_detailed_physics(self): self.outfile, "Volume averaged electron-electron collision time (τₑₑ) (s)", "(t_plasma_electron_electron_collision_vol_avg)", - physics_variables.t_plasma_electron_electron_collision_vol_avg, + self.data.physics.t_plasma_electron_electron_collision_vol_avg, "OP ", ) for i in range( - len(physics_variables.t_plasma_electron_electron_collision_profile) + len(self.data.physics.t_plasma_electron_electron_collision_profile) ): po.ovarre( self.mfile, f"Electron-electron collision time at point {i}", f"(t_plasma_electron_electron_collision_profile{i})", - physics_variables.t_plasma_electron_electron_collision_profile[i], + self.data.physics.t_plasma_electron_electron_collision_profile[i], ) po.ovarrf( self.outfile, "Volume averaged electron-deuteron collision time (τₑD) (s)", "(t_plasma_electron_deuteron_collision_vol_avg)", - physics_variables.t_plasma_electron_deuteron_collision_vol_avg, + self.data.physics.t_plasma_electron_deuteron_collision_vol_avg, "OP ", ) for i in range( - len(physics_variables.t_plasma_electron_deuteron_collision_profile) + len(self.data.physics.t_plasma_electron_deuteron_collision_profile) ): po.ovarre( self.mfile, f"Electron-deuteron collision time at point {i}", f"(t_plasma_electron_deuteron_collision_profile{i})", - physics_variables.t_plasma_electron_deuteron_collision_profile[i], + self.data.physics.t_plasma_electron_deuteron_collision_profile[i], ) po.ovarrf( self.outfile, "Volume averaged electron-triton collision time (τₑT) (s)", "(t_plasma_electron_triton_collision_vol_avg)", - physics_variables.t_plasma_electron_triton_collision_vol_avg, + self.data.physics.t_plasma_electron_triton_collision_vol_avg, "OP ", ) for i in range( - len(physics_variables.t_plasma_electron_triton_collision_profile) + len(self.data.physics.t_plasma_electron_triton_collision_profile) ): po.ovarre( self.mfile, f"Electron-triton collision time at point {i}", f"(t_plasma_electron_triton_collision_profile{i})", - physics_variables.t_plasma_electron_triton_collision_profile[i], + self.data.physics.t_plasma_electron_triton_collision_profile[i], ) po.ovarrf( self.outfile, "Volume averaged electron-alpha thermal collision time (τₑαₜₕ) (s)", "(t_plasma_electron_alpha_thermal_collision_vol_avg)", - physics_variables.t_plasma_electron_alpha_thermal_collision_vol_avg, + self.data.physics.t_plasma_electron_alpha_thermal_collision_vol_avg, "OP ", ) for i in range( - len(physics_variables.t_plasma_electron_alpha_thermal_collision_profile) + len(self.data.physics.t_plasma_electron_alpha_thermal_collision_profile) ): po.ovarre( self.mfile, f"Electron-alpha thermal collision time at point {i}", f"(t_plasma_electron_alpha_thermal_collision_profile{i})", - physics_variables.t_plasma_electron_alpha_thermal_collision_profile[i], + self.data.physics.t_plasma_electron_alpha_thermal_collision_profile[i], ) po.osubhd(self.outfile, "Collision Frequencies:") @@ -6066,68 +6096,68 @@ def output_detailed_physics(self): self.outfile, "Volume averaged electron-electron collision frequency (Hz)", "(freq_plasma_electron_electron_collision_vol_avg)", - physics_variables.freq_plasma_electron_electron_collision_vol_avg, + self.data.physics.freq_plasma_electron_electron_collision_vol_avg, ) for i in range( - len(physics_variables.freq_plasma_electron_electron_collision_profile) + len(self.data.physics.freq_plasma_electron_electron_collision_profile) ): po.ovarre( self.mfile, f"Electron-electron collision frequency at point {i}", f"(freq_plasma_electron_electron_collision_profile{i})", - physics_variables.freq_plasma_electron_electron_collision_profile[i], + self.data.physics.freq_plasma_electron_electron_collision_profile[i], ) po.ovarre( self.outfile, "Volume averaged electron-deuteron collision frequency (Hz)", "(freq_plasma_electron_deuteron_collision_vol_avg)", - physics_variables.freq_plasma_electron_deuteron_collision_vol_avg, + self.data.physics.freq_plasma_electron_deuteron_collision_vol_avg, ) for i in range( - len(physics_variables.freq_plasma_electron_deuteron_collision_profile) + len(self.data.physics.freq_plasma_electron_deuteron_collision_profile) ): po.ovarre( self.mfile, f"Electron-deuteron collision frequency at point {i}", f"(freq_plasma_electron_deuteron_collision_profile{i})", - physics_variables.freq_plasma_electron_deuteron_collision_profile[i], + self.data.physics.freq_plasma_electron_deuteron_collision_profile[i], ) po.ovarre( self.outfile, "Volume averaged electron-triton collision frequency (Hz)", "(freq_plasma_electron_triton_collision_vol_avg)", - physics_variables.freq_plasma_electron_triton_collision_vol_avg, + self.data.physics.freq_plasma_electron_triton_collision_vol_avg, ) for i in range( - len(physics_variables.freq_plasma_electron_triton_collision_profile) + len(self.data.physics.freq_plasma_electron_triton_collision_profile) ): po.ovarre( self.mfile, f"Electron-triton collision frequency at point {i}", f"(freq_plasma_electron_triton_collision_profile{i})", - physics_variables.freq_plasma_electron_triton_collision_profile[i], + self.data.physics.freq_plasma_electron_triton_collision_profile[i], ) po.ovarre( self.outfile, "Volume averaged electron-alpha thermal collision frequency (Hz)", "(freq_plasma_electron_alpha_thermal_collision_vol_avg)", - physics_variables.freq_plasma_electron_alpha_thermal_collision_vol_avg, + self.data.physics.freq_plasma_electron_alpha_thermal_collision_vol_avg, ) for i in range( - len(physics_variables.freq_plasma_electron_alpha_thermal_collision_profile) + len(self.data.physics.freq_plasma_electron_alpha_thermal_collision_profile) ): po.ovarre( self.mfile, f"Electron-alpha thermal collision frequency at point {i}", f"(freq_plasma_electron_alpha_thermal_collision_profile{i})", - physics_variables.freq_plasma_electron_alpha_thermal_collision_profile[ + self.data.physics.freq_plasma_electron_alpha_thermal_collision_profile[ i ], ) @@ -6138,70 +6168,70 @@ def output_detailed_physics(self): self.outfile, "Volume averaged electron-electron mean free path (λₑₑ) (m)", "(len_plasma_electron_electron_mean_free_path_vol_avg)", - physics_variables.len_plasma_electron_electron_mean_free_path_vol_avg, + self.data.physics.len_plasma_electron_electron_mean_free_path_vol_avg, ) for i in range( - len(physics_variables.len_plasma_electron_electron_mean_free_path_profile) + len(self.data.physics.len_plasma_electron_electron_mean_free_path_profile) ): po.ovarre( self.mfile, f"Electron-electron mean free path at point {i}", f"(len_plasma_electron_electron_mean_free_path_profile{i})", - physics_variables.len_plasma_electron_electron_mean_free_path_profile[i], + self.data.physics.len_plasma_electron_electron_mean_free_path_profile[i], ) po.ovarre( self.outfile, "Volume averaged electron-deuteron mean free path (λₑD) (m)", "(len_plasma_electron_deuteron_mean_free_path_vol_avg)", - physics_variables.len_plasma_electron_deuteron_mean_free_path_vol_avg, + self.data.physics.len_plasma_electron_deuteron_mean_free_path_vol_avg, ) for i in range( - len(physics_variables.len_plasma_electron_deuteron_mean_free_path_profile) + len(self.data.physics.len_plasma_electron_deuteron_mean_free_path_profile) ): po.ovarre( self.mfile, f"Electron-deuteron mean free path at point {i}", f"(len_plasma_electron_deuteron_mean_free_path_profile{i})", - physics_variables.len_plasma_electron_deuteron_mean_free_path_profile[i], + self.data.physics.len_plasma_electron_deuteron_mean_free_path_profile[i], ) po.ovarre( self.outfile, "Volume averaged electron-triton mean free path (λₑT) (m)", "(len_plasma_electron_triton_mean_free_path_vol_avg)", - physics_variables.len_plasma_electron_triton_mean_free_path_vol_avg, + self.data.physics.len_plasma_electron_triton_mean_free_path_vol_avg, ) for i in range( - len(physics_variables.len_plasma_electron_triton_mean_free_path_profile) + len(self.data.physics.len_plasma_electron_triton_mean_free_path_profile) ): po.ovarre( self.mfile, f"Electron-triton mean free path at point {i}", f"(len_plasma_electron_triton_mean_free_path_profile{i})", - physics_variables.len_plasma_electron_triton_mean_free_path_profile[i], + self.data.physics.len_plasma_electron_triton_mean_free_path_profile[i], ) po.ovarre( self.outfile, "Volume averaged electron-alpha thermal mean free path (λₑα) (m)", "(len_plasma_electron_alpha_thermal_mean_free_path_vol_avg)", - physics_variables.len_plasma_electron_alpha_thermal_mean_free_path_vol_avg, + self.data.physics.len_plasma_electron_alpha_thermal_mean_free_path_vol_avg, ) for i in range( len( - physics_variables.len_plasma_electron_alpha_thermal_mean_free_path_profile + self.data.physics.len_plasma_electron_alpha_thermal_mean_free_path_profile ) ): po.ovarre( self.mfile, f"Electron-alpha thermal mean free path at point {i}", f"(len_plasma_electron_alpha_thermal_mean_free_path_profile{i})", - physics_variables.len_plasma_electron_alpha_thermal_mean_free_path_profile[ + self.data.physics.len_plasma_electron_alpha_thermal_mean_free_path_profile[ i ], ) @@ -6212,17 +6242,17 @@ def output_detailed_physics(self): self.outfile, "Volume averaged electron-alpha Spitzer slowing down time (s)", "(t_plasma_electron_alpha_spitzer_slow_vol_avg)", - physics_variables.t_plasma_electron_alpha_spitzer_slow_vol_avg, + self.data.physics.t_plasma_electron_alpha_spitzer_slow_vol_avg, ) for i in range( - len(physics_variables.t_plasma_electron_alpha_spitzer_slow_profile) + len(self.data.physics.t_plasma_electron_alpha_spitzer_slow_profile) ): po.ovarre( self.mfile, f"Electron-alpha Spitzer slowing down time at point {i}", f"(t_plasma_electron_alpha_spitzer_slow_profile{i})", - physics_variables.t_plasma_electron_alpha_spitzer_slow_profile[i], + self.data.physics.t_plasma_electron_alpha_spitzer_slow_profile[i], ) po.osubhd(self.outfile, "Resistivities:") @@ -6231,13 +6261,13 @@ def output_detailed_physics(self): self.outfile, "Volume averaged plasma fuel Spitzer resistivity (η) (Ohm m)", "(res_plasma_fuel_spitzer_vol_avg)", - physics_variables.res_plasma_fuel_spitzer_vol_avg, + self.data.physics.res_plasma_fuel_spitzer_vol_avg, ) - for i in range(len(physics_variables.res_plasma_fuel_spitzer_profile)): + for i in range(len(self.data.physics.res_plasma_fuel_spitzer_profile)): po.ovarre( self.mfile, f"Plasma Spitzer resistivity at point {i}", f"(res_plasma_fuel_spitzer_profile{i})", - physics_variables.res_plasma_fuel_spitzer_profile[i], + self.data.physics.res_plasma_fuel_spitzer_profile[i], ) diff --git a/process/models/physics/plasma_current.py b/process/models/physics/plasma_current.py index 5c35b83d53..8f3ae395be 100644 --- a/process/models/physics/plasma_current.py +++ b/process/models/physics/plasma_current.py @@ -16,7 +16,6 @@ from process.core import process_output as po from process.core.exceptions import ProcessValueError from process.core.model import Model -from process.data_structure import physics_variables from process.models.physics.plasma_geometry import PlasmaGeometryModelType logger = logging.getLogger(__name__) @@ -86,10 +85,10 @@ def output(self) -> None: self.outfile, "Plasma current scaling law used", "(i_plasma_current)", - physics_variables.i_plasma_current, + self.data.physics.i_plasma_current, ) full_model_name = PlasmaCurrentModel( - physics_variables.i_plasma_current + self.data.physics.i_plasma_current ).full_name po.ocmmnt( self.outfile, @@ -100,26 +99,26 @@ def output(self) -> None: self.outfile, "Plasma current (Iₚ) (MA)", "(plasma_current_MA)", - physics_variables.plasma_current / 1.0e6, + self.data.physics.plasma_current / 1.0e6, "OP ", ) po.ovarrf( self.outfile, "Plasma current (Iₚ) (A)", "(plasma_current)", - physics_variables.plasma_current, + self.data.physics.plasma_current, "OP ", ) self.output_plasma_current_models() po.oblnkl(self.outfile) - if physics_variables.i_alphaj == 1: + if self.data.physics.i_alphaj == 1: po.ovarrf( self.outfile, "Current density profile factor (αⱼ)", "(alphaj)", - physics_variables.alphaj, + self.data.physics.alphaj, "OP ", ) else: @@ -127,7 +126,7 @@ def output(self) -> None: self.outfile, "Current density profile factor (αⱼ)", "(alphaj)", - physics_variables.alphaj, + self.data.physics.alphaj, ) po.ocmmnt(self.outfile, "Current profile index scalings:") po.oblnkl(self.outfile) @@ -136,7 +135,7 @@ def output(self) -> None: self.outfile, "J. Wesson plasma current profile index", "(alphaj_wesson)", - physics_variables.alphaj_wesson, + self.data.physics.alphaj_wesson, "OP ", ) po.oblnkl(self.outfile) @@ -144,47 +143,47 @@ def output(self) -> None: self.outfile, "On-axis plasma current density (j₀) (A/m²)", "(j_plasma_on_axis)", - physics_variables.j_plasma_on_axis, + self.data.physics.j_plasma_on_axis, "OP ", ) if self.data.stellarator.istell == 0: po.ovarrf( - self.outfile, "Safety factor on axis (q₀)", "(q0)", physics_variables.q0 + self.outfile, "Safety factor on axis (q₀)", "(q0)", self.data.physics.q0 ) - if physics_variables.i_plasma_current == 2: + if self.data.physics.i_plasma_current == 2: po.ovarrf( self.outfile, "Mean edge safety factor (q₉₅)", "(q95)", - physics_variables.q95, + self.data.physics.q95, ) po.ovarrf( self.outfile, "Safety factor at 95% flux surface (q₉₅)", "(q95)", - physics_variables.q95, + self.data.physics.q95, ) po.ovarrf( self.outfile, "Cylindrical safety factor (qcyl)", "(qstar)", - physics_variables.qstar, + self.data.physics.qstar, "OP ", ) if ( - physics_variables.i_plasma_geometry + self.data.physics.i_plasma_geometry == PlasmaGeometryModelType.STAR_FIESTA ): po.ovarrf( self.outfile, "Lower limit for edge safety factor q95", "(q95_min)", - physics_variables.q95_min, + self.data.physics.q95_min, "OP ", ) po.oblnkl(self.outfile) @@ -381,7 +380,7 @@ def calculate_plasma_current( except ValueError as e: raise ProcessValueError( "Illegal value of i_plasma_current", - i_plasma_current=physics_variables.i_plasma_current, + i_plasma_current=self.data.physics.i_plasma_current, ) from e # Main plasma current calculation using the fq value from the different settings @@ -479,46 +478,46 @@ def output_plasma_current_models(self) -> None: This function outputs the plasma current for all models to the output file. """ plasma_currents = self.calculate_all_plasma_current_models( - alphaj=physics_variables.alphaj, - alphap=physics_variables.alphap, - b_plasma_toroidal_on_axis=physics_variables.b_plasma_toroidal_on_axis, - eps=physics_variables.eps, - kappa=physics_variables.kappa, - kappa95=physics_variables.kappa95, - pres_plasma_on_axis=physics_variables.pres_plasma_thermal_on_axis, - len_plasma_poloidal=physics_variables.len_plasma_poloidal, - q95=physics_variables.q95, - rmajor=physics_variables.rmajor, - rminor=physics_variables.rminor, - triang=physics_variables.triang, - triang95=physics_variables.triang95, + alphaj=self.data.physics.alphaj, + alphap=self.data.physics.alphap, + b_plasma_toroidal_on_axis=self.data.physics.b_plasma_toroidal_on_axis, + eps=self.data.physics.eps, + kappa=self.data.physics.kappa, + kappa95=self.data.physics.kappa95, + pres_plasma_on_axis=self.data.physics.pres_plasma_thermal_on_axis, + len_plasma_poloidal=self.data.physics.len_plasma_poloidal, + q95=self.data.physics.q95, + rmajor=self.data.physics.rmajor, + rminor=self.data.physics.rminor, + triang=self.data.physics.triang, + triang95=self.data.physics.triang95, ) - physics_variables.c_plasma_peng_analytic = plasma_currents.get( + self.data.physics.c_plasma_peng_analytic = plasma_currents.get( PlasmaCurrentModel.PENG_ANALYTIC_FIT ) - physics_variables.c_plasma_peng_double_null = plasma_currents.get( + self.data.physics.c_plasma_peng_double_null = plasma_currents.get( PlasmaCurrentModel.PENG_DIVERTOR_SCALING ) - physics_variables.c_plasma_cyclindrical = plasma_currents.get( + self.data.physics.c_plasma_cyclindrical = plasma_currents.get( PlasmaCurrentModel.ITER_SCALING ) - physics_variables.c_plasma_ipdg89 = plasma_currents.get( + self.data.physics.c_plasma_ipdg89 = plasma_currents.get( PlasmaCurrentModel.IPDG89_SCALING ) - physics_variables.c_plasma_todd_empirical_i = plasma_currents.get( + self.data.physics.c_plasma_todd_empirical_i = plasma_currents.get( PlasmaCurrentModel.TODD_EMPIRICAL_SCALING_I ) - physics_variables.c_plasma_todd_empirical_ii = plasma_currents.get( + self.data.physics.c_plasma_todd_empirical_ii = plasma_currents.get( PlasmaCurrentModel.TODD_EMPIRICAL_SCALING_II ) - physics_variables.c_plasma_connor_hastie = plasma_currents.get( + self.data.physics.c_plasma_connor_hastie = plasma_currents.get( PlasmaCurrentModel.CONNOR_HASTIE_MODEL ) - physics_variables.c_plasma_sauter = plasma_currents.get( + self.data.physics.c_plasma_sauter = plasma_currents.get( PlasmaCurrentModel.SAUTER_SCALING ) - physics_variables.c_plasma_fiesta_st = plasma_currents.get( + self.data.physics.c_plasma_fiesta_st = plasma_currents.get( PlasmaCurrentModel.FIESTA_ST_SCALING ) @@ -528,63 +527,63 @@ def output_plasma_current_models(self) -> None: self.outfile, f"{PlasmaCurrentModel.PENG_ANALYTIC_FIT.full_name}", "(c_plasma_peng_analytic)", - physics_variables.c_plasma_peng_analytic, + self.data.physics.c_plasma_peng_analytic, "OP ", ) po.ovarre( self.outfile, f"{PlasmaCurrentModel.PENG_DIVERTOR_SCALING.full_name}", "(c_plasma_peng_double_null)", - physics_variables.c_plasma_peng_double_null, + self.data.physics.c_plasma_peng_double_null, "OP ", ) po.ovarre( self.outfile, f"{PlasmaCurrentModel.ITER_SCALING.full_name}", "(c_plasma_cyclindrical)", - physics_variables.c_plasma_cyclindrical, + self.data.physics.c_plasma_cyclindrical, "OP ", ) po.ovarre( self.outfile, f"{PlasmaCurrentModel.IPDG89_SCALING.full_name}", "(c_plasma_ipdg89)", - physics_variables.c_plasma_ipdg89, + self.data.physics.c_plasma_ipdg89, "OP ", ) po.ovarre( self.outfile, f"{PlasmaCurrentModel.TODD_EMPIRICAL_SCALING_I.full_name}", "(c_plasma_todd_empirical_i)", - physics_variables.c_plasma_todd_empirical_i, + self.data.physics.c_plasma_todd_empirical_i, "OP ", ) po.ovarre( self.outfile, f"{PlasmaCurrentModel.TODD_EMPIRICAL_SCALING_II.full_name}", "(c_plasma_todd_empirical_ii)", - physics_variables.c_plasma_todd_empirical_ii, + self.data.physics.c_plasma_todd_empirical_ii, "OP ", ) po.ovarre( self.outfile, f"{PlasmaCurrentModel.CONNOR_HASTIE_MODEL.full_name}", "(c_plasma_connor_hastie)", - physics_variables.c_plasma_connor_hastie, + self.data.physics.c_plasma_connor_hastie, "OP ", ) po.ovarre( self.outfile, f"{PlasmaCurrentModel.SAUTER_SCALING.full_name}", "(c_plasma_sauter)", - physics_variables.c_plasma_sauter, + self.data.physics.c_plasma_sauter, "OP ", ) po.ovarre( self.outfile, f"{PlasmaCurrentModel.FIESTA_ST_SCALING.full_name}", "(c_plasma_fiesta_st)", - physics_variables.c_plasma_fiesta_st, + self.data.physics.c_plasma_fiesta_st, "OP ", ) @@ -744,7 +743,7 @@ def calculate_poloidal_field( ff1, ff2, _, _ = self.plascar_bpol(aspect, eps, kappa, delta) # Transform q95 to qbar - qbar = q95 * 1.3e0 * (1.0e0 - physics_variables.eps) ** 0.6e0 + qbar = q95 * 1.3e0 * (1.0e0 - self.data.physics.eps) ** 0.6e0 return b_plasma_toroidal_on_axis * (ff1 + ff2) / (2.0 * np.pi * qbar) @@ -821,7 +820,7 @@ def calculate_plasma_current_peng( 1729-1738. https://doi.org/10.13182/FST92-A29971 """ # Transform q95 to qbar - qbar = q95 * 1.3e0 * (1.0e0 - physics_variables.eps) ** 0.6e0 + qbar = q95 * 1.3e0 * (1.0e0 - self.data.physics.eps) ** 0.6e0 ff1, ff2, d1, d2 = self.plascar_bpol(aspect, eps, kappa, delta) @@ -1119,29 +1118,29 @@ def __init__(self): def run(self): """Calculate plasma diamagnetic current fractions using scalings.""" - # Hender scaling for diamagnetic current at tight physics_variables.aspect ratio + # Hender scaling for diamagnetic current at tight self.data.physics.aspect ratio self.data.current_drive.f_c_plasma_diamagnetic_hender = ( - self.diamagnetic_fraction_hender(physics_variables.beta_total_vol_avg) + self.diamagnetic_fraction_hender(self.data.physics.beta_total_vol_avg) ) # SCENE scaling for diamagnetic current self.data.current_drive.f_c_plasma_diamagnetic_scene = ( self.diamagnetic_fraction_scene( - physics_variables.beta_total_vol_avg, - physics_variables.q95, - physics_variables.q0, + self.data.physics.beta_total_vol_avg, + self.data.physics.q95, + self.data.physics.q0, ) ) if ( - physics_variables.i_diamagnetic_current + self.data.physics.i_diamagnetic_current == PlasmaDiamagneticCurrentModel.HENDER_ST_FIT ): self.data.current_drive.f_c_plasma_diamagnetic = ( self.data.current_drive.f_c_plasma_diamagnetic_hender ) elif ( - physics_variables.i_diamagnetic_current + self.data.physics.i_diamagnetic_current == PlasmaDiamagneticCurrentModel.SCENE_FIT ): self.data.current_drive.f_c_plasma_diamagnetic = ( @@ -1155,10 +1154,10 @@ def output(self): self.outfile, "Plasma diamagnetic current fraction scaling law used", "(i_diamagnetic_current)", - physics_variables.i_diamagnetic_current, + self.data.physics.i_diamagnetic_current, ) full_model_name = PlasmaDiamagneticCurrentModel( - physics_variables.i_diamagnetic_current + self.data.physics.i_diamagnetic_current ).full_name po.ocmmnt( self.outfile, @@ -1181,7 +1180,7 @@ def output(self): ) po.oblnkl(self.outfile) if ( - physics_variables.i_diamagnetic_current == PlasmaDiamagneticCurrentModel.NONE + self.data.physics.i_diamagnetic_current == PlasmaDiamagneticCurrentModel.NONE and self.data.current_drive.f_c_plasma_diamagnetic_scene > 0.01e0 ): # Error to show if diamagnetic current is above 1% but not used diff --git a/process/models/physics/plasma_fields.py b/process/models/physics/plasma_fields.py index 690db2d6ac..fe1a3e78c8 100644 --- a/process/models/physics/plasma_fields.py +++ b/process/models/physics/plasma_fields.py @@ -8,9 +8,6 @@ from process.core import constants from process.core import process_output as po from process.core.model import Model -from process.data_structure import ( - physics_variables, -) from process.models.physics.plasma_current import PlasmaCurrent logger = logging.getLogger(__name__) @@ -91,7 +88,7 @@ def calculate_surface_averaged_poloidal_field( ff1, ff2, _, _ = self.current.plascar_bpol(aspect, eps, kappa, delta) # Transform q95 to qbar - qbar = q95 * 1.3e0 * (1.0e0 - physics_variables.eps) ** 0.6e0 + qbar = q95 * 1.3e0 * (1.0e0 - self.data.physics.eps) ** 0.6e0 return b_plasma_toroidal_on_axis * (ff1 + ff2) / (2.0 * np.pi * qbar) @@ -208,7 +205,7 @@ def output(self): self.outfile, "Vertical field at plasma (Bᵥ) (T)", "(b_plasma_vertical_required)", - physics_variables.b_plasma_vertical_required, + self.data.physics.b_plasma_vertical_required, "OP ", ) @@ -216,33 +213,33 @@ def output(self): self.outfile, "Vacuum toroidal field at R₀ (Bᴛ(R₀)) (T)", "(b_plasma_toroidal_on_axis)", - physics_variables.b_plasma_toroidal_on_axis, + self.data.physics.b_plasma_toroidal_on_axis, ) po.ovarrf( self.outfile, "Toroidal field at plasma inboard (Bᴛ(R₀-a)) (T)", "(b_plasma_inboard_toroidal)", - physics_variables.b_plasma_inboard_toroidal, + self.data.physics.b_plasma_inboard_toroidal, ) po.ovarrf( self.outfile, "Toroidal field at plasma outboard (Bᴛ(R₀+a)) (T)", "(b_plasma_outboard_toroidal)", - physics_variables.b_plasma_outboard_toroidal, + self.data.physics.b_plasma_outboard_toroidal, ) - for i in range(len(physics_variables.b_plasma_toroidal_profile)): + for i in range(len(self.data.physics.b_plasma_toroidal_profile)): po.ovarre( self.mfile, f"Toroidal field in plasma at point {i}", f"b_plasma_toroidal_profile{i}", - physics_variables.b_plasma_toroidal_profile[i], + self.data.physics.b_plasma_toroidal_profile[i], ) po.ovarrf( self.outfile, "Plasma surface averaged poloidal field (⟨Bₚₒₗ(a)⟩) (T)", "(b_plasma_surface_poloidal_average)", - physics_variables.b_plasma_surface_poloidal_average, + self.data.physics.b_plasma_surface_poloidal_average, "OP ", ) @@ -250,6 +247,6 @@ def output(self): self.outfile, "Total field (Bₜₒₜ) (T)", "(b_plasma_total)", - physics_variables.b_plasma_total, + self.data.physics.b_plasma_total, "OP ", ) diff --git a/process/models/physics/plasma_geometry.py b/process/models/physics/plasma_geometry.py index ac26d9b925..427d931176 100644 --- a/process/models/physics/plasma_geometry.py +++ b/process/models/physics/plasma_geometry.py @@ -10,9 +10,6 @@ from process.core import process_output as po from process.core.exceptions import ProcessValueError from process.core.model import Model -from process.data_structure import ( - physics_variables, -) logger = logging.getLogger(__name__) @@ -224,151 +221,151 @@ def run(self): xo = 0.0e0 # Define plasma minor radius from major radius and aspect ratio - physics_variables.rminor = physics_variables.rmajor / physics_variables.aspect + self.data.physics.rminor = self.data.physics.rmajor / self.data.physics.aspect # Define the inverse aspect ratio - physics_variables.eps = 1.0e0 / physics_variables.aspect + self.data.physics.eps = 1.0e0 / self.data.physics.aspect # ====================================================================== if ( - physics_variables.i_plasma_geometry == PlasmaGeometryModelType.IPDG89_X_POINT - ): # Use input kappa, physics_variables.triang values + self.data.physics.i_plasma_geometry == PlasmaGeometryModelType.IPDG89_X_POINT + ): # Use input kappa, self.data.physics.triang values # Rough estimate of 95% values # ITER Physics Design Guidlines: 1989 (Uckan et al. 1990) - # (close to previous estimate of (physics_variables.kappa - 0.04) / 1.1 - # over a large physics_variables.kappa range) + # (close to previous estimate of (self.data.physics.kappa - 0.04) / 1.1 + # over a large self.data.physics.kappa range) - physics_variables.kappa95 = physics_variables.kappa / 1.12e0 - physics_variables.triang95 = physics_variables.triang / 1.50e0 + self.data.physics.kappa95 = self.data.physics.kappa / 1.12e0 + self.data.physics.triang95 = self.data.physics.triang / 1.50e0 # ====================================================================== if ( - physics_variables.i_plasma_geometry == PlasmaGeometryModelType.STAR_FIESTA - ): # ST scaling with physics_variables.aspect ratio [STAR Code] - physics_variables.q95_min = 3.0e0 * ( - 1.0e0 + 2.6e0 * physics_variables.eps**2.8e0 + self.data.physics.i_plasma_geometry == PlasmaGeometryModelType.STAR_FIESTA + ): # ST scaling with self.data.physics.aspect ratio [STAR Code] + self.data.physics.q95_min = 3.0e0 * ( + 1.0e0 + 2.6e0 * self.data.physics.eps**2.8e0 ) - physics_variables.kappa = 2.05e0 * ( - 1.0e0 + 0.44e0 * physics_variables.eps**2.1e0 + self.data.physics.kappa = 2.05e0 * ( + 1.0e0 + 0.44e0 * self.data.physics.eps**2.1e0 ) - physics_variables.triang = 0.53e0 * ( - 1.0e0 + 0.77e0 * physics_variables.eps**3 + self.data.physics.triang = 0.53e0 * ( + 1.0e0 + 0.77e0 * self.data.physics.eps**3 ) # SIM 10/09/2020: Switched to FIESTA ST scaling from IPDG89 - physics_variables.kappa95 = ( - physics_variables.kappa - 0.39467e0 + self.data.physics.kappa95 = ( + self.data.physics.kappa - 0.39467e0 ) / 0.90698e0 # Fit to FIESTA (Issue #1086) - physics_variables.triang95 = ( - physics_variables.triang - 0.048306e0 + self.data.physics.triang95 = ( + self.data.physics.triang - 0.048306e0 ) / 1.3799e0 # ====================================================================== if ( - physics_variables.i_plasma_geometry + self.data.physics.i_plasma_geometry == PlasmaGeometryModelType.ZOHM_ITER_X_POINT - ): # Zohm et al. ITER scaling for elongation, input physics_variables.triang - physics_variables.kappa = physics_variables.fkzohm * min( - 2.0e0, 1.5e0 + 0.5e0 / (physics_variables.aspect - 1.0e0) + ): # Zohm et al. ITER scaling for elongation, input self.data.physics.triang + self.data.physics.kappa = self.data.physics.fkzohm * min( + 2.0e0, 1.5e0 + 0.5e0 / (self.data.physics.aspect - 1.0e0) ) # ITER Physics Design Guidlines: 1989 (Uckan et al. 1990) - physics_variables.kappa95 = physics_variables.kappa / 1.12e0 - physics_variables.triang95 = physics_variables.triang / 1.50e0 + self.data.physics.kappa95 = self.data.physics.kappa / 1.12e0 + self.data.physics.triang95 = self.data.physics.triang / 1.50e0 # ====================================================================== if ( - physics_variables.i_plasma_geometry == PlasmaGeometryModelType.ZOHM_ITER_95 - ): # Zohm et al. ITER scaling for elongation, input physics_variables.triang95 - physics_variables.kappa = physics_variables.fkzohm * min( - 2.0e0, 1.5e0 + 0.5e0 / (physics_variables.aspect - 1.0e0) + self.data.physics.i_plasma_geometry == PlasmaGeometryModelType.ZOHM_ITER_95 + ): # Zohm et al. ITER scaling for elongation, input self.data.physics.triang95 + self.data.physics.kappa = self.data.physics.fkzohm * min( + 2.0e0, 1.5e0 + 0.5e0 / (self.data.physics.aspect - 1.0e0) ) # ITER Physics Design Guidlines: 1989 (Uckan et al. 1990) - physics_variables.triang = 1.5e0 * physics_variables.triang95 + self.data.physics.triang = 1.5e0 * self.data.physics.triang95 - physics_variables.kappa95 = physics_variables.kappa / 1.12e0 + self.data.physics.kappa95 = self.data.physics.kappa / 1.12e0 # ====================================================================== if ( - physics_variables.i_plasma_geometry == PlasmaGeometryModelType.IPDG89_95 - ): # Use input kappa95, physics_variables.triang95 values + self.data.physics.i_plasma_geometry == PlasmaGeometryModelType.IPDG89_95 + ): # Use input kappa95, self.data.physics.triang95 values # ITER Physics Design Guidlines: 1989 (Uckan et al. 1990) - physics_variables.kappa = 1.12e0 * physics_variables.kappa95 - physics_variables.triang = 1.5e0 * physics_variables.triang95 + self.data.physics.kappa = 1.12e0 * self.data.physics.kappa95 + self.data.physics.triang = 1.5e0 * self.data.physics.triang95 # ====================================================================== if ( - physics_variables.i_plasma_geometry == PlasmaGeometryModelType.MAST_DATA_95 - ): # Use input kappa95, physics_variables.triang95 values + self.data.physics.i_plasma_geometry == PlasmaGeometryModelType.MAST_DATA_95 + ): # Use input kappa95, self.data.physics.triang95 values # Fit to MAST data (Issue #1086) - physics_variables.kappa = 0.91300e0 * physics_variables.kappa95 + 0.38654e0 - physics_variables.triang = 0.77394e0 * physics_variables.triang95 + 0.18515e0 + self.data.physics.kappa = 0.91300e0 * self.data.physics.kappa95 + 0.38654e0 + self.data.physics.triang = 0.77394e0 * self.data.physics.triang95 + 0.18515e0 # ====================================================================== if ( - physics_variables.i_plasma_geometry + self.data.physics.i_plasma_geometry == PlasmaGeometryModelType.MAST_DATA_X_POINT - ): # Use input kappa, physics_variables.triang values + ): # Use input kappa, self.data.physics.triang values # Fit to MAST data (Issue #1086) - physics_variables.kappa95 = (physics_variables.kappa - 0.38654e0) / 0.91300e0 - physics_variables.triang95 = ( - physics_variables.triang - 0.18515e0 + self.data.physics.kappa95 = (self.data.physics.kappa - 0.38654e0) / 0.91300e0 + self.data.physics.triang95 = ( + self.data.physics.triang - 0.18515e0 ) / 0.77394e0 # ====================================================================== if ( - physics_variables.i_plasma_geometry == PlasmaGeometryModelType.FIESTA_RUNS_95 - ): # Use input kappa95, physics_variables.triang95 values + self.data.physics.i_plasma_geometry == PlasmaGeometryModelType.FIESTA_RUNS_95 + ): # Use input kappa95, self.data.physics.triang95 values # Fit to FIESTA (Issue #1086) - physics_variables.kappa = 0.90698e0 * physics_variables.kappa95 + 0.39467e0 - physics_variables.triang = 1.3799e0 * physics_variables.triang95 + 0.048306e0 + self.data.physics.kappa = 0.90698e0 * self.data.physics.kappa95 + 0.39467e0 + self.data.physics.triang = 1.3799e0 * self.data.physics.triang95 + 0.048306e0 # ====================================================================== if ( - physics_variables.i_plasma_geometry + self.data.physics.i_plasma_geometry == PlasmaGeometryModelType.FIESTA_RUNS_X_POINT - ): # Use input kappa, physics_variables.triang values + ): # Use input kappa, self.data.physics.triang values # Fit to FIESTA (Issue #1086) - physics_variables.kappa95 = (physics_variables.kappa - 0.39467e0) / 0.90698e0 - physics_variables.triang95 = ( - physics_variables.triang - 0.048306e0 + self.data.physics.kappa95 = (self.data.physics.kappa - 0.39467e0) / 0.90698e0 + self.data.physics.triang95 = ( + self.data.physics.triang - 0.048306e0 ) / 1.3799e0 # ====================================================================== if ( - physics_variables.i_plasma_geometry + self.data.physics.i_plasma_geometry == PlasmaGeometryModelType.INDUCTANCE_SCALING_X_POINT - ): # Use input triang, physics_variables.ind_plasma_internal_norm values - # physics_variables.kappa found from physics_variables.aspect ratio and + ): # Use input triang, self.data.physics.ind_plasma_internal_norm values + # self.data.physics.kappa found from self.data.physics.aspect ratio and # plasma internal inductance li(3) - physics_variables.kappa = ( - 1.09e0 + 0.26e0 / physics_variables.ind_plasma_internal_norm - ) * (1.5e0 / physics_variables.aspect) ** 0.4e0 + self.data.physics.kappa = ( + 1.09e0 + 0.26e0 / self.data.physics.ind_plasma_internal_norm + ) * (1.5e0 / self.data.physics.aspect) ** 0.4e0 - physics_variables.kappa95 = physics_variables.kappa / 1.12e0 - physics_variables.triang95 = physics_variables.triang / 1.50e0 + self.data.physics.kappa95 = self.data.physics.kappa / 1.12e0 + self.data.physics.triang95 = self.data.physics.triang / 1.50e0 # ====================================================================== if ( - physics_variables.i_plasma_geometry + self.data.physics.i_plasma_geometry == PlasmaGeometryModelType.CREATE_DATA_EU_DEMO_X_POINT ): - # physics_variables.kappa95 found from physics_variables.aspect ratio and + # self.data.physics.kappa95 found from self.data.physics.aspect ratio and # stability margin Based on fit to CREATE data. ref Issue #1399 - # valid for EU-DEMO like machine - physics_variables.aspect ratio 2.6 - 3.6 + # valid for EU-DEMO like machine - self.data.physics.aspect ratio 2.6 - 3.6 # Model updated see Issue #1648 a = 3.68436807e0 b = -0.27706527e0 @@ -377,125 +374,125 @@ def run(self): e = -0.27267618e0 f = 20.5141261e0 - physics_variables.kappa95 = ( + self.data.physics.kappa95 = ( -d - - c * physics_variables.aspect + - c * self.data.physics.aspect - np.sqrt( - (c**2.0e0 - 4.0e0 * a * b) * physics_variables.aspect**2.0e0 - + (2.0e0 * d * c - 4.0e0 * a * e) * physics_variables.aspect + (c**2.0e0 - 4.0e0 * a * b) * self.data.physics.aspect**2.0e0 + + (2.0e0 * d * c - 4.0e0 * a * e) * self.data.physics.aspect + d**2.0e0 - 4.0e0 * a * f - + 4.0e0 * a * physics_variables.m_s_limit + + 4.0e0 * a * self.data.physics.m_s_limit ) ) / (2.0e0 * a) - if physics_variables.kappa95 > 1.77: - ratio = 1.77 / physics_variables.kappa95 - corner_fudge = 0.3 * (physics_variables.kappa95 - 1.77) / ratio - physics_variables.kappa95 = ( - physics_variables.kappa95 ** (ratio) + corner_fudge + if self.data.physics.kappa95 > 1.77: + ratio = 1.77 / self.data.physics.kappa95 + corner_fudge = 0.3 * (self.data.physics.kappa95 - 1.77) / ratio + self.data.physics.kappa95 = ( + self.data.physics.kappa95 ** (ratio) + corner_fudge ) - physics_variables.kappa = 1.12e0 * physics_variables.kappa95 - physics_variables.triang95 = physics_variables.triang / 1.50e0 + self.data.physics.kappa = 1.12e0 * self.data.physics.kappa95 + self.data.physics.triang95 = self.data.physics.triang / 1.50e0 # ====================================================================== if ( - physics_variables.i_plasma_geometry + self.data.physics.i_plasma_geometry == PlasmaGeometryModelType.MENARD_2016_X_POINT ): # See Issue #1439 - # physics_variables.triang is an input - # physics_variables.kappa found from physics_variables.aspect ratio scaling + # self.data.physics.triang is an input + # self.data.physics.kappa found from self.data.physics.aspect ratio scaling # on p32 of Menard: Menard, et al. "Fusion Nuclear Science Facilities # and Pilot Plants Based on the Spherical Tokamak." Nucl. Fusion, 2016, 44. - physics_variables.kappa = 0.95e0 * ( - 1.9e0 + 1.9e0 / physics_variables.aspect**1.4e0 + self.data.physics.kappa = 0.95e0 * ( + 1.9e0 + 1.9e0 / self.data.physics.aspect**1.4e0 ) - physics_variables.kappa95 = physics_variables.kappa / 1.12e0 - physics_variables.triang95 = physics_variables.triang / 1.50e0 + self.data.physics.kappa95 = self.data.physics.kappa / 1.12e0 + self.data.physics.triang95 = self.data.physics.triang / 1.50e0 # ====================================================================== if ( - physics_variables.i_plasma_geometry + self.data.physics.i_plasma_geometry == PlasmaGeometryModelType.MENARD_1997_X_POINT ): - # physics_variables.triang is an input - # physics_variables.kappa found from physics_variables.aspect ratio scaling from + # self.data.physics.triang is an input + # self.data.physics.kappa found from self.data.physics.aspect ratio scaling from # J.E. Menard et al 1997 Nucl. Fusion 37 595 and assume max controllable kappa # and assume lᵢ(3) is held constant - physics_variables.kappa = ( - 2.93e0 * (1.8e0 / physics_variables.aspect) ** 0.4e0 + self.data.physics.kappa = ( + 2.93e0 * (1.8e0 / self.data.physics.aspect) ** 0.4e0 ) - physics_variables.kappa95 = physics_variables.kappa / 1.12e0 - physics_variables.triang95 = physics_variables.triang / 1.50e0 + self.data.physics.kappa95 = self.data.physics.kappa / 1.12e0 + self.data.physics.triang95 = self.data.physics.triang / 1.50e0 # ====================================================================== # Scrape-off layer thicknesses - if physics_variables.i_plasma_wall_gap == 0: - self.data.build.dr_fw_plasma_gap_outboard = 0.1e0 * physics_variables.rminor - self.data.build.dr_fw_plasma_gap_inboard = 0.1e0 * physics_variables.rminor + if self.data.physics.i_plasma_wall_gap == 0: + self.data.build.dr_fw_plasma_gap_outboard = 0.1e0 * self.data.physics.rminor + self.data.build.dr_fw_plasma_gap_inboard = 0.1e0 * self.data.physics.rminor # ====================================================================== # Find parameters of arcs describing plasma surfaces xi, thetai, xo, thetao = self.plasma_angles_arcs( - physics_variables.rminor, - physics_variables.kappa, - physics_variables.triang, + self.data.physics.rminor, + self.data.physics.kappa, + self.data.physics.triang, ) # Surface area - inboard and outboard. These are not given by Sauter but # the outboard area is required by DCLL and divertor xsi, xso = self.plasma_surface_area( - physics_variables.rmajor, - physics_variables.rminor, + self.data.physics.rmajor, + self.data.physics.rminor, xi, thetai, xo, thetao, ) - physics_variables.a_plasma_surface_outboard = xso + self.data.physics.a_plasma_surface_outboard = xso # ====================================================================== # i_plasma_current = 8 specifies use of the Sauter geometry as well as plasma # current. if ( - physics_variables.i_plasma_current == 8 - or physics_variables.i_plasma_shape == PlasmaShapeModelType.SAUTER + self.data.physics.i_plasma_current == 8 + or self.data.physics.i_plasma_shape == PlasmaShapeModelType.SAUTER ): ( - physics_variables.len_plasma_poloidal, - physics_variables.a_plasma_surface, - physics_variables.a_plasma_poloidal, - physics_variables.vol_plasma, + self.data.physics.len_plasma_poloidal, + self.data.physics.a_plasma_surface, + self.data.physics.a_plasma_poloidal, + self.data.physics.vol_plasma, ) = self.sauter_geometry( - physics_variables.rminor, - physics_variables.rmajor, - physics_variables.kappa, - physics_variables.triang, - physics_variables.plasma_square, + self.data.physics.rminor, + self.data.physics.rmajor, + self.data.physics.kappa, + self.data.physics.triang, + self.data.physics.plasma_square, ) else: # Poloidal perimeter - physics_variables.len_plasma_poloidal = self.plasma_poloidal_perimeter( + self.data.physics.len_plasma_poloidal = self.plasma_poloidal_perimeter( xi, thetai, xo, thetao ) # Volume - physics_variables.vol_plasma = ( - physics_variables.f_vol_plasma + self.data.physics.vol_plasma = ( + self.data.physics.f_vol_plasma * self.plasma_volume( - physics_variables.rmajor, - physics_variables.rminor, + self.data.physics.rmajor, + self.data.physics.rminor, xi, thetai, xo, @@ -504,12 +501,12 @@ def run(self): ) # Cross-sectional area - physics_variables.a_plasma_poloidal = self.plasma_cross_section( + self.data.physics.a_plasma_poloidal = self.plasma_cross_section( xi, thetai, xo, thetao ) # Surface area - sum of inboard and outboard. - physics_variables.a_plasma_surface = xsi + xso + self.data.physics.a_plasma_surface = xsi + xso # ====================================================================== @@ -539,52 +536,52 @@ def output(self): po.ocmmnt(self.outfile, "Plasma configuration = stellarator") if self.data.stellarator.istell == 0: - if physics_variables.itart == 0: - physics_variables.itart_r = physics_variables.itart + if self.data.physics.itart == 0: + self.data.physics.itart_r = self.data.physics.itart po.ovarin( self.outfile, "Tokamak aspect ratio = Conventional, itart = 0", "(itart)", - physics_variables.itart_r, + self.data.physics.itart_r, ) - elif physics_variables.itart == 1: - physics_variables.itart_r = physics_variables.itart + elif self.data.physics.itart == 1: + self.data.physics.itart_r = self.data.physics.itart po.ovarin( self.outfile, "Tokamak aspect ratio = Spherical, itart = 1", "(itart)", - physics_variables.itart_r, + self.data.physics.itart_r, ) po.ovarin( self.outfile, "Plasma shaping model", "(i_plasma_shape)", - physics_variables.i_plasma_shape, + self.data.physics.i_plasma_shape, ) po.osubhd( self.outfile, - f"{PlasmaShapeModelType(physics_variables.i_plasma_shape).full_name} " + f"{PlasmaShapeModelType(self.data.physics.i_plasma_shape).full_name} " "plasma shape model is used :", ) po.ovarrf( - self.outfile, "Major radius (R₀) (m)", "(rmajor)", physics_variables.rmajor + self.outfile, "Major radius (R₀) (m)", "(rmajor)", self.data.physics.rmajor ) po.ovarrf( self.outfile, "Minor radius (a) (m)", "(rminor)", - physics_variables.rminor, + self.data.physics.rminor, "OP ", ) - po.ovarrf(self.outfile, "Aspect ratio (A)", "(aspect)", physics_variables.aspect) + po.ovarrf(self.outfile, "Aspect ratio (A)", "(aspect)", self.data.physics.aspect) po.ovarrf( self.outfile, "Plasma squareness (ζ)", "(plasma_square)", - physics_variables.plasma_square, + self.data.physics.plasma_square, "IP", ) po.oblnkl(self.outfile) @@ -593,18 +590,18 @@ def output(self): self.outfile, "Plasma geometry model", "(i_plasma_geometry)", - physics_variables.i_plasma_geometry, + self.data.physics.i_plasma_geometry, ) po.oblnkl(self.outfile) po.ovarre( self.outfile, "ITER Physics Basis definition of elongation (κₐ)", "(kappa_ipb)", - physics_variables.kappa_ipb, + self.data.physics.kappa_ipb, "OP ", ) po.oblnkl(self.outfile) - geom_type = PlasmaGeometryModelType(physics_variables.i_plasma_geometry) + geom_type = PlasmaGeometryModelType(self.data.physics.i_plasma_geometry) if self.data.stellarator.istell == 0: po.ocmmnt( @@ -616,7 +613,7 @@ def output(self): self.outfile, "Elongation, X-point (κₐ)", "(kappa)", - physics_variables.kappa, + self.data.physics.kappa, "IP" if geom_type.kappa_model == PlasmaGeometryModels.USER_INPUT else "OP", @@ -626,7 +623,7 @@ def output(self): self.outfile, "Zohm scaling adjustment factor", "(fkzohm)", - physics_variables.fkzohm, + self.data.physics.fkzohm, ) po.oblnkl(self.outfile) @@ -639,7 +636,7 @@ def output(self): self.outfile, "Elongation, 95% surface (κ₉₅)", "(kappa95)", - physics_variables.kappa95, + self.data.physics.kappa95, "IP" if geom_type.kappa95_model == PlasmaGeometryModels.USER_INPUT else "OP", @@ -656,7 +653,7 @@ def output(self): self.outfile, "Triangularity, X-point (δ)", "(triang)", - physics_variables.triang, + self.data.physics.triang, "IP " if geom_type.triang_model == PlasmaGeometryModels.USER_INPUT else "OP", @@ -671,7 +668,7 @@ def output(self): self.outfile, "Triangularity, 95% surface (δ₉₅)", "(triang95)", - physics_variables.triang95, + self.data.physics.triang95, "IP " if geom_type.triang95_model == PlasmaGeometryModels.USER_INPUT else "OP", @@ -683,7 +680,7 @@ def output(self): self.outfile, "Plasma poloidal perimeter (m)", "(len_plasma_poloidal)", - physics_variables.len_plasma_poloidal, + self.data.physics.len_plasma_poloidal, "OP ", ) @@ -691,21 +688,21 @@ def output(self): self.outfile, "Plasma cross-sectional area (m²)", "(a_plasma_poloidal)", - physics_variables.a_plasma_poloidal, + self.data.physics.a_plasma_poloidal, "OP ", ) po.ovarre( self.outfile, "Plasma surface area (m²)", "(a_plasma_surface)", - physics_variables.a_plasma_surface, + self.data.physics.a_plasma_surface, "OP ", ) po.ovarre( self.outfile, "Plasma volume (m³)", "(vol_plasma)", - physics_variables.vol_plasma, + self.data.physics.vol_plasma, "OP ", ) diff --git a/process/models/physics/plasma_profiles.py b/process/models/physics/plasma_profiles.py index 1956ed38af..f716aacf14 100644 --- a/process/models/physics/plasma_profiles.py +++ b/process/models/physics/plasma_profiles.py @@ -12,8 +12,7 @@ from process.core import constants from process.core.exceptions import ProcessValueError from process.core.model import Model -from process.data_structure import physics_variables -from process.models.physics.profiles import NeProfile, PlasmaProfileShapeType, TeProfile +from process.models.physics.profiles import PlasmaProfileShapeType logger = logging.getLogger(__name__) @@ -23,7 +22,7 @@ class PlasmaProfile(Model): profiles and handles the required physics variables. """ - def __init__(self): + def __init__(self, ne_profile, te_profile): """ Initialize the PlasmaProfile class. @@ -34,11 +33,11 @@ def __init__(self): teprofile (TeProfile): An instance of the TeProfile class. """ # Default profile_size = 501, but it's possible to experiment with this value. - self.profile_size = 501 - physics_variables.n_plasma_profile_elements = self.profile_size + self.profile_size = self.data.physics.n_plasma_profile_elements + self.data.physics.n_plasma_profile_elements = self.profile_size self.outfile = constants.NOUT - self.neprofile = NeProfile(self.profile_size) - self.teprofile = TeProfile(self.profile_size) + self.neprofile = ne_profile + self.teprofile = te_profile def run(self): """Subroutine to execute PlasmaProfile functions. @@ -63,15 +62,15 @@ def parameterise_plasma(self): # Volume-averaged ion temperature # (input value used directly if f_temp_plasma_ion_electron=0.0) - if physics_variables.f_temp_plasma_ion_electron > 0.0e0: - physics_variables.temp_plasma_ion_vol_avg_kev = ( - physics_variables.f_temp_plasma_ion_electron - * physics_variables.temp_plasma_electron_vol_avg_kev + if self.data.physics.f_temp_plasma_ion_electron > 0.0e0: + self.data.physics.temp_plasma_ion_vol_avg_kev = ( + self.data.physics.f_temp_plasma_ion_electron + * self.data.physics.temp_plasma_electron_vol_avg_kev ) # Parabolic profile case if ( - PlasmaProfileShapeType(physics_variables.i_plasma_pedestal) + PlasmaProfileShapeType(self.data.physics.i_plasma_pedestal) == PlasmaProfileShapeType.PARABOLIC_PROFILE ): self.parabolic_paramterisation() @@ -92,13 +91,13 @@ def parabolic_paramterisation(self): # Reset pedestal values to agree with original parabolic profiles # ruff: disable[RUF069] if ( - physics_variables.radius_plasma_pedestal_temp_norm != 1.0 - or physics_variables.radius_plasma_pedestal_density_norm != 1.0 - or physics_variables.temp_plasma_pedestal_kev != 0.0 - or physics_variables.temp_plasma_separatrix_kev != 0.0 - or physics_variables.nd_plasma_pedestal_electron != 0.0 - or physics_variables.nd_plasma_separatrix_electron != 0.0 - or physics_variables.tbeta != 2.0 + self.data.physics.radius_plasma_pedestal_temp_norm != 1.0 + or self.data.physics.radius_plasma_pedestal_density_norm != 1.0 + or self.data.physics.temp_plasma_pedestal_kev != 0.0 + or self.data.physics.temp_plasma_separatrix_kev != 0.0 + or self.data.physics.nd_plasma_pedestal_electron != 0.0 + or self.data.physics.nd_plasma_separatrix_electron != 0.0 + or self.data.physics.tbeta != 2.0 ): logger.error( "Parabolic plasma profiles is used for an L-Mode plasma, " @@ -110,13 +109,13 @@ def parabolic_paramterisation(self): "and 'tbeta' have all been reset to L-Mode appropriate values" ) - physics_variables.radius_plasma_pedestal_temp_norm = 1.0e0 - physics_variables.radius_plasma_pedestal_density_norm = 1.0e0 - physics_variables.temp_plasma_pedestal_kev = 0.0e0 - physics_variables.temp_plasma_separatrix_kev = 0.0e0 - physics_variables.nd_plasma_pedestal_electron = 0.0e0 - physics_variables.nd_plasma_separatrix_electron = 0.0e0 - physics_variables.tbeta = 2.0e0 + self.data.physics.radius_plasma_pedestal_temp_norm = 1.0e0 + self.data.physics.radius_plasma_pedestal_density_norm = 1.0e0 + self.data.physics.temp_plasma_pedestal_kev = 0.0e0 + self.data.physics.temp_plasma_separatrix_kev = 0.0e0 + self.data.physics.nd_plasma_pedestal_electron = 0.0e0 + self.data.physics.nd_plasma_separatrix_electron = 0.0e0 + self.data.physics.tbeta = 2.0e0 # ruff: enable[RUF069] # Re-caluclate core and profile values self.teprofile.run() @@ -125,53 +124,53 @@ def parabolic_paramterisation(self): # Profile factor; ratio of density-weighted to volume-averaged # temperature - physics_variables.f_temp_plasma_electron_density_vol_avg = ( - (1.0e0 + physics_variables.alphan) - * (1.0e0 + physics_variables.alphat) - / (1.0e0 + physics_variables.alphan + physics_variables.alphat) + self.data.physics.f_temp_plasma_electron_density_vol_avg = ( + (1.0e0 + self.data.physics.alphan) + * (1.0e0 + self.data.physics.alphat) + / (1.0e0 + self.data.physics.alphan + self.data.physics.alphat) ) # Line averaged electron density (IPDG89) # Taken by integrating the parabolic profile over rho in the bounds of 0 and # 1 and dividng by the width of the integration bounds - physics_variables.nd_plasma_electron_line = ( - physics_variables.nd_plasma_electrons_vol_avg - * (1.0 + physics_variables.alphan) + self.data.physics.nd_plasma_electron_line = ( + self.data.physics.nd_plasma_electrons_vol_avg + * (1.0 + self.data.physics.alphan) * (sp.special.gamma(0.5) / 2.0) - * sp.special.gamma(physics_variables.alphan + 1.0) - / sp.special.gamma(physics_variables.alphan + 1.5) + * sp.special.gamma(self.data.physics.alphan + 1.0) + / sp.special.gamma(self.data.physics.alphan + 1.5) ) # Density-weighted temperatures - physics_variables.temp_plasma_electron_density_weighted_kev = ( - physics_variables.temp_plasma_electron_vol_avg_kev - * physics_variables.f_temp_plasma_electron_density_vol_avg + self.data.physics.temp_plasma_electron_density_weighted_kev = ( + self.data.physics.temp_plasma_electron_vol_avg_kev + * self.data.physics.f_temp_plasma_electron_density_vol_avg ) - physics_variables.temp_plasma_ion_density_weighted_kev = ( - physics_variables.temp_plasma_ion_vol_avg_kev - * physics_variables.f_temp_plasma_electron_density_vol_avg + self.data.physics.temp_plasma_ion_density_weighted_kev = ( + self.data.physics.temp_plasma_ion_vol_avg_kev + * self.data.physics.f_temp_plasma_electron_density_vol_avg ) # Central values for temperature (keV) and density (m**-3) - physics_variables.temp_plasma_electron_on_axis_kev = ( - physics_variables.temp_plasma_electron_vol_avg_kev - * (1.0 + physics_variables.alphat) + self.data.physics.temp_plasma_electron_on_axis_kev = ( + self.data.physics.temp_plasma_electron_vol_avg_kev + * (1.0 + self.data.physics.alphat) ) - physics_variables.temp_plasma_ion_on_axis_kev = ( - physics_variables.temp_plasma_ion_vol_avg_kev - * (1.0 + physics_variables.alphat) + self.data.physics.temp_plasma_ion_on_axis_kev = ( + self.data.physics.temp_plasma_ion_vol_avg_kev + * (1.0 + self.data.physics.alphat) ) - physics_variables.nd_plasma_electron_on_axis = ( - physics_variables.nd_plasma_electrons_vol_avg - * (1.0 + physics_variables.alphan) + self.data.physics.nd_plasma_electron_on_axis = ( + self.data.physics.nd_plasma_electrons_vol_avg + * (1.0 + self.data.physics.alphan) ) - physics_variables.nd_plasma_ions_on_axis = ( - physics_variables.nd_plasma_ions_total_vol_avg - * (1.0 + physics_variables.alphan) + self.data.physics.nd_plasma_ions_on_axis = ( + self.data.physics.nd_plasma_ions_total_vol_avg + * (1.0 + self.data.physics.alphan) ) def pedestal_parameterisation(self): @@ -207,35 +206,35 @@ def pedestal_parameterisation(self): integ1 = sp.integrate.simpson(arg1, x=rho, dx=drho) integ2 = sp.integrate.simpson(arg2, x=rho, dx=drho) - physics_variables.integ1 = integ1 - physics_variables.integ2 = integ2 + self.data.physics.integ1 = integ1 + self.data.physics.integ2 = integ2 # Density-weighted temperatures - physics_variables.temp_plasma_electron_density_weighted_kev = integ1 / integ2 - physics_variables.temp_plasma_ion_density_weighted_kev = ( - physics_variables.temp_plasma_ion_vol_avg_kev - / physics_variables.temp_plasma_electron_vol_avg_kev - * physics_variables.temp_plasma_electron_density_weighted_kev + self.data.physics.temp_plasma_electron_density_weighted_kev = integ1 / integ2 + self.data.physics.temp_plasma_ion_density_weighted_kev = ( + self.data.physics.temp_plasma_ion_vol_avg_kev + / self.data.physics.temp_plasma_electron_vol_avg_kev + * self.data.physics.temp_plasma_electron_density_weighted_kev ) # Profile factor; ratio of density-weighted to volume-averaged # temperature - physics_variables.f_temp_plasma_electron_density_vol_avg = ( - physics_variables.temp_plasma_electron_density_weighted_kev - / physics_variables.temp_plasma_electron_vol_avg_kev + self.data.physics.f_temp_plasma_electron_density_vol_avg = ( + self.data.physics.temp_plasma_electron_density_weighted_kev + / self.data.physics.temp_plasma_electron_vol_avg_kev ) # Line-averaged electron density # = integral(n(rho).drho) - physics_variables.nd_plasma_electron_line = self.neprofile.profile_integ + self.data.physics.nd_plasma_electron_line = self.neprofile.profile_integ # Scrape-off density / volume averaged density # (Input value is used if i_plasma_pedestal = 0) self.data.divertor.prn1 = max( 0.01e0, - physics_variables.nd_plasma_separatrix_electron - / physics_variables.nd_plasma_electrons_vol_avg, + self.data.physics.nd_plasma_separatrix_electron + / self.data.physics.nd_plasma_electrons_vol_avg, ) # Preventing division by zero later def calculate_profile_factors(self): @@ -248,42 +247,42 @@ def calculate_profile_factors(self): """ # Central pressure (Pa), from ideal gas law : p = nkT - physics_variables.pres_plasma_thermal_on_axis = ( - physics_variables.nd_plasma_electron_on_axis - * physics_variables.temp_plasma_electron_on_axis_kev - + physics_variables.nd_plasma_ions_on_axis - * physics_variables.temp_plasma_ion_on_axis_kev + self.data.physics.pres_plasma_thermal_on_axis = ( + self.data.physics.nd_plasma_electron_on_axis + * self.data.physics.temp_plasma_electron_on_axis_kev + + self.data.physics.nd_plasma_ions_on_axis + * self.data.physics.temp_plasma_ion_on_axis_kev ) * constants.KILOELECTRON_VOLT # Electron pressure profile (Pa) - physics_variables.pres_plasma_electron_profile = self.neprofile.profile_y * ( + self.data.physics.pres_plasma_electron_profile = self.neprofile.profile_y * ( self.teprofile.profile_y * constants.KILOELECTRON_VOLT ) # Total ion pressure profile (Pa) - physics_variables.pres_plasma_ion_total_profile = ( - physics_variables.nd_plasma_ions_total_vol_avg - * (self.neprofile.profile_y / physics_variables.nd_plasma_electrons_vol_avg) + self.data.physics.pres_plasma_ion_total_profile = ( + self.data.physics.nd_plasma_ions_total_vol_avg + * (self.neprofile.profile_y / self.data.physics.nd_plasma_electrons_vol_avg) ) * ( self.teprofile.profile_y * constants.KILOELECTRON_VOLT - * physics_variables.f_temp_plasma_ion_electron + * self.data.physics.f_temp_plasma_ion_electron ) # Total pressure profile (Pa) - physics_variables.pres_plasma_thermal_total_profile = ( - physics_variables.pres_plasma_electron_profile - + physics_variables.pres_plasma_ion_total_profile + self.data.physics.pres_plasma_thermal_total_profile = ( + self.data.physics.pres_plasma_electron_profile + + self.data.physics.pres_plasma_ion_total_profile ) # Fuel ion pressure profile (Pa) - physics_variables.pres_plasma_fuel_profile = ( - physics_variables.nd_plasma_fuel_ions_vol_avg - * (self.neprofile.profile_y / physics_variables.nd_plasma_electrons_vol_avg) + self.data.physics.pres_plasma_fuel_profile = ( + self.data.physics.nd_plasma_fuel_ions_vol_avg + * (self.neprofile.profile_y / self.data.physics.nd_plasma_electrons_vol_avg) ) * ( self.teprofile.profile_y * constants.KILOELECTRON_VOLT - * physics_variables.f_temp_plasma_ion_electron + * self.data.physics.f_temp_plasma_ion_electron ) # Pressure profile index (only true for a parabolic profile) @@ -292,31 +291,30 @@ def calculate_profile_factors(self): # and

= .T_n where <...> denotes volume-averages and T_n is the # density-weighted temperature - physics_variables.alphap = physics_variables.alphan + physics_variables.alphat + self.data.physics.alphap = self.data.physics.alphan + self.data.physics.alphat # Calculate the volume averaged plasma thermal pressure from the # density-weighted temperatures # Density-weighted temperatures are used as != * - physics_variables.pres_plasma_thermal_vol_avg = ( - physics_variables.nd_plasma_electrons_vol_avg - * physics_variables.temp_plasma_electron_density_weighted_kev - + physics_variables.nd_plasma_ions_total_vol_avg - * physics_variables.temp_plasma_ion_density_weighted_kev + self.data.physics.pres_plasma_thermal_vol_avg = ( + self.data.physics.nd_plasma_electrons_vol_avg + * self.data.physics.temp_plasma_electron_density_weighted_kev + + self.data.physics.nd_plasma_ions_total_vol_avg + * self.data.physics.temp_plasma_ion_density_weighted_kev ) * constants.KILOELECTRON_VOLT # Central plasma current density (A/m^2) # Assumes a parabolic profile for the current density - physics_variables.j_plasma_on_axis = ( - (physics_variables.plasma_current) + self.data.physics.j_plasma_on_axis = ( + (self.data.physics.plasma_current) * 2 / ( - sp.special.beta(0.5, physics_variables.alphaj + 1) - * physics_variables.a_plasma_poloidal + sp.special.beta(0.5, self.data.physics.alphaj + 1) + * self.data.physics.a_plasma_poloidal ) ) - @staticmethod - def calculate_parabolic_profile_factors(): + def calculate_parabolic_profile_factors(self): """Calculate the gradient information for i_plasma_pedestal = 0. This function calculates the gradient information for the plasma profiles at @@ -333,64 +331,64 @@ def calculate_parabolic_profile_factors(): If alphat or alphan is negative. """ if ( - PlasmaProfileShapeType(physics_variables.i_plasma_pedestal) + PlasmaProfileShapeType(self.data.physics.i_plasma_pedestal) == PlasmaProfileShapeType.PARABOLIC_PROFILE ): - if physics_variables.alphat > 1.0: + if self.data.physics.alphat > 1.0: # Rho (normalized radius), where temperature derivative is largest - rho_te_max = 1.0 / np.sqrt(-1.0 + 2.0 * physics_variables.alphat) + rho_te_max = 1.0 / np.sqrt(-1.0 + 2.0 * self.data.physics.alphat) dtdrho_max = ( - -(2.0**physics_variables.alphat) - * (-1.0 + physics_variables.alphat) - ** (-1.0 + physics_variables.alphat) - * physics_variables.alphat - * (-1.0 + 2.0 * physics_variables.alphat) - ** (0.5e0 - physics_variables.alphat) - * physics_variables.temp_plasma_electron_on_axis_kev + -(2.0**self.data.physics.alphat) + * (-1.0 + self.data.physics.alphat) + ** (-1.0 + self.data.physics.alphat) + * self.data.physics.alphat + * (-1.0 + 2.0 * self.data.physics.alphat) + ** (0.5e0 - self.data.physics.alphat) + * self.data.physics.temp_plasma_electron_on_axis_kev ) te_max = ( - physics_variables.temp_plasma_electron_on_axis_kev - * (1 - rho_te_max**2) ** physics_variables.alphat + self.data.physics.temp_plasma_electron_on_axis_kev + * (1 - rho_te_max**2) ** self.data.physics.alphat ) - elif physics_variables.alphat <= 1.0 and physics_variables.alphat > 0.0: + elif self.data.physics.alphat <= 1.0 and self.data.physics.alphat > 0.0: # This makes the profiles very 'boxy' # The gradient diverges here at the edge so define some 'wrong' value of # 0.9 to approximate the gradient rho_te_max = 0.9 dtdrho_max = ( -2.0 - * physics_variables.alphat + * self.data.physics.alphat * rho_te_max - * (1 - rho_te_max**2) ** (-1.0 + physics_variables.alphat) - * physics_variables.temp_plasma_electron_on_axis_kev + * (1 - rho_te_max**2) ** (-1.0 + self.data.physics.alphat) + * self.data.physics.temp_plasma_electron_on_axis_kev ) te_max = ( - physics_variables.temp_plasma_electron_on_axis_kev - * (1 - rho_te_max**2) ** physics_variables.alphat + self.data.physics.temp_plasma_electron_on_axis_kev + * (1 - rho_te_max**2) ** self.data.physics.alphat ) else: raise ProcessValueError( - f"alphat is negative: {physics_variables.alphat}" + f"alphat is negative: {self.data.physics.alphat}" ) # Same for density - if physics_variables.alphan > 1.0: - rho_ne_max = 1.0 / np.sqrt(-1.0 + 2.0 * physics_variables.alphan) + if self.data.physics.alphan > 1.0: + rho_ne_max = 1.0 / np.sqrt(-1.0 + 2.0 * self.data.physics.alphan) dndrho_max = ( - -(2.0**physics_variables.alphan) - * (-1.0 + physics_variables.alphan) - ** (-1.0 + physics_variables.alphan) - * physics_variables.alphan - * (-1.0 + 2.0 * physics_variables.alphan) - ** (0.5 - physics_variables.alphan) - * physics_variables.nd_plasma_electron_on_axis + -(2.0**self.data.physics.alphan) + * (-1.0 + self.data.physics.alphan) + ** (-1.0 + self.data.physics.alphan) + * self.data.physics.alphan + * (-1.0 + 2.0 * self.data.physics.alphan) + ** (0.5 - self.data.physics.alphan) + * self.data.physics.nd_plasma_electron_on_axis ) ne_max = ( - physics_variables.nd_plasma_electron_on_axis - * (1e0 - rho_ne_max**2) ** physics_variables.alphan + self.data.physics.nd_plasma_electron_on_axis + * (1e0 - rho_ne_max**2) ** self.data.physics.alphan ) - elif physics_variables.alphan <= 1.0 and physics_variables.alphan > 0.0: + elif self.data.physics.alphan <= 1.0 and self.data.physics.alphan > 0.0: # This makes the profiles very 'boxy' # The gradient diverges here at the edge so define some 'wrong' value of # 0.9 @@ -398,26 +396,26 @@ def calculate_parabolic_profile_factors(): rho_ne_max = 0.9 dndrho_max = ( -2.0 - * physics_variables.alphan + * self.data.physics.alphan * rho_ne_max - * (1 - rho_ne_max**2) ** (-1.0 + physics_variables.alphan) - * physics_variables.nd_plasma_electron_on_axis + * (1 - rho_ne_max**2) ** (-1.0 + self.data.physics.alphan) + * self.data.physics.nd_plasma_electron_on_axis ) ne_max = ( - physics_variables.nd_plasma_electron_on_axis - * (1 - rho_ne_max**2) ** physics_variables.alphan + self.data.physics.nd_plasma_electron_on_axis + * (1 - rho_ne_max**2) ** self.data.physics.alphan ) else: raise ProcessValueError( - f"alphan is negative: {physics_variables.alphan}" + f"alphan is negative: {self.data.physics.alphan}" ) # set normalized gradient length # te at rho_te_max - physics_variables.gradient_length_te = ( - -dtdrho_max * physics_variables.rminor * rho_te_max / te_max + self.data.physics.gradient_length_te = ( + -dtdrho_max * self.data.physics.rminor * rho_te_max / te_max ) # same for density: - physics_variables.gradient_length_ne = ( - -dndrho_max * physics_variables.rminor * rho_ne_max / ne_max + self.data.physics.gradient_length_ne = ( + -dndrho_max * self.data.physics.rminor * rho_ne_max / ne_max ) diff --git a/process/models/physics/profiles.py b/process/models/physics/profiles.py index 6344511098..03cf25efce 100644 --- a/process/models/physics/profiles.py +++ b/process/models/physics/profiles.py @@ -12,7 +12,7 @@ import numpy as np import scipy as sp -from process.data_structure import physics_variables +from process.core.model import Model logger = logging.getLogger(__name__) @@ -36,17 +36,13 @@ def description(self): return self._description_ -class Profile(ABC): +class Profile(Model, ABC): """Abstract base class used to create and hold profiles (temperature, density)""" - def __init__(self, profile_size: int): + def __init__(self): """ Initialize a Profiles object. - Parameters - ---------- - - profile_size (int): The size of the profile. - Attributes ---------- - profile_size (int): The size of the profile. @@ -55,12 +51,18 @@ def __init__(self, profile_size: int): - profile_integ (int): The integral of the profile_y array. - profile_dx (int): The step size between consecutive values in profile_x. """ - self.profile_size = profile_size + self.profile_size = self.data.physics.n_plasma_profile_elements self.profile_x = np.arange(self.profile_size, dtype=float) self.profile_y = np.zeros(self.profile_size) self.profile_integ = 0 self.profile_dx = 0 + def run(self): + """This model isn't run""" + + def output(self): + """This model doesn't have any output""" + def normalise_profile_x(self): """Normalizes the x-dimension of the profile. @@ -117,11 +119,11 @@ def run(self): self.set_physics_variables() self.calculate_profile_y( self.profile_x, - physics_variables.radius_plasma_pedestal_density_norm, - physics_variables.nd_plasma_electron_on_axis, - physics_variables.nd_plasma_pedestal_electron, - physics_variables.nd_plasma_separatrix_electron, - physics_variables.alphan, + self.data.physics.radius_plasma_pedestal_density_norm, + self.data.physics.nd_plasma_electron_on_axis, + self.data.physics.nd_plasma_pedestal_electron, + self.data.physics.nd_plasma_separatrix_electron, + self.data.physics.alphan, ) self.integrate_profile_y() @@ -153,7 +155,7 @@ def calculate_profile_y( Density peaking parameter. """ if ( - PlasmaProfileShapeType(physics_variables.i_plasma_pedestal) + PlasmaProfileShapeType(self.data.physics.i_plasma_pedestal) == PlasmaProfileShapeType.PARABOLIC_PROFILE ): self.profile_y = n0 * (1 - rho**2) ** alphan @@ -253,28 +255,28 @@ def ncore( def set_physics_variables(self): """Calculates and sets physics variables required for the profile.""" if ( - PlasmaProfileShapeType(physics_variables.i_plasma_pedestal) + PlasmaProfileShapeType(self.data.physics.i_plasma_pedestal) == PlasmaProfileShapeType.PARABOLIC_PROFILE ): - physics_variables.nd_plasma_electron_on_axis = ( - physics_variables.nd_plasma_electrons_vol_avg - * (1.0 + physics_variables.alphan) + self.data.physics.nd_plasma_electron_on_axis = ( + self.data.physics.nd_plasma_electrons_vol_avg + * (1.0 + self.data.physics.alphan) ) elif ( - PlasmaProfileShapeType(physics_variables.i_plasma_pedestal) + PlasmaProfileShapeType(self.data.physics.i_plasma_pedestal) == PlasmaProfileShapeType.PEDESTAL_PROFILE ): - physics_variables.nd_plasma_electron_on_axis = self.ncore( - physics_variables.radius_plasma_pedestal_density_norm, - physics_variables.nd_plasma_pedestal_electron, - physics_variables.nd_plasma_separatrix_electron, - physics_variables.nd_plasma_electrons_vol_avg, - physics_variables.alphan, + self.data.physics.nd_plasma_electron_on_axis = self.ncore( + self.data.physics.radius_plasma_pedestal_density_norm, + self.data.physics.nd_plasma_pedestal_electron, + self.data.physics.nd_plasma_separatrix_electron, + self.data.physics.nd_plasma_electrons_vol_avg, + self.data.physics.alphan, ) - physics_variables.nd_plasma_ions_on_axis = ( - physics_variables.nd_plasma_ions_total_vol_avg - / physics_variables.nd_plasma_electrons_vol_avg - * physics_variables.nd_plasma_electron_on_axis + self.data.physics.nd_plasma_ions_on_axis = ( + self.data.physics.nd_plasma_ions_total_vol_avg + / self.data.physics.nd_plasma_electrons_vol_avg + * self.data.physics.nd_plasma_electron_on_axis ) @@ -290,12 +292,12 @@ def run(self): self.set_physics_variables() self.calculate_profile_y( self.profile_x, - physics_variables.radius_plasma_pedestal_temp_norm, - physics_variables.temp_plasma_electron_on_axis_kev, - physics_variables.temp_plasma_pedestal_kev, - physics_variables.temp_plasma_separatrix_kev, - physics_variables.alphat, - physics_variables.tbeta, + self.data.physics.radius_plasma_pedestal_temp_norm, + self.data.physics.temp_plasma_electron_on_axis_kev, + self.data.physics.temp_plasma_pedestal_kev, + self.data.physics.temp_plasma_separatrix_kev, + self.data.physics.alphat, + self.data.physics.tbeta, ) self.integrate_profile_y() @@ -337,7 +339,7 @@ def calculate_profile_y( https://doi.org/10.13182/FST11-A11650 """ if ( - PlasmaProfileShapeType(physics_variables.i_plasma_pedestal) + PlasmaProfileShapeType(self.data.physics.i_plasma_pedestal) == PlasmaProfileShapeType.PARABOLIC_PROFILE ): # profile values of 0 cause divide by 0 errors so ensure the profile value @@ -440,28 +442,28 @@ def tcore( def set_physics_variables(self): """Calculates and sets physics variables required for the temperature profile.""" if ( - PlasmaProfileShapeType(physics_variables.i_plasma_pedestal) + PlasmaProfileShapeType(self.data.physics.i_plasma_pedestal) == PlasmaProfileShapeType.PARABOLIC_PROFILE ): - physics_variables.temp_plasma_electron_on_axis_kev = ( - physics_variables.temp_plasma_electron_vol_avg_kev - * (1.0 + physics_variables.alphat) + self.data.physics.temp_plasma_electron_on_axis_kev = ( + self.data.physics.temp_plasma_electron_vol_avg_kev + * (1.0 + self.data.physics.alphat) ) elif ( - PlasmaProfileShapeType(physics_variables.i_plasma_pedestal) + PlasmaProfileShapeType(self.data.physics.i_plasma_pedestal) == PlasmaProfileShapeType.PEDESTAL_PROFILE ): - physics_variables.temp_plasma_electron_on_axis_kev = self.tcore( - physics_variables.radius_plasma_pedestal_temp_norm, - physics_variables.temp_plasma_pedestal_kev, - physics_variables.temp_plasma_separatrix_kev, - physics_variables.temp_plasma_electron_vol_avg_kev, - physics_variables.alphat, - physics_variables.tbeta, + self.data.physics.temp_plasma_electron_on_axis_kev = self.tcore( + self.data.physics.radius_plasma_pedestal_temp_norm, + self.data.physics.temp_plasma_pedestal_kev, + self.data.physics.temp_plasma_separatrix_kev, + self.data.physics.temp_plasma_electron_vol_avg_kev, + self.data.physics.alphat, + self.data.physics.tbeta, ) - physics_variables.temp_plasma_ion_on_axis_kev = ( - physics_variables.temp_plasma_ion_vol_avg_kev - / physics_variables.temp_plasma_electron_vol_avg_kev - * physics_variables.temp_plasma_electron_on_axis_kev + self.data.physics.temp_plasma_ion_on_axis_kev = ( + self.data.physics.temp_plasma_ion_vol_avg_kev + / self.data.physics.temp_plasma_electron_vol_avg_kev + * self.data.physics.temp_plasma_electron_on_axis_kev ) diff --git a/process/models/power.py b/process/models/power.py index a81f0c06ff..c68a582584 100644 --- a/process/models/power.py +++ b/process/models/power.py @@ -13,7 +13,6 @@ from process.core.model import Model from process.data_structure import ( numerics, - physics_variables, tfcoil_variables, ) from process.data_structure.pfcoil_variables import NGC2 @@ -319,7 +318,7 @@ def pfpwr(self, output: bool): pfdissipation = np.zeros((5,)) # Bus length - pfbusl = 8.0e0 * physics_variables.rmajor + 140.0e0 + pfbusl = 8.0e0 * self.data.physics.rmajor + 140.0e0 # Find power requirements for PF coils at # self.data.times.t_pulse_cumulative(ktim) @@ -573,9 +572,9 @@ def pfpwr(self, output: bool): # PF wall plug power dissipated in power supply for ohmic heating (MW) # This is additional to that required for moving stored energy around - # p_pf_electric_supplies_mw = physics_variables.p_plasma_ohmic_mw + # p_pf_electric_supplies_mw = self.data.physics.p_plasma_ohmic_mw # / self.data.pf_coil.etapsu - wall_plug_ohmicmw = physics_variables.p_plasma_ohmic_mw * ( + wall_plug_ohmicmw = self.data.physics.p_plasma_ohmic_mw * ( 1.0e0 / self.data.pf_coil.etapsu - 1.0e0 ) # Total mean wall plug power dissipated in PFC and CS power supplies. Issue #713 @@ -882,7 +881,7 @@ def component_thermal_powers(self): + self.data.heat_transport.p_blkt_breeder_pump_mw + self.data.primary_pumping.p_fw_blkt_coolant_pump_mw + self.data.current_drive.p_beam_orbit_loss_mw - + physics_variables.p_fw_alpha_mw + + self.data.physics.p_fw_alpha_mw + self.data.current_drive.p_beam_shine_through_mw ) else: @@ -893,7 +892,7 @@ def component_thermal_powers(self): + self.data.fwbs.p_blkt_nuclear_heat_total_mw + self.data.primary_pumping.p_fw_blkt_coolant_pump_mw + self.data.current_drive.p_beam_orbit_loss_mw - + physics_variables.p_fw_alpha_mw + + self.data.physics.p_fw_alpha_mw + self.data.current_drive.p_beam_shine_through_mw ) @@ -903,7 +902,7 @@ def component_thermal_powers(self): + self.data.fwbs.p_fw_rad_total_mw + self.data.heat_transport.p_fw_coolant_pump_mw + self.data.current_drive.p_beam_orbit_loss_mw - + physics_variables.p_fw_alpha_mw + + self.data.physics.p_fw_alpha_mw + self.data.current_drive.p_beam_shine_through_mw ) @@ -922,7 +921,7 @@ def component_thermal_powers(self): # Total thermal power deposited in divertor (MW) self.data.power.p_div_heat_deposited_mw = ( - physics_variables.p_plasma_separatrix_mw + self.data.physics.p_plasma_separatrix_mw + ( self.data.fwbs.p_div_nuclear_heat_total_mw + self.data.fwbs.p_div_rad_total_mw @@ -1114,7 +1113,7 @@ def output_plant_thermal_powers(self): self.outfile, "Lost alpha-particle heat deposited in FW [MW]", "(p_fw_alpha_mw)", - physics_variables.p_fw_alpha_mw, + self.data.physics.p_fw_alpha_mw, ) po.ovarre( self.outfile, @@ -1239,7 +1238,7 @@ def output_plant_thermal_powers(self): self.outfile, "Plasma separatrix power deposited in divertor [MW]", "(p_plasma_separatrix_mw)", - physics_variables.p_plasma_separatrix_mw, + self.data.physics.p_plasma_separatrix_mw, ) po.ovarre( self.outfile, @@ -1612,7 +1611,7 @@ def plant_electric_production(self): power and heat transport balance, assumptions, and efficiency metrics to the specified output file. """ - if physics_variables.itart == 1 and tfcoil_variables.i_tf_sup == 0: + if self.data.physics.itart == 1 and tfcoil_variables.i_tf_sup == 0: self.data.power.p_cp_coolant_pump_elec_mw = ( 1.0e-6 * tfcoil_variables.p_cp_coolant_pump_elec ) @@ -1738,7 +1737,7 @@ def plant_electric_production(self): p_pf_electric_supplies_mw=self.data.pf_coil.p_pf_electric_supplies_mw, p_coolant_pump_elec_total_mw=self.data.heat_transport.p_coolant_pump_elec_total_mw, p_hcd_electric_total_mw=self.data.heat_transport.p_hcd_electric_total_mw, - p_fusion_total_mw=physics_variables.p_fusion_total_mw, + p_fusion_total_mw=self.data.physics.p_fusion_total_mw, p_plant_electric_gross_mw=self.data.heat_transport.p_plant_electric_gross_mw, p_plant_electric_net_mw=self.data.heat_transport.p_plant_electric_net_mw, ) @@ -2294,7 +2293,7 @@ def tfpwcall(self, output: bool): ) = self.tfcpwr( output, itfka, - physics_variables.rmajor, + self.data.physics.rmajor, tfcoil_variables.n_tf_coils, tfcoil_variables.v_tf_coil_dump_quench_kv, ettfmj, diff --git a/process/models/pulse.py b/process/models/pulse.py index 3adda00143..74b2e51109 100644 --- a/process/models/pulse.py +++ b/process/models/pulse.py @@ -5,10 +5,7 @@ from process.core import constants from process.core import process_output as po from process.core.model import Model -from process.data_structure import ( - numerics, - physics_variables, -) +from process.data_structure import numerics logger = logging.getLogger(__name__) @@ -41,7 +38,7 @@ def run(self, output: bool = False): self.data.times.t_plant_pulse_burn = self.calculate_burn_time( vs_cs_pf_total_burn=self.data.pf_coil.vs_cs_pf_total_burn, - v_plasma_loop_burn=physics_variables.v_plasma_loop_burn, + v_plasma_loop_burn=self.data.physics.v_plasma_loop_burn, t_plant_pulse_fusion_ramp=self.data.times.t_plant_pulse_fusion_ramp, ) @@ -88,7 +85,7 @@ def tohswg(self, output: bool): # Central Solenoid bus resistance (ohms) (assumed to include power supply) # Bus parameters taken from routine PFPWR. - pfbusl = 8.0e0 * physics_variables.rmajor + 140.0e0 + pfbusl = 8.0e0 * self.data.physics.rmajor + 140.0e0 albusa = ( abs( self.data.pf_coil.c_pf_coil_turn_peak_input[ @@ -123,7 +120,7 @@ def tohswg(self, output: bool): # Maximum rate of change of plasma current (A/s) # - now a function of the plasma current itself (previously just 0.5e6) - ipdot = 0.0455e0 * physics_variables.plasma_current + ipdot = 0.0455e0 * self.data.physics.plasma_current # Minimum plasma current ramp-up time (s) # - corrected (bus resistance is not a function of self.data.pf_coil.turns) diff --git a/process/models/shield.py b/process/models/shield.py index 3b096fd912..fa87e4cced 100644 --- a/process/models/shield.py +++ b/process/models/shield.py @@ -5,7 +5,6 @@ from process.core import constants from process.core import process_output as po from process.core.model import Model -from process.data_structure import physics_variables from process.models.build import FwBlktVVShape from process.models.engineering.ivc_functions import ( dshellarea, @@ -47,7 +46,7 @@ def run(self): ) # D-shaped blanket and shield if ( - physics_variables.itart == 1 + self.data.physics.itart == 1 or self.data.fwbs.i_fw_blkt_vv_shape == FwBlktVVShape.D_SHAPED ): ( @@ -59,7 +58,7 @@ def run(self): dr_shld_inboard=self.data.build.dr_shld_inboard, dr_fw_inboard=self.data.build.dr_fw_inboard, dr_fw_plasma_gap_inboard=self.data.build.dr_fw_plasma_gap_inboard, - rminor=physics_variables.rminor, + rminor=self.data.physics.rminor, dr_fw_plasma_gap_outboard=self.data.build.dr_fw_plasma_gap_outboard, dr_fw_outboard=self.data.build.dr_fw_outboard, dr_blkt_inboard=self.data.build.dr_blkt_inboard, @@ -76,7 +75,7 @@ def run(self): dr_shld_inboard=self.data.build.dr_shld_inboard, dr_fw_inboard=self.data.build.dr_fw_inboard, dr_fw_plasma_gap_inboard=self.data.build.dr_fw_plasma_gap_inboard, - rminor=physics_variables.rminor, + rminor=self.data.physics.rminor, dr_fw_plasma_gap_outboard=self.data.build.dr_fw_plasma_gap_outboard, dr_fw_outboard=self.data.build.dr_fw_outboard, dr_blkt_inboard=self.data.build.dr_blkt_inboard, @@ -94,10 +93,10 @@ def run(self): ) = self.calculate_elliptical_shield_areas( r_shld_inboard_inner=self.data.build.r_shld_inboard_inner, r_shld_outboard_outer=self.data.build.r_shld_outboard_outer, - rmajor=physics_variables.rmajor, - triang=physics_variables.triang, + rmajor=self.data.physics.rmajor, + triang=self.data.physics.triang, dr_shld_inboard=self.data.build.dr_shld_inboard, - rminor=physics_variables.rminor, + rminor=self.data.physics.rminor, dz_shld_half=self.data.blanket.dz_shld_half, dr_shld_outboard=self.data.build.dr_shld_outboard, ) @@ -109,10 +108,10 @@ def run(self): ) = self.calculate_elliptical_shield_volumes( r_shld_inboard_inner=self.data.build.r_shld_inboard_inner, r_shld_outboard_outer=self.data.build.r_shld_outboard_outer, - rmajor=physics_variables.rmajor, - triang=physics_variables.triang, + rmajor=self.data.physics.rmajor, + triang=self.data.physics.triang, dr_shld_inboard=self.data.build.dr_shld_inboard, - rminor=physics_variables.rminor, + rminor=self.data.physics.rminor, dz_shld_half=self.data.blanket.dz_shld_half, dr_shld_outboard=self.data.build.dr_shld_outboard, dz_shld_upper=self.data.build.dz_shld_upper, diff --git a/process/models/stellarator/build.py b/process/models/stellarator/build.py index 64c6087cac..62897c834f 100644 --- a/process/models/stellarator/build.py +++ b/process/models/stellarator/build.py @@ -1,6 +1,5 @@ from process.core import process_output as po from process.core.model import DataStructure -from process.data_structure import physics_variables def st_build(stellarator, f_output: bool, data: DataStructure): @@ -44,7 +43,7 @@ def st_build(stellarator, f_output: bool, data: DataStructure): ) data.build.dr_fw_outboard = data.build.dr_fw_inboard - data.build.dr_bore = physics_variables.rmajor - ( + data.build.dr_bore = data.physics.rmajor - ( data.build.dr_cs + data.build.dr_cs_tf_gap + data.build.dr_tf_inboard @@ -54,10 +53,10 @@ def st_build(stellarator, f_output: bool, data: DataStructure): + data.build.dr_blkt_inboard + data.build.dr_fw_inboard + data.build.dr_fw_plasma_gap_inboard - + physics_variables.rminor + + data.physics.rminor ) - # Radial build to centre of plasma (should be equal to physics_variables.rmajor) + # Radial build to centre of plasma (should be equal to data.physics.rmajor) data.build.rbld = ( data.build.dr_bore + data.build.dr_cs @@ -69,10 +68,10 @@ def st_build(stellarator, f_output: bool, data: DataStructure): + data.build.dr_blkt_inboard + data.build.dr_fw_inboard + data.build.dr_fw_plasma_gap_inboard - + physics_variables.rminor + + data.physics.rminor ) - # Bc stellarators cannot scale physics_variables.rminor reasonably well an additional constraint equation is required, + # Bc stellarators cannot scale data.physics.rminor reasonably well an additional constraint equation is required, # that ensures that there is enough space between coils and plasma. data.build.required_radial_space = ( data.build.dr_tf_inboard / 2.0e0 @@ -87,17 +86,17 @@ def st_build(stellarator, f_output: bool, data: DataStructure): # derivative_min_LCFS_coils_dist for how strong the stellarator shape changes wrt to aspect ratio data.build.available_radial_space = ( data.stellarator.r_coil_minor * data.stellarator.f_coil_shape - - physics_variables.rminor + - data.physics.rminor ) +data.stellarator_config.stella_config_derivative_min_lcfs_coils_dist * ( - physics_variables.rminor + data.physics.rminor - data.stellarator.f_st_rmajor * data.stellarator_config.stella_config_rminor_ref ) # Radius to inner edge of inboard shield data.build.r_shld_inboard_inner = ( - physics_variables.rmajor - - physics_variables.rminor + data.physics.rmajor + - data.physics.rminor - data.build.dr_fw_plasma_gap_inboard - data.build.dr_fw_inboard - data.build.dr_blkt_inboard @@ -106,8 +105,8 @@ def st_build(stellarator, f_output: bool, data: DataStructure): # Radius to outer edge of outboard shield data.build.r_shld_outboard_outer = ( - physics_variables.rmajor - + physics_variables.rminor + data.physics.rmajor + + data.physics.rminor + data.build.dr_fw_plasma_gap_outboard + data.build.dr_fw_outboard + data.build.dr_blkt_outboard @@ -139,10 +138,10 @@ def st_build(stellarator, f_output: bool, data: DataStructure): + data.build.dr_blkt_inboard + data.build.dr_fw_inboard + data.build.dr_fw_plasma_gap_inboard - + physics_variables.rminor + + data.physics.rminor ) + ( - physics_variables.rminor + data.physics.rminor + data.build.dr_fw_plasma_gap_outboard + data.build.dr_fw_outboard + data.build.dr_blkt_outboard @@ -154,16 +153,16 @@ def st_build(stellarator, f_output: bool, data: DataStructure): # Outer divertor strike point radius, set equal to major radius - data.build.rspo = physics_variables.rmajor + data.build.rspo = data.physics.rmajor # First wall area: scales with minor radius # Average minor radius of the first wall - awall = physics_variables.rminor + 0.5e0 * ( + awall = data.physics.rminor + 0.5e0 * ( data.build.dr_fw_plasma_gap_inboard + data.build.dr_fw_plasma_gap_outboard ) data.first_wall.a_fw_total = ( - physics_variables.a_plasma_surface * awall / physics_variables.rminor + data.physics.a_plasma_surface * awall / data.physics.rminor ) if data.heat_transport.ipowerflow == 0: @@ -312,20 +311,20 @@ def output(stellarator, data): data.build.dr_fw_plasma_gap_inboard, ) - radius += physics_variables.rminor + radius += data.physics.rminor po.obuild( stellarator.outfile, "Plasma geometric centre", - physics_variables.rminor, + data.physics.rminor, radius, "(rminor)", ) - radius += physics_variables.rminor + radius += data.physics.rminor po.obuild( stellarator.outfile, "Plasma outboard edge", - physics_variables.rminor, + data.physics.rminor, radius, "(rminor)", ) diff --git a/process/models/stellarator/coils/quench.py b/process/models/stellarator/coils/quench.py index fed5fd484d..2619012cda 100644 --- a/process/models/stellarator/coils/quench.py +++ b/process/models/stellarator/coils/quench.py @@ -4,7 +4,6 @@ from process.core.model import DataStructure from process.data_structure import ( - physics_variables, rebco_variables, superconducting_tf_coil_variables, tfcoil_variables, @@ -26,8 +25,8 @@ def calculate_quench_protection(coilcurrent, data: DataStructure): # This copied from the tokamak module: # Radial position of vacuum vessel [m] rad_vv_in = ( - physics_variables.rmajor - - physics_variables.rminor + data.physics.rmajor + - data.physics.rminor - data.build.dr_fw_plasma_gap_inboard - data.build.dr_fw_inboard - data.build.dr_blkt_inboard @@ -35,8 +34,8 @@ def calculate_quench_protection(coilcurrent, data: DataStructure): - data.build.dr_shld_inboard ) rad_vv_out = ( - physics_variables.rmajor - + physics_variables.rminor + data.physics.rmajor + + data.physics.rminor + data.build.dr_fw_plasma_gap_outboard + data.build.dr_fw_outboard + data.build.dr_blkt_outboard @@ -47,7 +46,7 @@ def calculate_quench_protection(coilcurrent, data: DataStructure): # Stellarator version is working on the W7-X scaling, so we should actual use vv r_major # plasma r_major is just an approximation, but exact calculations require 3D geometry # Maybe it can be added to the stella_config file in the future - rad_vv = physics_variables.rmajor + rad_vv = data.physics.rmajor # MN/m^3 f_vv_actual = calculate_vv_max_force_density_from_W7X_scaling(rad_vv, data) @@ -132,11 +131,11 @@ def calculate_vv_max_force_density_from_W7X_scaling( force_density_ref * ( b_ref - / physics_variables.b_plasma_toroidal_on_axis + / data.physics.b_plasma_toroidal_on_axis * i_total_ref / tfcoil_variables.c_tf_total * rminor_ref**2 - / physics_variables.rminor**2 + / data.physics.rminor**2 ) ** (-1) * ( diff --git a/process/models/stellarator/denisty_limits.py b/process/models/stellarator/denisty_limits.py index 7f4e8b1c19..4e6363393f 100644 --- a/process/models/stellarator/denisty_limits.py +++ b/process/models/stellarator/denisty_limits.py @@ -5,7 +5,6 @@ from process.core import process_output as po from process.core.exceptions import ProcessValueError -from process.data_structure import physics_variables logger = logging.getLogger(__name__) @@ -26,28 +25,30 @@ def st_denisty_limits(stellarator, f_output, data): """ # Set the required value for icc=5 - physics_variables.nd_plasma_electrons_max = st_sudo_density_limit( - physics_variables.b_plasma_toroidal_on_axis, - physics_variables.p_plasma_loss_mw, - physics_variables.rmajor, - physics_variables.rminor, + data.physics.nd_plasma_electrons_max = st_sudo_density_limit( + data.physics.b_plasma_toroidal_on_axis, + data.physics.p_plasma_loss_mw, + data.physics.rmajor, + data.physics.rminor, + data, ) # Calculates the ECRH parameters ne0_max_ECRH, bt_ecrh = st_d_limit_ecrh( data.stellarator.max_gyrotron_frequency, - physics_variables.b_plasma_toroidal_on_axis, + data.physics.b_plasma_toroidal_on_axis, + data.physics.i_plasma_pedestal, ) - ne0_max_ECRH = min(physics_variables.nd_plasma_electron_on_axis, ne0_max_ECRH) - bt_ecrh = min(physics_variables.b_plasma_toroidal_on_axis, bt_ecrh) + ne0_max_ECRH = min(data.physics.nd_plasma_electron_on_axis, ne0_max_ECRH) + bt_ecrh = min(data.physics.b_plasma_toroidal_on_axis, bt_ecrh) if f_output: output(stellarator, bt_ecrh, ne0_max_ECRH, data) -def st_sudo_density_limit(b_plasma_toroidal_on_axis, powht, rmajor, rminor): +def st_sudo_density_limit(b_plasma_toroidal_on_axis, powht, rmajor, rminor, data): """Routine to calculate the Sudo density limit in a stellarator This routine calculates the density limit for a stellarator. @@ -60,11 +61,13 @@ def st_sudo_density_limit(b_plasma_toroidal_on_axis, powht, rmajor, rminor): b_plasma_toroidal_on_axis : Toroidal field on axis (T) powht : - Absored heating power (MW) + Absorbed heating power (MW) rmajor : Plama major radius (m) rminor : Plama minor radius (m) + data: DataStructure + data structure object Returns ------- @@ -93,16 +96,16 @@ def st_sudo_density_limit(b_plasma_toroidal_on_axis, powht, rmajor, rminor): nd_plasma_electron_max_array = ( dnlamx - * physics_variables.nd_plasma_electrons_vol_avg - / physics_variables.nd_plasma_electron_line + * data.physics.nd_plasma_electrons_vol_avg + / data.physics.nd_plasma_electron_line ) - physics_variables.nd_plasma_electrons_max = nd_plasma_electron_max_array + data.physics.nd_plasma_electrons_max = nd_plasma_electron_max_array return nd_plasma_electron_max_array -def st_d_limit_ecrh(gyro_frequency_max, bt_input): +def st_d_limit_ecrh(gyro_frequency_max, bt_input, i_plasma_pedestal): """Routine to calculate the density limit due to an ECRH heating scheme on axis depending on an assumed maximal available gyrotron frequency. @@ -132,18 +135,16 @@ def st_d_limit_ecrh(gyro_frequency_max, bt_input): ne0_max = max(0.0e0, 3.142077e-4 * gyro_frequency**2) # Check if parabolic profiles are used: - if physics_variables.i_plasma_pedestal == 0: + if i_plasma_pedestal == 0: # Parabolic profiles used, use analytical formula: dlimit_ecrh = ne0_max else: - logger.error( - "It was used physics_variables.i_plasma_pedestal = 1 in a stellarator routine." - ) + logger.error("It was used i_plasma_pedestal = 1 in a stellarator routine.") return dlimit_ecrh, bt_max -def power_at_ignition_point(stellarator, gyro_frequency_max, te0_available): +def power_at_ignition_point(stellarator, gyro_frequency_max, te0_available, data): """Routine to calculate if the plasma is ignitable with the current values for the B field. Assumes current ECRH achievable peak temperature (which is inaccurate as the cordey pass should be calculated) @@ -160,6 +161,8 @@ def power_at_ignition_point(stellarator, gyro_frequency_max, te0_available): te0_available : Reachable peak electron temperature, reached by ECRH (KEV) + data: DataStructure + data structure object Returns ------- @@ -169,25 +172,27 @@ def power_at_ignition_point(stellarator, gyro_frequency_max, te0_available): Heating Power loss at ignition point (MW) """ - te_old = copy(physics_variables.temp_plasma_electron_vol_avg_kev) - # Volume averaged physics_variables.te from te0_achievable - physics_variables.temp_plasma_electron_vol_avg_kev = te0_available / ( - 1.0e0 + physics_variables.alphat + te_old = copy(data.physics.temp_plasma_electron_vol_avg_kev) + # Volume averaged data.physics.te from te0_achievable + data.physics.temp_plasma_electron_vol_avg_kev = te0_available / ( + 1.0e0 + data.physics.alphat ) ne0_max, bt_ecrh_max = st_d_limit_ecrh( - gyro_frequency_max, physics_variables.b_plasma_toroidal_on_axis + gyro_frequency_max, + data.physics.b_plasma_toroidal_on_axis, + data.physics.i_plasma_pedestal, ) # Now go to point where ECRH is still available # In density.. - dene_old = copy(physics_variables.nd_plasma_electrons_vol_avg) - physics_variables.nd_plasma_electrons_vol_avg = min( - dene_old, ne0_max / (1.0e0 + physics_variables.alphan) + dene_old = copy(data.physics.nd_plasma_electrons_vol_avg) + data.physics.nd_plasma_electrons_vol_avg = min( + dene_old, ne0_max / (1.0e0 + data.physics.alphan) ) # And B-field.. - bt_old = copy(physics_variables.b_plasma_toroidal_on_axis) - physics_variables.b_plasma_toroidal_on_axis = min( - bt_ecrh_max, physics_variables.b_plasma_toroidal_on_axis + bt_old = copy(data.physics.b_plasma_toroidal_on_axis) + data.physics.b_plasma_toroidal_on_axis = min( + bt_ecrh_max, data.physics.b_plasma_toroidal_on_axis ) stellarator.st_phys(False) @@ -196,15 +201,15 @@ def power_at_ignition_point(stellarator, gyro_frequency_max, te0_available): ) # The second call seems to be necessary for all values to "converge" (and is sufficient) powerht_out = max( - copy(physics_variables.p_plasma_loss_mw), 0.00001e0 + copy(data.physics.p_plasma_loss_mw), 0.00001e0 ) # the radiation module sometimes returns negative heating power - pscalingmw_out = copy(physics_variables.pscalingmw) + pscalingmw_out = copy(data.physics.pscalingmw) # Reverse it and do it again because anything more efficiently isn't suitable with the current implementation # This is bad practice but seems to be necessary as of now: - physics_variables.temp_plasma_electron_vol_avg_kev = te_old - physics_variables.nd_plasma_electrons_vol_avg = dene_old - physics_variables.b_plasma_toroidal_on_axis = bt_old + data.physics.temp_plasma_electron_vol_avg_kev = te_old + data.physics.nd_plasma_electrons_vol_avg = dene_old + data.physics.b_plasma_toroidal_on_axis = bt_old # The second call seems to be necessary for all values to "converge" (and is sufficient) stellarator.st_phys(False) @@ -227,20 +232,20 @@ def output(stellarator, bt_ecrh, ne0_max_ECRH, data): stellarator.outfile, "Operating point: bfield", "(b_plasma_toroidal_on_axis)", - physics_variables.b_plasma_toroidal_on_axis, + data.physics.b_plasma_toroidal_on_axis, ) po.ovarre( stellarator.outfile, "Operating point: Peak density", "(nd_plasma_electron_on_axis)", - physics_variables.nd_plasma_electron_on_axis, + data.physics.nd_plasma_electron_on_axis, ) po.ovarre( stellarator.outfile, "Operating point: Peak temperature", "(temp_plasma_electron_on_axis_kev)", - physics_variables.temp_plasma_electron_on_axis_kev, + data.physics.temp_plasma_electron_on_axis_kev, ) po.ovarre(stellarator.outfile, "Ignition point: bfield (T)", "(bt_ecrh)", bt_ecrh) @@ -261,6 +266,7 @@ def output(stellarator, bt_ecrh, ne0_max_ECRH, data): stellarator, data.stellarator.max_gyrotron_frequency, data.stellarator.te0_ecrh_achievable, + data, ) po.ovarre( stellarator.outfile, diff --git a/process/models/stellarator/divertor.py b/process/models/stellarator/divertor.py index ded0770c94..e8393c7e78 100644 --- a/process/models/stellarator/divertor.py +++ b/process/models/stellarator/divertor.py @@ -3,9 +3,6 @@ from process.core import constants from process.core import process_output as po from process.core.model import DataStructure -from process.data_structure import ( - physics_variables, -) def st_div(stellarator, f_output: bool, data: DataStructure): @@ -27,8 +24,8 @@ def st_div(stellarator, f_output: bool, data: DataStructure): Stellarator Divertor Model for the Systems Code PROCESS, F. Warmer, 21/06/2013 """ Theta = data.stellarator.flpitch # ~bmn [rad] field line pitch - r = physics_variables.rmajor - p_div = physics_variables.p_plasma_separatrix_mw + r = data.physics.rmajor + p_div = data.physics.p_plasma_separatrix_mw alpha = data.divertor.anginc xi_p = data.divertor.xpertin T_scrape = data.divertor.tdiv @@ -39,7 +36,7 @@ def st_div(stellarator, f_output: bool, data: DataStructure): # Sound speed of particles (m/s) - c_s = np.sqrt(e / (physics_variables.m_fuel_amu * constants.UMASS)) + c_s = np.sqrt(e / (data.physics.m_fuel_amu * constants.UMASS)) # Island size (m) @@ -139,7 +136,7 @@ def output(stellarator, a_eff, l_d, l_w, f_x, l_q, w_r, Delta, data: DataStructu stellarator.outfile, "Power to divertor (MW)", "(p_plasma_separatrix_mw.)", - physics_variables.p_plasma_separatrix_mw, + data.physics.p_plasma_separatrix_mw, ) po.ovarre( stellarator.outfile, diff --git a/process/models/stellarator/heating.py b/process/models/stellarator/heating.py index 46313b35bd..302c63fd6f 100644 --- a/process/models/stellarator/heating.py +++ b/process/models/stellarator/heating.py @@ -3,7 +3,6 @@ from process.core import process_output as po from process.core.exceptions import ProcessValueError from process.core.model import DataStructure -from process.data_structure import physics_variables logger = logging.getLogger(__name__) @@ -117,16 +116,16 @@ def st_heat(stellarator, f_output: bool, data: DataStructure): abs( data.current_drive.p_hcd_injected_total_mw + data.current_drive.p_beam_orbit_loss_mw - + physics_variables.p_plasma_ohmic_mw + + data.physics.p_plasma_ohmic_mw ) < 1e-6 ): data.current_drive.big_q_plasma = 1e18 else: - data.current_drive.big_q_plasma = physics_variables.p_fusion_total_mw / ( + data.current_drive.big_q_plasma = data.physics.p_fusion_total_mw / ( data.current_drive.p_hcd_injected_total_mw + data.current_drive.p_beam_orbit_loss_mw - + physics_variables.p_plasma_ohmic_mw + + data.physics.p_plasma_ohmic_mw ) if f_output: @@ -143,7 +142,7 @@ def output(stellarator, data: DataStructure, f_p_beam_injected_ions=None): elif data.stellarator.isthtr == 3: po.ocmmnt(stellarator.outfile, "Neutral Beam Injection Heating") - if physics_variables.i_plasma_ignited == 1: + if data.physics.i_plasma_ignited == 1: po.ocmmnt( stellarator.outfile, "Ignited plasma; injected power only used for start-up phase", diff --git a/process/models/stellarator/initialization.py b/process/models/stellarator/initialization.py index 15801a286f..f5f02c26de 100644 --- a/process/models/stellarator/initialization.py +++ b/process/models/stellarator/initialization.py @@ -1,8 +1,5 @@ from process.core.model import DataStructure -from process.data_structure import ( - numerics, - physics_variables, -) +from process.data_structure import numerics def st_init(data: DataStructure): @@ -30,11 +27,11 @@ def st_init(data: DataStructure): # Physics quantities - physics_variables.i_plasma_pedestal = 0 - physics_variables.beta_norm_max = 0.0 - physics_variables.kappa95 = 1.0 - physics_variables.triang = 0.0 - physics_variables.q95 = 1.03 + data.physics.i_plasma_pedestal = 0 + data.physics.beta_norm_max = 0.0 + data.physics.kappa95 = 1.0 + data.physics.triang = 0.0 + data.physics.q95 = 1.03 # Turn off current drive diff --git a/process/models/stellarator/neoclassics.py b/process/models/stellarator/neoclassics.py index 23ecb21c3d..f555675c7a 100644 --- a/process/models/stellarator/neoclassics.py +++ b/process/models/stellarator/neoclassics.py @@ -4,7 +4,6 @@ from process.core import constants from process.core.model import Model -from process.data_structure import physics_variables from process.models.stellarator.stellarator import KEV logger = logging.getLogger(__name__) @@ -146,126 +145,126 @@ def init_profile_values_from_PROCESS(self, rho): """ tempe = ( - physics_variables.temp_plasma_electron_on_axis_kev - * (1 - rho**2) ** physics_variables.alphat + self.data.physics.temp_plasma_electron_on_axis_kev + * (1 - rho**2) ** self.data.physics.alphat * KEV ) tempT = ( - physics_variables.temp_plasma_ion_on_axis_kev - * (1 - rho**2) ** physics_variables.alphat + self.data.physics.temp_plasma_ion_on_axis_kev + * (1 - rho**2) ** self.data.physics.alphat * KEV ) tempD = ( - physics_variables.temp_plasma_ion_on_axis_kev - * (1 - rho**2) ** physics_variables.alphat + self.data.physics.temp_plasma_ion_on_axis_kev + * (1 - rho**2) ** self.data.physics.alphat * KEV ) tempa = ( - physics_variables.temp_plasma_ion_on_axis_kev - * (1 - rho**2) ** physics_variables.alphat + self.data.physics.temp_plasma_ion_on_axis_kev + * (1 - rho**2) ** self.data.physics.alphat * KEV ) dense = ( - physics_variables.nd_plasma_electron_on_axis - * (1 - rho**2) ** physics_variables.alphan + self.data.physics.nd_plasma_electron_on_axis + * (1 - rho**2) ** self.data.physics.alphan ) densT = ( - (1 - physics_variables.f_plasma_fuel_deuterium) - * physics_variables.nd_plasma_ions_on_axis - * (1 - rho**2) ** physics_variables.alphan + (1 - self.data.physics.f_plasma_fuel_deuterium) + * self.data.physics.nd_plasma_ions_on_axis + * (1 - rho**2) ** self.data.physics.alphan ) densD = ( - physics_variables.f_plasma_fuel_deuterium - * physics_variables.nd_plasma_ions_on_axis - * (1 - rho**2) ** physics_variables.alphan + self.data.physics.f_plasma_fuel_deuterium + * self.data.physics.nd_plasma_ions_on_axis + * (1 - rho**2) ** self.data.physics.alphan ) densa = ( - physics_variables.nd_plasma_alphas_vol_avg - * (1 + physics_variables.alphan) - * (1 - rho**2) ** physics_variables.alphan + self.data.physics.nd_plasma_alphas_vol_avg + * (1 + self.data.physics.alphan) + * (1 - rho**2) ** self.data.physics.alphan ) # Derivatives in real space dr_tempe = ( -2.0 * 1.0 - / physics_variables.rminor - * physics_variables.temp_plasma_electron_on_axis_kev + / self.data.physics.rminor + * self.data.physics.temp_plasma_electron_on_axis_kev * rho - * (1.0 - rho**2) ** (physics_variables.alphat - 1.0) - * physics_variables.alphat + * (1.0 - rho**2) ** (self.data.physics.alphat - 1.0) + * self.data.physics.alphat * KEV ) dr_tempT = ( -2.0 * 1.0 - / physics_variables.rminor - * physics_variables.temp_plasma_ion_on_axis_kev + / self.data.physics.rminor + * self.data.physics.temp_plasma_ion_on_axis_kev * rho - * (1.0 - rho**2) ** (physics_variables.alphat - 1.0) - * physics_variables.alphat + * (1.0 - rho**2) ** (self.data.physics.alphat - 1.0) + * self.data.physics.alphat * KEV ) dr_tempD = ( -2.0 * 1.0 - / physics_variables.rminor - * physics_variables.temp_plasma_ion_on_axis_kev + / self.data.physics.rminor + * self.data.physics.temp_plasma_ion_on_axis_kev * rho - * (1.0 - rho**2) ** (physics_variables.alphat - 1.0) - * physics_variables.alphat + * (1.0 - rho**2) ** (self.data.physics.alphat - 1.0) + * self.data.physics.alphat * KEV ) dr_tempa = ( -2.0 * 1.0 - / physics_variables.rminor - * physics_variables.temp_plasma_ion_on_axis_kev + / self.data.physics.rminor + * self.data.physics.temp_plasma_ion_on_axis_kev * rho - * (1.0 - rho**2) ** (physics_variables.alphat - 1.0) - * physics_variables.alphat + * (1.0 - rho**2) ** (self.data.physics.alphat - 1.0) + * self.data.physics.alphat * KEV ) dr_dense = ( -2.0 * 1.0 - / physics_variables.rminor + / self.data.physics.rminor * rho - * physics_variables.nd_plasma_electron_on_axis - * (1.0 - rho**2) ** (physics_variables.alphan - 1.0) - * physics_variables.alphan + * self.data.physics.nd_plasma_electron_on_axis + * (1.0 - rho**2) ** (self.data.physics.alphan - 1.0) + * self.data.physics.alphan ) dr_densT = ( -2.0 * 1.0 - / physics_variables.rminor + / self.data.physics.rminor * rho - * (1 - physics_variables.f_plasma_fuel_deuterium) - * physics_variables.nd_plasma_ions_on_axis - * (1.0 - rho**2) ** (physics_variables.alphan - 1.0) - * physics_variables.alphan + * (1 - self.data.physics.f_plasma_fuel_deuterium) + * self.data.physics.nd_plasma_ions_on_axis + * (1.0 - rho**2) ** (self.data.physics.alphan - 1.0) + * self.data.physics.alphan ) dr_densD = ( -2.0 * 1.0 - / physics_variables.rminor + / self.data.physics.rminor * rho - * physics_variables.f_plasma_fuel_deuterium - * physics_variables.nd_plasma_ions_on_axis - * (1.0 - rho**2) ** (physics_variables.alphan - 1.0) - * physics_variables.alphan + * self.data.physics.f_plasma_fuel_deuterium + * self.data.physics.nd_plasma_ions_on_axis + * (1.0 - rho**2) ** (self.data.physics.alphan - 1.0) + * self.data.physics.alphan ) dr_densa = ( -2.0 * 1.0 - / physics_variables.rminor + / self.data.physics.rminor * rho - * physics_variables.nd_plasma_alphas_vol_avg - * (1 + physics_variables.alphan) - * (1.0 - rho**2) ** (physics_variables.alphan - 1.0) - * physics_variables.alphan + * self.data.physics.nd_plasma_alphas_vol_avg + * (1 + self.data.physics.alphan) + * (1.0 - rho**2) ** (self.data.physics.alphan - 1.0) + * self.data.physics.alphan ) dens = np.array([dense, densD, densT, densa]) @@ -288,22 +287,22 @@ def calc_neoclassics(self): q_PROCESS = ( ( - physics_variables.f_p_alpha_plasma_deposited - * physics_variables.pden_alpha_total_mw - - physics_variables.pden_plasma_core_rad_mw + self.data.physics.f_p_alpha_plasma_deposited + * self.data.physics.pden_alpha_total_mw + - self.data.physics.pden_plasma_core_rad_mw ) - * physics_variables.vol_plasma - / physics_variables.a_plasma_surface + * self.data.physics.vol_plasma + / self.data.physics.a_plasma_surface * self.data.impurity_radiation.radius_plasma_core_norm ) q_PROCESS_r1 = ( ( - physics_variables.f_p_alpha_plasma_deposited - * physics_variables.pden_alpha_total_mw - - physics_variables.pden_plasma_core_rad_mw + self.data.physics.f_p_alpha_plasma_deposited + * self.data.physics.pden_alpha_total_mw + - self.data.physics.pden_plasma_core_rad_mw ) - * physics_variables.vol_plasma - / physics_variables.a_plasma_surface + * self.data.physics.vol_plasma + / self.data.physics.a_plasma_surface ) q_neo = sum(self.data.neoclassics.q_flux * 1e-6) @@ -362,18 +361,18 @@ def calc_neoclassics(self): dndt_neo_fuel = ( (dndt_neo_D + dndt_neo_T) - * physics_variables.a_plasma_surface + * self.data.physics.a_plasma_surface * self.data.impurity_radiation.radius_plasma_core_norm ) dmdt_neo_fuel = ( - dndt_neo_fuel * physics_variables.m_fuel_amu * constants.PROTON_MASS * 1.0e6 + dndt_neo_fuel * self.data.physics.m_fuel_amu * constants.PROTON_MASS * 1.0e6 ) # mg dmdt_neo_fuel_from_e = ( 4 * dndt_neo_e - * physics_variables.a_plasma_surface + * self.data.physics.a_plasma_surface * self.data.impurity_radiation.radius_plasma_core_norm - * physics_variables.m_fuel_amu + * self.data.physics.m_fuel_amu * constants.PROTON_MASS * 1.0e6 ) # kg @@ -522,7 +521,7 @@ def neoclassics_calc_nu_star(self): ) return ( - physics_variables.rmajor + self.data.physics.rmajor * self.data.neoclassics.nu / (self.data.neoclassics.iota * v) ) @@ -538,20 +537,20 @@ def neoclassics_calc_nu_star_fromT(self, iota): """ temp = ( np.array([ - physics_variables.temp_plasma_electron_vol_avg_kev, - physics_variables.temp_plasma_ion_vol_avg_kev, - physics_variables.temp_plasma_ion_vol_avg_kev, - physics_variables.temp_plasma_ion_vol_avg_kev, + self.data.physics.temp_plasma_electron_vol_avg_kev, + self.data.physics.temp_plasma_ion_vol_avg_kev, + self.data.physics.temp_plasma_ion_vol_avg_kev, + self.data.physics.temp_plasma_ion_vol_avg_kev, ]) * KEV ) density = np.array([ - physics_variables.nd_plasma_electrons_vol_avg, - physics_variables.nd_plasma_fuel_ions_vol_avg - * physics_variables.f_plasma_fuel_deuterium, - physics_variables.nd_plasma_fuel_ions_vol_avg - * (1 - physics_variables.f_plasma_fuel_deuterium), - physics_variables.nd_plasma_alphas_vol_avg, + self.data.physics.nd_plasma_electrons_vol_avg, + self.data.physics.nd_plasma_fuel_ions_vol_avg + * self.data.physics.f_plasma_fuel_deuterium, + self.data.physics.nd_plasma_fuel_ions_vol_avg + * (1 - self.data.physics.f_plasma_fuel_deuterium), + self.data.physics.nd_plasma_alphas_vol_avg, ]) mass = np.array([ @@ -602,7 +601,7 @@ def neoclassics_calc_nu_star_fromT(self, iota): * lnlambda * phixmgx / (4.0 * np.pi * constants.EPSILON0**2 * mass[j] ** 2 * v**4) - * physics_variables.rmajor + * self.data.physics.rmajor / iota ) return neoclassics_calc_nu_star_fromT @@ -613,8 +612,8 @@ def neoclassics_calc_vd(self): * self.data.neoclassics.temperatures[0] / ( constants.ELECTRON_CHARGE - * physics_variables.rmajor - * physics_variables.b_plasma_toroidal_on_axis + * self.data.physics.rmajor + * self.data.physics.b_plasma_toroidal_on_axis ) ) vdD = ( @@ -622,8 +621,8 @@ def neoclassics_calc_vd(self): * self.data.neoclassics.temperatures[1] / ( constants.ELECTRON_CHARGE - * physics_variables.rmajor - * physics_variables.b_plasma_toroidal_on_axis + * self.data.physics.rmajor + * self.data.physics.b_plasma_toroidal_on_axis ) ) vdT = ( @@ -631,8 +630,8 @@ def neoclassics_calc_vd(self): * self.data.neoclassics.temperatures[2] / ( constants.ELECTRON_CHARGE - * physics_variables.rmajor - * physics_variables.b_plasma_toroidal_on_axis + * self.data.physics.rmajor + * self.data.physics.b_plasma_toroidal_on_axis ) ) vda = ( @@ -641,8 +640,8 @@ def neoclassics_calc_vd(self): / ( 2.0 * constants.ELECTRON_CHARGE - * physics_variables.rmajor - * physics_variables.b_plasma_toroidal_on_axis + * self.data.physics.rmajor + * self.data.physics.b_plasma_toroidal_on_axis ) ) @@ -690,7 +689,7 @@ def neoclassics_calc_D11_plateau(self): np.pi / 4.0 * self.data.neoclassics.vd**2 - * physics_variables.rmajor + * self.data.physics.rmajor / self.data.neoclassics.iota / v ) @@ -781,29 +780,29 @@ def neoclassics_calc_q_flux(self): def st_calc_eff_chi(self): volscaling = ( - physics_variables.vol_plasma + self.data.physics.vol_plasma * self.data.stellarator.f_st_rmajor * ( self.data.impurity_radiation.radius_plasma_core_norm - * physics_variables.rminor + * self.data.physics.rminor / self.data.stellarator_config.stella_config_rminor_ref ) ** 2 ) surfacescaling = ( - physics_variables.a_plasma_surface + self.data.physics.a_plasma_surface * self.data.stellarator.f_st_rmajor * ( self.data.impurity_radiation.radius_plasma_core_norm - * physics_variables.rminor + * self.data.physics.rminor / self.data.stellarator_config.stella_config_rminor_ref ) ) nominator = ( - physics_variables.f_p_alpha_plasma_deposited - * physics_variables.pden_alpha_total_mw - - physics_variables.pden_plasma_core_rad_mw + self.data.physics.f_p_alpha_plasma_deposited + * self.data.physics.pden_alpha_total_mw + - self.data.physics.pden_plasma_core_rad_mw ) * volscaling # in fortran there was a 0*alphan term which I have removed for obvious reasons @@ -813,14 +812,14 @@ def st_calc_eff_chi(self): denominator = ( ( 3 - * physics_variables.nd_plasma_electron_on_axis + * self.data.physics.nd_plasma_electron_on_axis * constants.ELECTRON_CHARGE - * physics_variables.temp_plasma_electron_on_axis_kev + * self.data.physics.temp_plasma_electron_on_axis_kev * 1e3 - * physics_variables.alphat + * self.data.physics.alphat * self.data.impurity_radiation.radius_plasma_core_norm * (1 - self.data.impurity_radiation.radius_plasma_core_norm**2) - ** (physics_variables.alphan + physics_variables.alphat - 1) + ** (self.data.physics.alphan + self.data.physics.alphat - 1) ) * surfacescaling * 1e-6 diff --git a/process/models/stellarator/stellarator.py b/process/models/stellarator/stellarator.py index da7983b85b..8d60b8f2f7 100644 --- a/process/models/stellarator/stellarator.py +++ b/process/models/stellarator/stellarator.py @@ -16,7 +16,6 @@ from process.data_structure import ( global_variables, numerics, - physics_variables, tfcoil_variables, ) from process.models.physics.physics import Physics, rether @@ -185,6 +184,7 @@ def run(self, output: bool = False): ) = power_at_ignition_point( self.data.stellarator.max_gyrotron_frequency, self.data.stellarator.te0_ecrh_achievable, + self.data, ) self.data.stellarator.first_call = False @@ -201,7 +201,7 @@ def st_new_config(self): To clarify the coils scaling factor: Coil aspect ratio factor can be described with the reversed equation (so if we would know r_coil_minor) f_coil_aspect = ( - (physics_variables.rmajor / self.data.stellarator.r_coil_minor) / + (self.data.physics.rmajor / self.data.stellarator.r_coil_minor) / (self.data.stellarator_config.stella_config_rmajor_ref / self.data.stellarator_config.stella_config_coil_rminor) ) @@ -213,16 +213,16 @@ def st_new_config(self): self.data, ) - # If physics_variables.aspect ratio is not in numerics.ixc set it to default value + # If self.data.physics.aspect ratio is not in numerics.ixc set it to default value # Or when you call it the first time if 1 not in numerics.ixc: - physics_variables.aspect = ( + self.data.physics.aspect = ( self.data.stellarator_config.stella_config_aspect_ref ) - # Set the physics_variables.rminor radius as result here. - physics_variables.rminor = physics_variables.rmajor / physics_variables.aspect - physics_variables.eps = 1.0e0 / physics_variables.aspect + # Set the self.data.physics.rminor radius as result here. + self.data.physics.rminor = self.data.physics.rmajor / self.data.physics.aspect + self.data.physics.eps = 1.0e0 / self.data.physics.aspect tfcoil_variables.n_tf_coils = ( self.data.stellarator_config.stella_config_coilspermodule @@ -230,16 +230,16 @@ def st_new_config(self): ) # This overwrites tfcoil_variables.n_tf_coils in input file. self.data.stellarator.f_st_rmajor = ( - physics_variables.rmajor + self.data.physics.rmajor / self.data.stellarator_config.stella_config_rmajor_ref ) # Size scaling factor with respect to the reference calculation self.data.stellarator.f_st_rminor = ( - physics_variables.rminor + self.data.physics.rminor / self.data.stellarator_config.stella_config_rminor_ref ) # Size scaling factor with respect to the reference calculation self.data.stellarator.f_st_aspect = ( - physics_variables.aspect + self.data.physics.aspect / self.data.stellarator_config.stella_config_aspect_ref ) self.data.stellarator.f_st_n_coils = tfcoil_variables.n_tf_coils / ( @@ -247,7 +247,7 @@ def st_new_config(self): * self.data.stellarator_config.stella_config_symmetry ) # Coil number factor self.data.stellarator.f_st_b = ( - physics_variables.b_plasma_toroidal_on_axis + self.data.physics.b_plasma_toroidal_on_axis / self.data.stellarator_config.stella_config_bt_ref ) # B-field scaling factor @@ -289,29 +289,29 @@ def st_geom(self): surfaces with Fourier coefficients') """ - physics_variables.vol_plasma = ( + self.data.physics.vol_plasma = ( self.data.stellarator.f_st_rmajor * self.data.stellarator.f_st_rminor**2 * self.data.stellarator_config.stella_config_vol_plasma ) # Plasma surface scaled from effective parameter: - physics_variables.a_plasma_surface = ( + self.data.physics.a_plasma_surface = ( self.data.stellarator.f_st_rmajor * self.data.stellarator.f_st_rminor * self.data.stellarator_config.stella_config_plasma_surface ) # Plasma cross section area. Approximated - physics_variables.a_plasma_poloidal = ( - np.pi * physics_variables.rminor * physics_variables.rminor + self.data.physics.a_plasma_poloidal = ( + np.pi * self.data.physics.rminor * self.data.physics.rminor ) # average, could be calculated for every toroidal angle if desired - # physics_variables.a_plasma_surface_outboard is retained only for obsolescent fispact calculation... + # self.data.physics.a_plasma_surface_outboard is retained only for obsolescent fispact calculation... # Cross-sectional area, averaged over toroidal angle - physics_variables.a_plasma_surface_outboard = ( - 0.5e0 * physics_variables.a_plasma_surface + self.data.physics.a_plasma_surface_outboard = ( + 0.5e0 * self.data.physics.a_plasma_surface ) # Used only in the divertor model; approximate as for tokamaks def st_strc(self, output): @@ -367,7 +367,7 @@ def st_strc(self, output): # The thickness 0.18m was obtained as a measured value from Schauer, F. and Bykov, V. design of Helias 5-B. (Nucl Fus. 2013) self.data.structure.aintmass = ( 0.18e0 - * (physics_variables.b_plasma_toroidal_on_axis / 5.6) ** 2 + * (self.data.physics.b_plasma_toroidal_on_axis / 5.6) ** 2 * intercoil_surface * self.data.fwbs.den_steel ) @@ -501,7 +501,7 @@ def st_fwbs(self, output: bool): """ self.data.fwbs.life_fw_fpy = min( - self.data.costs.abktflnc / physics_variables.pflux_fw_neutron_mw, + self.data.costs.abktflnc / self.data.physics.pflux_fw_neutron_mw, self.data.costs.life_plant, ) @@ -513,7 +513,7 @@ def st_fwbs(self, output: bool): # plasma surface area. # Uses self.data.fwbs.fhole etc. to take account of gaps due to ports etc. - r1 = physics_variables.rminor + 0.5e0 * ( + r1 = self.data.physics.rminor + 0.5e0 * ( self.data.build.dr_fw_plasma_gap_inboard + self.data.build.dr_fw_inboard + self.data.build.dr_fw_plasma_gap_outboard @@ -521,16 +521,16 @@ def st_fwbs(self, output: bool): ) if self.data.heat_transport.ipowerflow == 0: self.data.build.a_blkt_total_surface = ( - physics_variables.a_plasma_surface + self.data.physics.a_plasma_surface * r1 - / physics_variables.rminor + / self.data.physics.rminor * (1.0e0 - self.data.fwbs.fhole) ) else: self.data.build.a_blkt_total_surface = ( - physics_variables.a_plasma_surface + self.data.physics.a_plasma_surface * r1 - / physics_variables.rminor + / self.data.physics.rminor * ( 1.0e0 - self.data.fwbs.fhole @@ -563,7 +563,7 @@ def st_fwbs(self, output: bool): self.data.build.dr_blkt_inboard + self.data.build.dr_blkt_outboard ) self.data.build.a_shld_total_surface = ( - physics_variables.a_plasma_surface * r1 / physics_variables.rminor + self.data.physics.a_plasma_surface * r1 / self.data.physics.rminor ) self.data.build.a_shld_inboard_surface = ( 0.5e0 * self.data.build.a_shld_total_surface * self.data.fwbs.fvolsi @@ -584,7 +584,7 @@ def st_fwbs(self, output: bool): # shield) self.data.fwbs.pnucloss = ( - physics_variables.p_neutron_total_mw * self.data.fwbs.fhole + self.data.physics.p_neutron_total_mw * self.data.fwbs.fhole ) # The peaking factor, obtained as precalculated parameter @@ -598,32 +598,32 @@ def st_fwbs(self, output: bool): if self.data.heat_transport.ipowerflow == 1: self.data.fwbs.p_div_nuclear_heat_total_mw = ( - physics_variables.p_neutron_total_mw + self.data.physics.p_neutron_total_mw * self.data.fwbs.f_ster_div_single ) self.data.fwbs.p_fw_hcd_nuclear_heat_mw = ( - physics_variables.p_neutron_total_mw + self.data.physics.p_neutron_total_mw * self.data.fwbs.f_a_fw_outboard_hcd ) self.data.fwbs.p_fw_nuclear_heat_total_mw = ( - physics_variables.p_neutron_total_mw + self.data.physics.p_neutron_total_mw - self.data.fwbs.p_div_nuclear_heat_total_mw - self.data.fwbs.pnucloss - self.data.fwbs.p_fw_hcd_nuclear_heat_mw ) self.data.fwbs.pradloss = ( - physics_variables.p_plasma_rad_mw * self.data.fwbs.fhole + self.data.physics.p_plasma_rad_mw * self.data.fwbs.fhole ) self.data.fwbs.p_div_rad_total_mw = ( - physics_variables.p_plasma_rad_mw * self.data.fwbs.f_ster_div_single + self.data.physics.p_plasma_rad_mw * self.data.fwbs.f_ster_div_single ) self.data.fwbs.p_fw_hcd_rad_total_mw = ( - physics_variables.p_plasma_rad_mw + self.data.physics.p_plasma_rad_mw * self.data.fwbs.f_a_fw_outboard_hcd ) self.data.fwbs.p_fw_rad_total_mw = ( - physics_variables.p_plasma_rad_mw + self.data.physics.p_plasma_rad_mw - self.data.fwbs.p_div_rad_total_mw - self.data.fwbs.pradloss - self.data.fwbs.p_fw_hcd_rad_total_mw @@ -648,7 +648,7 @@ def st_fwbs(self, output: bool): self.data.heat_transport.p_div_coolant_pump_mw = ( self.data.heat_transport.f_p_div_coolant_pump_total_heat * ( - physics_variables.p_plasma_separatrix_mw + self.data.physics.p_plasma_separatrix_mw + self.data.fwbs.p_div_nuclear_heat_total_mw + self.data.fwbs.p_div_rad_total_mw ) @@ -672,13 +672,13 @@ def st_fwbs(self, output: bool): # Energy-multiplied neutron power pneut2 = ( - physics_variables.p_neutron_total_mw + self.data.physics.p_neutron_total_mw - self.data.fwbs.pnucloss - self.data.fwbs.pnuc_cp ) * self.data.fwbs.f_p_blkt_multiplication self.data.fwbs.p_blkt_multiplication_mw = pneut2 - ( - physics_variables.p_neutron_total_mw + self.data.physics.p_neutron_total_mw - self.data.fwbs.pnucloss - self.data.fwbs.pnuc_cp ) @@ -719,21 +719,21 @@ def st_fwbs(self, output: bool): # Neutron power incident on divertor (MW) self.data.fwbs.p_div_nuclear_heat_total_mw = ( - physics_variables.p_neutron_total_mw + self.data.physics.p_neutron_total_mw * self.data.fwbs.f_ster_div_single ) # Neutron power incident on HCD apparatus (MW) self.data.fwbs.p_fw_hcd_nuclear_heat_mw = ( - physics_variables.p_neutron_total_mw + self.data.physics.p_neutron_total_mw * self.data.fwbs.f_a_fw_outboard_hcd ) # Neutron power deposited in first wall, blanket and shield (MW) pnucfwbs = ( - physics_variables.p_neutron_total_mw + self.data.physics.p_neutron_total_mw - self.data.fwbs.p_div_nuclear_heat_total_mw - self.data.fwbs.pnucloss - self.data.fwbs.pnuc_cp @@ -756,27 +756,27 @@ def st_fwbs(self, output: bool): # Radiation power incident on divertor (MW) self.data.fwbs.p_fw_hcd_rad_total_mw = ( - physics_variables.p_plasma_rad_mw + self.data.physics.p_plasma_rad_mw * self.data.fwbs.f_a_fw_outboard_hcd ) # Radiation power incident on HCD apparatus (MW) self.data.fwbs.p_fw_hcd_rad_total_mw = ( - physics_variables.p_plasma_rad_mw + self.data.physics.p_plasma_rad_mw * self.data.fwbs.f_a_fw_outboard_hcd ) # Radiation power lost through holes (eventually hits shield) (MW) self.data.fwbs.pradloss = ( - physics_variables.p_plasma_rad_mw * self.data.fwbs.fhole + self.data.physics.p_plasma_rad_mw * self.data.fwbs.fhole ) # Radiation power incident on first wall (MW) self.data.fwbs.p_fw_rad_total_mw = ( - physics_variables.p_plasma_rad_mw + self.data.physics.p_plasma_rad_mw - self.data.fwbs.p_div_rad_total_mw - self.data.fwbs.pradloss - self.data.fwbs.p_fw_hcd_rad_total_mw @@ -992,7 +992,7 @@ def st_fwbs(self, output: bool): self.data.heat_transport.p_div_coolant_pump_mw = ( self.data.heat_transport.f_p_div_coolant_pump_total_heat * ( - physics_variables.p_plasma_separatrix_mw + self.data.physics.p_plasma_separatrix_mw + self.data.fwbs.p_div_nuclear_heat_total_mw + self.data.fwbs.p_div_rad_total_mw ) @@ -1267,14 +1267,14 @@ def st_fwbs(self, output: bool): + 0.5e0 * self.data.build.dr_tf_outboard + self.data.fwbs.dr_pf_cryostat ) - adewex = self.data.fwbs.r_cryostat_inboard - physics_variables.rmajor + adewex = self.data.fwbs.r_cryostat_inboard - self.data.physics.rmajor # External cryostat volume self.data.fwbs.vol_cryostat = ( 4.0e0 * (np.pi**2) - * physics_variables.rmajor + * self.data.physics.rmajor * adewex * self.data.build.dr_cryostat ) @@ -1282,7 +1282,7 @@ def st_fwbs(self, output: bool): # Internal vacuum vessel volume # self.data.fwbs.fvoldw accounts for ports, support, etc. additions - r1 = physics_variables.rminor + 0.5e0 * ( + r1 = self.data.physics.rminor + 0.5e0 * ( self.data.build.dr_fw_plasma_gap_inboard + self.data.build.dr_fw_inboard + self.data.build.dr_blkt_inboard @@ -1295,9 +1295,9 @@ def st_fwbs(self, output: bool): self.data.fwbs.vol_vv = ( (self.data.build.dr_vv_inboard + self.data.build.dr_vv_outboard) / 2.0e0 - * physics_variables.a_plasma_surface + * self.data.physics.a_plasma_surface * r1 - / physics_variables.rminor + / self.data.physics.rminor * self.data.fwbs.fvoldw ) @@ -1319,7 +1319,7 @@ def st_fwbs(self, output: bool): self.outfile, "Average neutron wall load (MW/m2)", "(pflux_fw_neutron_mw)", - physics_variables.pflux_fw_neutron_mw, + self.data.physics.pflux_fw_neutron_mw, ) if self.data.fwbs.blktmodel > 0: po.ovarre( @@ -1804,7 +1804,7 @@ def sc_tf_coil_nuclear_heating_iter90(self): coilhtmx = ( fact[0] - * physics_variables.pflux_fw_neutron_mw + * self.data.physics.pflux_fw_neutron_mw * coef[0, ishmat] * np.exp( -decay[5, ishmat] * (dshieq + tfcoil_variables.dr_tf_plasma_case) @@ -1821,7 +1821,7 @@ def sc_tf_coil_nuclear_heating_iter90(self): ) ptfowp = ( fact[0] - * physics_variables.pflux_fw_neutron_mw + * self.data.physics.pflux_fw_neutron_mw * coef[0, ishmat] * np.exp( -decay[5, ishmat] * (dshoeq + tfcoil_variables.dr_tf_plasma_case) @@ -1835,7 +1835,7 @@ def sc_tf_coil_nuclear_heating_iter90(self): htheci = ( fact[1] - * physics_variables.pflux_fw_neutron_mw + * self.data.physics.pflux_fw_neutron_mw * coef[1, ishmat] * np.exp(-decay[6, ishmat] * dshieq) ) @@ -1847,7 +1847,7 @@ def sc_tf_coil_nuclear_heating_iter90(self): ) pheco = ( fact[1] - * physics_variables.pflux_fw_neutron_mw + * self.data.physics.pflux_fw_neutron_mw * coef[1, ishmat] * np.exp(-decay[6, ishmat] * dshoeq) * tfcoil_variables.tfsao @@ -1871,7 +1871,7 @@ def sc_tf_coil_nuclear_heating_iter90(self): coef[2, ishmat] * fpsdt * fact[2] - * physics_variables.pflux_fw_neutron_mw + * self.data.physics.pflux_fw_neutron_mw * np.exp( -decay[2, ishmat] * (dshieq + tfcoil_variables.dr_tf_plasma_case) ) @@ -1882,7 +1882,7 @@ def sc_tf_coil_nuclear_heating_iter90(self): nflutf = ( fpsdt * fact[3] - * physics_variables.pflux_fw_neutron_mw + * self.data.physics.pflux_fw_neutron_mw * coef[3, ishmat] * np.exp( -decay[3, ishmat] * (dshieq + tfcoil_variables.dr_tf_plasma_case) @@ -1894,7 +1894,7 @@ def sc_tf_coil_nuclear_heating_iter90(self): dpacop = ( fpsdt * fact[4] - * physics_variables.pflux_fw_neutron_mw + * self.data.physics.pflux_fw_neutron_mw * coef[4, ishmat] * np.exp( -decay[4, ishmat] * (dshieq + tfcoil_variables.dr_tf_plasma_case) @@ -1939,64 +1939,64 @@ def st_phys(self, output): self.plasma_profile.run() # Total field - physics_variables.b_plasma_total = np.sqrt( - physics_variables.b_plasma_toroidal_on_axis**2 - + physics_variables.b_plasma_surface_poloidal_average**2 + self.data.physics.b_plasma_total = np.sqrt( + self.data.physics.b_plasma_toroidal_on_axis**2 + + self.data.physics.b_plasma_surface_poloidal_average**2 ) - # Check if physics_variables.beta (iteration variable 5) is an iteration variable + # Check if self.data.physics.beta (iteration variable 5) is an iteration variable if 5 in numerics.ixc: raise ProcessValueError( "Beta should not be in ixc if istell>0. Use Constraints 24 and 84 instead" ) - # Set physics_variables.beta as a consequence: + # Set self.data.physics.beta as a consequence: # This replaces constraint equation 1 as it is just an equality. - physics_variables.beta_total_vol_avg = ( - physics_variables.beta_fast_alpha - + physics_variables.beta_beam + self.data.physics.beta_total_vol_avg = ( + self.data.physics.beta_fast_alpha + + self.data.physics.beta_beam + 2.0e3 * constants.RMU0 * constants.ELECTRON_CHARGE * ( - physics_variables.nd_plasma_electrons_vol_avg - * physics_variables.temp_plasma_electron_density_weighted_kev - + physics_variables.nd_plasma_ions_total_vol_avg - * physics_variables.temp_plasma_ion_density_weighted_kev + self.data.physics.nd_plasma_electrons_vol_avg + * self.data.physics.temp_plasma_electron_density_weighted_kev + + self.data.physics.nd_plasma_ions_total_vol_avg + * self.data.physics.temp_plasma_ion_density_weighted_kev ) - / physics_variables.b_plasma_total**2 + / self.data.physics.b_plasma_total**2 ) - physics_variables.e_plasma_beta = ( + self.data.physics.e_plasma_beta = ( 1.5e0 - * physics_variables.beta_total_vol_avg - * physics_variables.b_plasma_total - * physics_variables.b_plasma_total + * self.data.physics.beta_total_vol_avg + * self.data.physics.b_plasma_total + * self.data.physics.b_plasma_total / (2.0e0 * constants.RMU0) - * physics_variables.vol_plasma + * self.data.physics.vol_plasma ) - physics_variables.rho_star = np.sqrt( + self.data.physics.rho_star = np.sqrt( 2.0e0 * constants.PROTON_MASS - * physics_variables.m_ions_total_amu - * physics_variables.e_plasma_beta + * self.data.physics.m_ions_total_amu + * self.data.physics.e_plasma_beta / ( 3.0e0 - * physics_variables.vol_plasma - * physics_variables.nd_plasma_electron_line + * self.data.physics.vol_plasma + * self.data.physics.nd_plasma_electron_line ) ) / ( constants.ELECTRON_CHARGE - * physics_variables.b_plasma_toroidal_on_axis - * physics_variables.eps - * physics_variables.rmajor + * self.data.physics.b_plasma_toroidal_on_axis + * self.data.physics.eps + * self.data.physics.rmajor ) # Calculate poloidal field using rotation transform - physics_variables.b_plasma_surface_poloidal_average = ( - physics_variables.rminor - * physics_variables.b_plasma_toroidal_on_axis - / physics_variables.rmajor + self.data.physics.b_plasma_surface_poloidal_average = ( + self.data.physics.rminor + * self.data.physics.b_plasma_toroidal_on_axis + / self.data.physics.rmajor * self.data.stellarator.iotabar ) @@ -2008,326 +2008,328 @@ def st_phys(self, output): fusion_reactions = reactions.FusionReactionRate(self.plasma_profile) fusion_reactions.deuterium_branching( - physics_variables.temp_plasma_ion_vol_avg_kev + self.data.physics.temp_plasma_ion_vol_avg_kev ) fusion_reactions.calculate_fusion_rates() fusion_reactions.set_physics_variables() # D-T power density is named differently to differentiate it from the beam given component - physics_variables.p_plasma_dt_mw = ( - physics_variables.dt_power_density_plasma * physics_variables.vol_plasma + self.data.physics.p_plasma_dt_mw = ( + self.data.physics.dt_power_density_plasma * self.data.physics.vol_plasma ) - physics_variables.p_dhe3_total_mw = ( - physics_variables.dhe3_power_density * physics_variables.vol_plasma + self.data.physics.p_dhe3_total_mw = ( + self.data.physics.dhe3_power_density * self.data.physics.vol_plasma ) - physics_variables.p_dd_total_mw = ( - physics_variables.dd_power_density * physics_variables.vol_plasma + self.data.physics.p_dd_total_mw = ( + self.data.physics.dd_power_density * self.data.physics.vol_plasma ) # Calculate neutral beam slowing down effects # If ignited, then ignore beam fusion effects if (self.data.current_drive.p_hcd_beam_injected_total_mw != 0.0e0) and ( # noqa: RUF069 - physics_variables.i_plasma_ignited == 0 + self.data.physics.i_plasma_ignited == 0 ): ( - physics_variables.beta_beam, - physics_variables.nd_beam_ions_out, - physics_variables.p_beam_alpha_mw, + self.data.physics.beta_beam, + self.data.physics.nd_beam_ions_out, + self.data.physics.p_beam_alpha_mw, ) = reactions.beam_fusion( - physics_variables.beamfus0, - physics_variables.betbm0, - physics_variables.b_plasma_total, + self.data.physics.beamfus0, + self.data.physics.betbm0, + self.data.physics.b_plasma_total, self.data.current_drive.c_beam_total, - physics_variables.nd_plasma_electrons_vol_avg, - physics_variables.nd_plasma_fuel_ions_vol_avg, - physics_variables.dlamie, + self.data.physics.nd_plasma_electrons_vol_avg, + self.data.physics.nd_plasma_fuel_ions_vol_avg, + self.data.physics.dlamie, self.data.current_drive.e_beam_kev, - physics_variables.f_plasma_fuel_deuterium, - physics_variables.f_plasma_fuel_tritium, + self.data.physics.f_plasma_fuel_deuterium, + self.data.physics.f_plasma_fuel_tritium, self.data.current_drive.f_beam_tritium, - physics_variables.temp_plasma_electron_density_weighted_kev, - physics_variables.vol_plasma, - physics_variables.n_charge_plasma_effective_mass_weighted_vol_avg, + self.data.physics.temp_plasma_electron_density_weighted_kev, + self.data.physics.vol_plasma, + self.data.physics.n_charge_plasma_effective_mass_weighted_vol_avg, ) - physics_variables.fusden_total = ( - physics_variables.fusden_plasma + self.data.physics.fusden_total = ( + self.data.physics.fusden_plasma + 1.0e6 - * physics_variables.p_beam_alpha_mw + * self.data.physics.p_beam_alpha_mw / (constants.DT_ALPHA_ENERGY) - / physics_variables.vol_plasma + / self.data.physics.vol_plasma ) - physics_variables.fusden_alpha_total = ( - physics_variables.fusden_plasma_alpha + self.data.physics.fusden_alpha_total = ( + self.data.physics.fusden_plasma_alpha + 1.0e6 - * physics_variables.p_beam_alpha_mw + * self.data.physics.p_beam_alpha_mw / (constants.DT_ALPHA_ENERGY) - / physics_variables.vol_plasma + / self.data.physics.vol_plasma ) - physics_variables.p_dt_total_mw = ( - physics_variables.p_plasma_dt_mw - + 5.0e0 * physics_variables.p_beam_alpha_mw + self.data.physics.p_dt_total_mw = ( + self.data.physics.p_plasma_dt_mw + + 5.0e0 * self.data.physics.p_beam_alpha_mw ) else: # If no beams present then the total alpha rates and power are the same as the plasma values - physics_variables.fusden_total = physics_variables.fusden_plasma - physics_variables.fusden_alpha_total = physics_variables.fusden_plasma_alpha - physics_variables.p_dt_total_mw = physics_variables.p_plasma_dt_mw + self.data.physics.fusden_total = self.data.physics.fusden_plasma + self.data.physics.fusden_alpha_total = self.data.physics.fusden_plasma_alpha + self.data.physics.p_dt_total_mw = self.data.physics.p_plasma_dt_mw # Create some derived values and add beam contribution to fusion power ( - physics_variables.pden_neutron_total_mw, - physics_variables.p_plasma_alpha_mw, - physics_variables.p_alpha_total_mw, - physics_variables.p_plasma_neutron_mw, - physics_variables.p_neutron_total_mw, - physics_variables.p_non_alpha_charged_mw, - physics_variables.pden_alpha_total_mw, - physics_variables.f_pden_alpha_electron_mw, - physics_variables.f_pden_alpha_ions_mw, - physics_variables.p_charged_particle_mw, - physics_variables.p_fusion_total_mw, + self.data.physics.pden_neutron_total_mw, + self.data.physics.p_plasma_alpha_mw, + self.data.physics.p_alpha_total_mw, + self.data.physics.p_plasma_neutron_mw, + self.data.physics.p_neutron_total_mw, + self.data.physics.p_non_alpha_charged_mw, + self.data.physics.pden_alpha_total_mw, + self.data.physics.f_pden_alpha_electron_mw, + self.data.physics.f_pden_alpha_ions_mw, + self.data.physics.p_charged_particle_mw, + self.data.physics.p_fusion_total_mw, ) = reactions.set_fusion_powers( - physics_variables.f_alpha_electron, - physics_variables.f_alpha_ion, - physics_variables.p_beam_alpha_mw, - physics_variables.pden_non_alpha_charged_mw, - physics_variables.pden_plasma_neutron_mw, - physics_variables.vol_plasma, - physics_variables.pden_plasma_alpha_mw, - ) - - physics_variables.beta_fast_alpha = self.beta.fast_alpha_beta( - physics_variables.b_plasma_surface_poloidal_average, - physics_variables.b_plasma_toroidal_on_axis, - physics_variables.nd_plasma_electrons_vol_avg, - physics_variables.nd_plasma_fuel_ions_vol_avg, - physics_variables.nd_plasma_ions_total_vol_avg, - physics_variables.temp_plasma_electron_density_weighted_kev, - physics_variables.temp_plasma_ion_density_weighted_kev, - physics_variables.pden_alpha_total_mw, - physics_variables.pden_plasma_alpha_mw, - physics_variables.i_beta_fast_alpha, + self.data.physics.f_alpha_electron, + self.data.physics.f_alpha_ion, + self.data.physics.p_beam_alpha_mw, + self.data.physics.pden_non_alpha_charged_mw, + self.data.physics.pden_plasma_neutron_mw, + self.data.physics.vol_plasma, + self.data.physics.pden_plasma_alpha_mw, + self.data.physics.f_p_alpha_plasma_deposited, + ) + + self.data.physics.beta_fast_alpha = self.beta.fast_alpha_beta( + self.data.physics.b_plasma_surface_poloidal_average, + self.data.physics.b_plasma_toroidal_on_axis, + self.data.physics.nd_plasma_electrons_vol_avg, + self.data.physics.nd_plasma_fuel_ions_vol_avg, + self.data.physics.nd_plasma_ions_total_vol_avg, + self.data.physics.temp_plasma_electron_density_weighted_kev, + self.data.physics.temp_plasma_ion_density_weighted_kev, + self.data.physics.pden_alpha_total_mw, + self.data.physics.pden_plasma_alpha_mw, + self.data.physics.i_beta_fast_alpha, + self.data.physics.f_plasma_fuel_deuterium, ) # Neutron wall load - if physics_variables.i_pflux_fw_neutron == 1: - physics_variables.pflux_fw_neutron_mw = ( - physics_variables.ffwal - * physics_variables.p_neutron_total_mw - / physics_variables.a_plasma_surface + if self.data.physics.i_pflux_fw_neutron == 1: + self.data.physics.pflux_fw_neutron_mw = ( + self.data.physics.ffwal + * self.data.physics.p_neutron_total_mw + / self.data.physics.a_plasma_surface ) elif self.data.heat_transport.ipowerflow == 0: - physics_variables.pflux_fw_neutron_mw = ( + self.data.physics.pflux_fw_neutron_mw = ( (1.0e0 - self.data.fwbs.fhole) - * physics_variables.p_neutron_total_mw + * self.data.physics.p_neutron_total_mw / self.data.first_wall.a_fw_total ) else: - physics_variables.pflux_fw_neutron_mw = ( + self.data.physics.pflux_fw_neutron_mw = ( ( 1.0e0 - self.data.fwbs.fhole - self.data.fwbs.f_a_fw_outboard_hcd - self.data.fwbs.f_ster_div_single ) - * physics_variables.p_neutron_total_mw + * self.data.physics.p_neutron_total_mw / self.data.first_wall.a_fw_total ) # Calculate ion/electron equilibration power - physics_variables.pden_ion_electron_equilibration_mw = rether( - physics_variables.alphan, - physics_variables.alphat, - physics_variables.nd_plasma_electrons_vol_avg, - physics_variables.dlamie, - physics_variables.temp_plasma_electron_vol_avg_kev, - physics_variables.temp_plasma_ion_vol_avg_kev, - physics_variables.n_charge_plasma_effective_mass_weighted_vol_avg, + self.data.physics.pden_ion_electron_equilibration_mw = rether( + self.data.physics.alphan, + self.data.physics.alphat, + self.data.physics.nd_plasma_electrons_vol_avg, + self.data.physics.dlamie, + self.data.physics.temp_plasma_electron_vol_avg_kev, + self.data.physics.temp_plasma_ion_vol_avg_kev, + self.data.physics.n_charge_plasma_effective_mass_weighted_vol_avg, ) # Calculate radiation power radpwr_data = physics_funcs.calculate_radiation_powers( self.plasma_profile, - physics_variables.nd_plasma_electron_on_axis, - physics_variables.rminor, - physics_variables.b_plasma_toroidal_on_axis, - physics_variables.aspect, - physics_variables.alphan, - physics_variables.alphat, - physics_variables.tbeta, - physics_variables.temp_plasma_electron_on_axis_kev, - physics_variables.f_sync_reflect, - physics_variables.rmajor, - physics_variables.kappa, - physics_variables.vol_plasma, + self.data.physics.nd_plasma_electron_on_axis, + self.data.physics.rminor, + self.data.physics.b_plasma_toroidal_on_axis, + self.data.physics.aspect, + self.data.physics.alphan, + self.data.physics.alphat, + self.data.physics.tbeta, + self.data.physics.temp_plasma_electron_on_axis_kev, + self.data.physics.f_sync_reflect, + self.data.physics.rmajor, + self.data.physics.kappa, + self.data.physics.vol_plasma, self.data, ) - physics_variables.pden_plasma_sync_mw = radpwr_data.pden_plasma_sync_mw - physics_variables.pden_plasma_core_rad_mw = radpwr_data.pden_plasma_core_rad_mw - physics_variables.pden_plasma_outer_rad_mw = radpwr_data.pden_plasma_outer_rad_mw - physics_variables.pden_plasma_rad_mw = radpwr_data.pden_plasma_rad_mw + self.data.physics.pden_plasma_sync_mw = radpwr_data.pden_plasma_sync_mw + self.data.physics.pden_plasma_core_rad_mw = radpwr_data.pden_plasma_core_rad_mw + self.data.physics.pden_plasma_outer_rad_mw = radpwr_data.pden_plasma_outer_rad_mw + self.data.physics.pden_plasma_rad_mw = radpwr_data.pden_plasma_rad_mw - physics_variables.pden_plasma_core_rad_mw = max( - physics_variables.pden_plasma_core_rad_mw, 0.0e0 + self.data.physics.pden_plasma_core_rad_mw = max( + self.data.physics.pden_plasma_core_rad_mw, 0.0e0 ) - physics_variables.pden_plasma_outer_rad_mw = max( - physics_variables.pden_plasma_outer_rad_mw, 0.0e0 + self.data.physics.pden_plasma_outer_rad_mw = max( + self.data.physics.pden_plasma_outer_rad_mw, 0.0e0 ) - physics_variables.p_plasma_inner_rad_mw = ( - physics_variables.pden_plasma_core_rad_mw * physics_variables.vol_plasma + self.data.physics.p_plasma_inner_rad_mw = ( + self.data.physics.pden_plasma_core_rad_mw * self.data.physics.vol_plasma ) # Should probably be vol_core - physics_variables.p_plasma_outer_rad_mw = ( - physics_variables.pden_plasma_outer_rad_mw * physics_variables.vol_plasma + self.data.physics.p_plasma_outer_rad_mw = ( + self.data.physics.pden_plasma_outer_rad_mw * self.data.physics.vol_plasma ) - physics_variables.p_plasma_rad_mw = ( - physics_variables.pden_plasma_rad_mw * physics_variables.vol_plasma + self.data.physics.p_plasma_rad_mw = ( + self.data.physics.pden_plasma_rad_mw * self.data.physics.vol_plasma ) # Heating power to plasma (= Psol in divertor model) # Ohmic power is zero in a stellarator - # physics_variables.p_plasma_rad_mw here is core + edge (no SOL) + # self.data.physics.p_plasma_rad_mw here is core + edge (no SOL) powht = ( - physics_variables.f_p_alpha_plasma_deposited - * physics_variables.p_alpha_total_mw - + physics_variables.p_non_alpha_charged_mw - + physics_variables.p_plasma_ohmic_mw - - physics_variables.pden_plasma_rad_mw * physics_variables.vol_plasma + self.data.physics.f_p_alpha_plasma_deposited + * self.data.physics.p_alpha_total_mw + + self.data.physics.p_non_alpha_charged_mw + + self.data.physics.p_plasma_ohmic_mw + - self.data.physics.pden_plasma_rad_mw * self.data.physics.vol_plasma ) powht = max( 0.00001e0, powht ) # To avoid negative heating power. This line is VERY important - if physics_variables.i_plasma_ignited == 0: + if self.data.physics.i_plasma_ignited == 0: # if not ignited add the auxiliary power powht += self.data.current_drive.p_hcd_injected_total_mw # Here the implementation sometimes leaves the accessible regime when p_plasma_rad_mw> powht which is unphysical and # is not taken care of by the rad module. We restrict the radiation power here by the heating power: - physics_variables.p_plasma_rad_mw = max(0.0e0, physics_variables.p_plasma_rad_mw) + self.data.physics.p_plasma_rad_mw = max(0.0e0, self.data.physics.p_plasma_rad_mw) # Power to divertor, = (1-self.data.stellarator.f_rad)*Psol - # The SOL radiation needs to be smaller than the physics_variables.p_plasma_rad_mw - physics_variables.psolradmw = self.data.stellarator.f_rad * powht - physics_variables.p_plasma_separatrix_mw = powht - physics_variables.psolradmw + # The SOL radiation needs to be smaller than the self.data.physics.p_plasma_rad_mw + self.data.physics.psolradmw = self.data.stellarator.f_rad * powht + self.data.physics.p_plasma_separatrix_mw = powht - self.data.physics.psolradmw # Add SOL Radiation to total - physics_variables.p_plasma_rad_mw += physics_variables.psolradmw + self.data.physics.p_plasma_rad_mw += self.data.physics.psolradmw # The following line is unphysical, but prevents -ve sqrt argument # Should be obsolete if constraint eqn 17 is turned on (but beware - # this may not be quite correct for stellarators) - physics_variables.p_plasma_separatrix_mw = max( - 0.001e0, physics_variables.p_plasma_separatrix_mw + self.data.physics.p_plasma_separatrix_mw = max( + 0.001e0, self.data.physics.p_plasma_separatrix_mw ) # Power transported to the first wall by escaped alpha particles - physics_variables.p_fw_alpha_mw = physics_variables.p_alpha_total_mw * ( - 1.0e0 - physics_variables.f_p_alpha_plasma_deposited + self.data.physics.p_fw_alpha_mw = self.data.physics.p_alpha_total_mw * ( + 1.0e0 - self.data.physics.f_p_alpha_plasma_deposited ) # Nominal mean photon wall load - if physics_variables.i_pflux_fw_neutron == 1: - physics_variables.pflux_fw_rad_mw = ( - physics_variables.ffwal - * physics_variables.p_plasma_rad_mw - / physics_variables.a_plasma_surface + if self.data.physics.i_pflux_fw_neutron == 1: + self.data.physics.pflux_fw_rad_mw = ( + self.data.physics.ffwal + * self.data.physics.p_plasma_rad_mw + / self.data.physics.a_plasma_surface ) elif self.data.heat_transport.ipowerflow == 0: - physics_variables.pflux_fw_rad_mw = ( + self.data.physics.pflux_fw_rad_mw = ( (1.0e0 - self.data.fwbs.fhole) - * physics_variables.p_plasma_rad_mw + * self.data.physics.p_plasma_rad_mw / self.data.first_wall.a_fw_total ) else: - physics_variables.pflux_fw_rad_mw = ( + self.data.physics.pflux_fw_rad_mw = ( ( 1.0e0 - self.data.fwbs.fhole - self.data.fwbs.f_a_fw_outboard_hcd - self.data.fwbs.f_ster_div_single ) - * physics_variables.p_plasma_rad_mw + * self.data.physics.p_plasma_rad_mw / self.data.first_wall.a_fw_total ) self.data.constraints.pflux_fw_rad_max_mw = ( - physics_variables.pflux_fw_rad_mw * self.data.constraints.f_fw_rad_max + self.data.physics.pflux_fw_rad_mw * self.data.constraints.f_fw_rad_max ) - physics_variables.rad_fraction_total = physics_variables.p_plasma_rad_mw / ( - physics_variables.f_p_alpha_plasma_deposited - * physics_variables.p_alpha_total_mw - + physics_variables.p_non_alpha_charged_mw - + physics_variables.p_plasma_ohmic_mw + self.data.physics.rad_fraction_total = self.data.physics.p_plasma_rad_mw / ( + self.data.physics.f_p_alpha_plasma_deposited + * self.data.physics.p_alpha_total_mw + + self.data.physics.p_non_alpha_charged_mw + + self.data.physics.p_plasma_ohmic_mw + self.data.current_drive.p_hcd_injected_total_mw ) # Calculate transport losses and energy confinement time using the # chosen scaling law - # N.B. self.data.stellarator.iotabar replaces tokamak physics_variables.q95 in argument list + # N.B. self.data.stellarator.iotabar replaces tokamak self.data.physics.q95 in argument list ( - physics_variables.pden_electron_transport_loss_mw, - physics_variables.pden_ion_transport_loss_mw, - physics_variables.t_electron_energy_confinement, - physics_variables.t_ion_energy_confinement, - physics_variables.t_energy_confinement, - physics_variables.p_plasma_loss_mw, + self.data.physics.pden_electron_transport_loss_mw, + self.data.physics.pden_ion_transport_loss_mw, + self.data.physics.t_electron_energy_confinement, + self.data.physics.t_ion_energy_confinement, + self.data.physics.t_energy_confinement, + self.data.physics.p_plasma_loss_mw, ) = self.physics.confinement.calculate_confinement_time( - physics_variables.m_fuel_amu, - physics_variables.p_alpha_total_mw, - physics_variables.aspect, - physics_variables.b_plasma_toroidal_on_axis, - physics_variables.nd_plasma_ions_total_vol_avg, - physics_variables.nd_plasma_electrons_vol_avg, - physics_variables.nd_plasma_electron_line, - physics_variables.eps, - physics_variables.hfact, - physics_variables.i_confinement_time, - physics_variables.i_plasma_ignited, - physics_variables.kappa, - physics_variables.kappa95, - physics_variables.p_non_alpha_charged_mw, + self.data.physics.m_fuel_amu, + self.data.physics.p_alpha_total_mw, + self.data.physics.aspect, + self.data.physics.b_plasma_toroidal_on_axis, + self.data.physics.nd_plasma_ions_total_vol_avg, + self.data.physics.nd_plasma_electrons_vol_avg, + self.data.physics.nd_plasma_electron_line, + self.data.physics.eps, + self.data.physics.hfact, + self.data.physics.i_confinement_time, + self.data.physics.i_plasma_ignited, + self.data.physics.kappa, + self.data.physics.kappa95, + self.data.physics.p_non_alpha_charged_mw, self.data.current_drive.p_hcd_injected_total_mw, - physics_variables.plasma_current, - physics_variables.pden_plasma_core_rad_mw, - physics_variables.rmajor, - physics_variables.rminor, - physics_variables.temp_plasma_electron_density_weighted_kev, - physics_variables.temp_plasma_ion_density_weighted_kev, + self.data.physics.plasma_current, + self.data.physics.pden_plasma_core_rad_mw, + self.data.physics.rmajor, + self.data.physics.rminor, + self.data.physics.temp_plasma_electron_density_weighted_kev, + self.data.physics.temp_plasma_ion_density_weighted_kev, self.data.stellarator.iotabar, - physics_variables.qstar, - physics_variables.vol_plasma, - physics_variables.n_charge_plasma_effective_vol_avg, + self.data.physics.qstar, + self.data.physics.vol_plasma, + self.data.physics.n_charge_plasma_effective_vol_avg, ) - physics_variables.ntau, physics_variables.nTtau = ( + self.data.physics.ntau, self.data.physics.nTtau = ( self.physics.confinement.calculate_double_and_triple_product( - nd_plasma_electrons_vol_avg=physics_variables.nd_plasma_electrons_vol_avg, - t_energy_confinement=physics_variables.t_energy_confinement, - temp_plasma_electrons_vol_avg_kev=physics_variables.temp_plasma_electron_vol_avg_kev, + nd_plasma_electrons_vol_avg=self.data.physics.nd_plasma_electrons_vol_avg, + t_energy_confinement=self.data.physics.t_energy_confinement, + temp_plasma_electrons_vol_avg_kev=self.data.physics.temp_plasma_electron_vol_avg_kev, ) ) - physics_variables.p_electron_transport_loss_mw = ( - physics_variables.pden_electron_transport_loss_mw - * physics_variables.vol_plasma + self.data.physics.p_electron_transport_loss_mw = ( + self.data.physics.pden_electron_transport_loss_mw + * self.data.physics.vol_plasma ) - physics_variables.p_ion_transport_loss_mw = ( - physics_variables.pden_ion_transport_loss_mw * physics_variables.vol_plasma + self.data.physics.p_ion_transport_loss_mw = ( + self.data.physics.pden_ion_transport_loss_mw * self.data.physics.vol_plasma ) - physics_variables.pscalingmw = ( - physics_variables.p_electron_transport_loss_mw - + physics_variables.p_ion_transport_loss_mw + self.data.physics.pscalingmw = ( + self.data.physics.p_electron_transport_loss_mw + + self.data.physics.p_ion_transport_loss_mw ) # Calculate auxiliary physics related information @@ -2335,23 +2337,25 @@ def st_phys(self, output): sbar = 1.0e0 ( - physics_variables.burnup, - physics_variables.figmer, + self.data.physics.burnup, + self.data.physics.figmer, _fusrat, - physics_variables.molflow_plasma_fuelling_required, - physics_variables.rndfuel, - physics_variables.t_alpha_confinement, - physics_variables.f_alpha_energy_confinement, + self.data.physics.molflow_plasma_fuelling_required, + self.data.physics.rndfuel, + self.data.physics.t_alpha_confinement, + self.data.physics.f_alpha_energy_confinement, ) = self.physics.phyaux( - physics_variables.aspect, - physics_variables.nd_plasma_fuel_ions_vol_avg, - physics_variables.fusden_total, - physics_variables.fusden_alpha_total, - physics_variables.plasma_current, + self.data.physics.aspect, + self.data.physics.nd_plasma_fuel_ions_vol_avg, + self.data.physics.fusden_total, + self.data.physics.fusden_alpha_total, + self.data.physics.plasma_current, sbar, - physics_variables.nd_plasma_alphas_vol_avg, - physics_variables.t_energy_confinement, - physics_variables.vol_plasma, + self.data.physics.nd_plasma_alphas_vol_avg, + self.data.physics.t_energy_confinement, + self.data.physics.vol_plasma, + self.data.physics.burnup_in, + self.data.physics.tauratio, ) # Calculate the neoclassical sanity check with PROCESS parameters @@ -2396,17 +2400,17 @@ def st_phys(self, output): q_neo_e, g_neo_e, dndt_neo_e, - physics_variables.rho_ne_max, - physics_variables.rho_te_max, - physics_variables.gradient_length_ne, - physics_variables.gradient_length_te, - physics_variables.rho_star, + self.data.physics.rho_ne_max, + self.data.physics.rho_te_max, + self.data.physics.gradient_length_ne, + self.data.physics.gradient_length_te, + self.data.physics.rho_star, nu_star_e, nu_star_d, nu_star_T, nu_star_He, - physics_variables.nd_plasma_electron_line, - physics_variables.nd_plasma_electrons_max, + self.data.physics.nd_plasma_electron_line, + self.data.physics.nd_plasma_electrons_max, ) def st_phys_output( diff --git a/process/models/structure.py b/process/models/structure.py index 00cf564de4..998919142f 100644 --- a/process/models/structure.py +++ b/process/models/structure.py @@ -8,7 +8,6 @@ from process.core import constants from process.core import process_output as po from process.core.model import Model -from process.data_structure import physics_variables as pv from process.data_structure import tfcoil_variables as tfv logger = logging.getLogger(__name__) @@ -52,11 +51,11 @@ def run(self, output: bool = False): self.data.structure.coldmass, self.data.structure.gsmass, ) = self.structure( - pv.plasma_current, - pv.rmajor, - pv.rminor, - pv.kappa, - pv.b_plasma_toroidal_on_axis, + self.data.physics.plasma_current, + self.data.physics.rmajor, + self.data.physics.rminor, + self.data.physics.kappa, + self.data.physics.b_plasma_toroidal_on_axis, tfv.i_tf_sup, self.data.pf_coil.i_pf_conductor, self.data.build.dr_tf_inner_bore diff --git a/process/models/tfcoil/base.py b/process/models/tfcoil/base.py index 6341404141..4e6025e063 100644 --- a/process/models/tfcoil/base.py +++ b/process/models/tfcoil/base.py @@ -20,7 +20,6 @@ from process.data_structure import ( global_variables, numerics, - physics_variables, rebco_variables, superconducting_tf_coil_variables, tfcoil_variables, @@ -184,8 +183,8 @@ def run_base_tf(self): tfcoil_variables.oacdcp, ) = self.tf_current( n_tf_coils=tfcoil_variables.n_tf_coils, - b_plasma_toroidal_on_axis=physics_variables.b_plasma_toroidal_on_axis, - rmajor=physics_variables.rmajor, + b_plasma_toroidal_on_axis=self.data.physics.b_plasma_toroidal_on_axis, + rmajor=self.data.physics.rmajor, r_b_tf_inboard_peak=tfcoil_variables.r_b_tf_inboard_peak, a_tf_inboard_total=tfcoil_variables.a_tf_inboard_total, ) @@ -198,12 +197,12 @@ def run_base_tf(self): tfcoil_variables.z_tf_arc, ) = self.tf_coil_shape_inner( i_tf_shape=tfcoil_variables.i_tf_shape, - itart=physics_variables.itart, - i_single_null=physics_variables.i_single_null, + itart=self.data.physics.itart, + i_single_null=self.data.physics.i_single_null, r_tf_inboard_out=self.data.build.r_tf_inboard_out, r_cp_top=self.data.build.r_cp_top, - rmajor=physics_variables.rmajor, - rminor=physics_variables.rminor, + rmajor=self.data.physics.rmajor, + rminor=self.data.physics.rminor, r_tf_outboard_in=superconducting_tf_coil_variables.r_tf_outboard_in, z_tf_inside_half=self.data.build.z_tf_inside_half, z_tf_top=self.data.build.z_tf_top, @@ -690,9 +689,9 @@ def outtf(self): self.outfile, "Presence of TF demountable joints", "(itart)", - physics_variables.itart, + self.data.physics.itart, ) - if physics_variables.itart == 1: + if self.data.physics.itart == 1: po.ocmmnt( self.outfile, " -> TF coil made of a Centerpost (CP) and outer legs" ) @@ -884,7 +883,7 @@ def outtf(self): self.data.build.dz_tf_upper_lower_midplane, "OP ", ) - if physics_variables.itart == 1: + if self.data.physics.itart == 1: po.ovarre( self.outfile, "Mean coil circumference (inboard leg not included) (m)", @@ -954,7 +953,7 @@ def outtf(self): # CP tapering geometry if ( - physics_variables.itart == 1 + self.data.physics.itart == 1 and tfcoil_variables.i_tf_sup != TFConductorModel.SUPERCONDUCTING ): po.osubhd(self.outfile, "Tapered Centrepost TF coil Dimensions:") @@ -1542,7 +1541,7 @@ def outtf(self): "(dr_tf_wp_with_insulation)", tfcoil_variables.dr_tf_wp_with_insulation, ) - if physics_variables.itart == 1: + if self.data.physics.itart == 1: po.ovarre( self.outfile, "Central collumn top conductor sector radial thickness (m)", @@ -1640,7 +1639,7 @@ def outtf(self): "OP ", ) - if physics_variables.itart == 1: + if self.data.physics.itart == 1: po.ovarre( self.outfile, "Mass of inboard legs (kg)", @@ -1729,7 +1728,7 @@ def outtf(self): "(oacdcp)", tfcoil_variables.oacdcp, ) - if physics_variables.itart == 1: + if self.data.physics.itart == 1: po.ovarre( self.outfile, "Outboard leg conductor current density (A/m2)", @@ -1804,7 +1803,7 @@ def outtf(self): self.outfile, "Resistive Material : Pure Aluminium (99.999+ %)" ) - if physics_variables.itart == 1: + if self.data.physics.itart == 1: po.ovarre( self.outfile, "CP resistivity (ohm.m)", @@ -2163,9 +2162,9 @@ def outtf(self): tf_total_width, ) - # Top section TF coil radial build (physics_variables.itart = 1 only) + # Top section TF coil radial build (self.data.physics.itart = 1 only) if ( - physics_variables.itart == 1 + self.data.physics.itart == 1 and tfcoil_variables.i_tf_sup != TFConductorModel.SUPERCONDUCTING ): po.osubhd(self.outfile, "Radial build of TF coil at central collumn top :") @@ -2287,13 +2286,13 @@ def cntrpst(self, output: bool = False): i.e. narrowest on the midplane (z=0). """ # Vertical distance from the midplane to the top of the tapered section [m] - if physics_variables.itart == 1: + if self.data.physics.itart == 1: superconducting_tf_coil_variables.z_cp_top = ( self.data.build.z_plasma_xpoint_upper + tfcoil_variables.dztop ) if ( - physics_variables.itart == 1 + self.data.physics.itart == 1 and tfcoil_variables.i_tf_sup != TFConductorModel.SUPERCONDUCTING ): tfcoil_variables.dx_tf_inboard_out_toroidal = ( @@ -2843,7 +2842,7 @@ def tf_field_and_force( ) ) - # Case of a centrepost (physics_variables.itart == 1) with sliding joints + # Case of a centrepost (self.data.physics.itart == 1) with sliding joints # (the CP vertical are separated from the leg ones) # Rem SK : casing/insulation thickness not subtracted as part of the CP is # genuinely connected to the legs.. diff --git a/process/models/tfcoil/resistive.py b/process/models/tfcoil/resistive.py index a017767127..66839b1217 100644 --- a/process/models/tfcoil/resistive.py +++ b/process/models/tfcoil/resistive.py @@ -7,7 +7,6 @@ from process.core import constants from process.data_structure import ( - physics_variables, superconducting_tf_coil_variables, tfcoil_variables, ) @@ -46,7 +45,7 @@ def run(self, output: bool = False): dr_tf_inboard=self.data.build.dr_tf_inboard, r_tf_arc=tfcoil_variables.r_tf_arc, z_tf_arc=tfcoil_variables.z_tf_arc, - itart=physics_variables.itart, + itart=self.data.physics.itart, i_tf_shape=tfcoil_variables.i_tf_shape, z_tf_inside_half=self.data.build.z_tf_inside_half, dr_tf_outboard=self.data.build.dr_tf_outboard, @@ -81,10 +80,10 @@ def run(self, output: bool = False): c_tf_total=tfcoil_variables.c_tf_total, n_tf_coils=tfcoil_variables.n_tf_coils, dr_tf_plasma_case=tfcoil_variables.dr_tf_plasma_case, - rmajor=physics_variables.rmajor, - b_plasma_toroidal_on_axis=physics_variables.b_plasma_toroidal_on_axis, + rmajor=self.data.physics.rmajor, + b_plasma_toroidal_on_axis=self.data.physics.b_plasma_toroidal_on_axis, r_cp_top=self.data.build.r_cp_top, - itart=physics_variables.itart, + itart=self.data.physics.itart, i_cp_joints=tfcoil_variables.i_cp_joints, f_vforce_inboard=tfcoil_variables.f_vforce_inboard, ) @@ -283,7 +282,7 @@ def res_tf_internal_geom(self): ) # Conductor layer radial thickness at centercollumn top [m] - if physics_variables.itart == 1: + if self.data.physics.itart == 1: superconducting_tf_coil_variables.dr_tf_wp_top = ( self.data.build.r_cp_top - tfcoil_variables.dr_tf_plasma_case @@ -404,7 +403,7 @@ def res_tf_internal_geom(self): # Total cross-sectional area of the bucking cylindre and the outer support # support structure per coil [m2] - # physics_variables.itart = 1 : Only valid at mid-plane + # self.data.physics.itart = 1 : Only valid at mid-plane tfcoil_variables.a_tf_coil_inboard_case = ( tfcoil_variables.a_tf_inboard_total / tfcoil_variables.n_tf_coils ) - superconducting_tf_coil_variables.a_tf_wp_with_insulation @@ -490,7 +489,7 @@ def tf_res_heating(self): ) # Calculations dedicated for configurations with CP - if physics_variables.itart == 1: + if self.data.physics.itart == 1: # Tricky trick to make the leg / CP tempearture the same if ( abs(tfcoil_variables.temp_tf_legs_outboard + 1.0e0) @@ -547,7 +546,7 @@ def tf_res_heating(self): ) # Leg cross-section areas - # Rem : For physics_variables.itart = 1, these quantitire corresponds to + # Rem : For self.data.physics.itart = 1, these quantitire corresponds to # the outer leg only # --- # Leg ground insulation area per coil [m2] @@ -594,7 +593,7 @@ def tf_res_heating(self): ) # --- - if physics_variables.itart == 1: + if self.data.physics.itart == 1: # Outer leg resistive power loss # --- # TF outboard leg's resistance calculation (per leg) [ohm] @@ -659,7 +658,7 @@ def tf_res_heating(self): # power losses tfcoil_variables.p_tf_leg_resistive = 0.0e0 - # No joints if physics_variables.itart = 0 + # No joints if self.data.physics.itart = 0 tfcoil_variables.p_tf_joints_resistive = 0.0e0 def resistive_tf_coil_areas_and_masses(self): @@ -676,7 +675,7 @@ def resistive_tf_coil_areas_and_masses(self): # ------- # CP with joints # --- - if physics_variables.itart == 1: + if self.data.physics.itart == 1: # Total volume of one outerleg [m3] tfcoil_variables.voltfleg = ( tfcoil_variables.len_tf_coil * tfcoil_variables.a_tf_leg_outboard @@ -763,7 +762,7 @@ def resistive_tf_coil_areas_and_masses(self): tfcoil_variables.whtconal = 0.0e0 # Outer legs/CP weights - if physics_variables.itart == 1: + if self.data.physics.itart == 1: # Weight of all the TF legs tfcoil_variables.whttflgs = tfcoil_variables.n_tf_coils * ( constants.den_copper * vol_cond_leg @@ -786,7 +785,7 @@ def resistive_tf_coil_areas_and_masses(self): # Cryo-aluminium conductor weights # Casing made of re-inforced aluminium alloy elif tfcoil_variables.i_tf_sup == TFConductorModel.HELIUM_COOLED_ALUMINIUM: - # Casing weight (CP only if physics_variables.itart = 1)bper leg/coil + # Casing weight (CP only if self.data.physics.itart = 1)bper leg/coil tfcoil_variables.m_tf_coil_case = ( constants.den_aluminium * vol_case / tfcoil_variables.n_tf_coils ) @@ -796,7 +795,7 @@ def resistive_tf_coil_areas_and_masses(self): ) # Outer legs/CP weights - if physics_variables.itart == 1: + if self.data.physics.itart == 1: # Weight of all the TF legs tfcoil_variables.whttflgs = tfcoil_variables.n_tf_coils * ( constants.den_aluminium * vol_cond_leg diff --git a/process/models/tfcoil/superconducting.py b/process/models/tfcoil/superconducting.py index 1a9d7283dc..ab15ffe648 100644 --- a/process/models/tfcoil/superconducting.py +++ b/process/models/tfcoil/superconducting.py @@ -14,7 +14,6 @@ from process.core.exceptions import ProcessValueError from process.data_structure import ( global_variables, - physics_variables, rebco_variables, superconducting_tf_coil_variables, tfcoil_variables, @@ -366,7 +365,7 @@ def run_base_superconducting_tf(self): dr_tf_inboard=self.data.build.dr_tf_inboard, r_tf_arc=tfcoil_variables.r_tf_arc, z_tf_arc=tfcoil_variables.z_tf_arc, - itart=physics_variables.itart, + itart=self.data.physics.itart, i_tf_shape=tfcoil_variables.i_tf_shape, z_tf_inside_half=self.data.build.z_tf_inside_half, dr_tf_outboard=self.data.build.dr_tf_outboard, @@ -401,10 +400,10 @@ def run_base_superconducting_tf(self): c_tf_total=tfcoil_variables.c_tf_total, n_tf_coils=tfcoil_variables.n_tf_coils, dr_tf_plasma_case=tfcoil_variables.dr_tf_plasma_case, - rmajor=physics_variables.rmajor, - b_plasma_toroidal_on_axis=physics_variables.b_plasma_toroidal_on_axis, + rmajor=self.data.physics.rmajor, + b_plasma_toroidal_on_axis=self.data.physics.b_plasma_toroidal_on_axis, r_cp_top=self.data.build.r_cp_top, - itart=physics_variables.itart, + itart=self.data.physics.itart, i_cp_joints=tfcoil_variables.i_cp_joints, f_vforce_inboard=tfcoil_variables.f_vforce_inboard, ) @@ -1448,7 +1447,7 @@ def superconducting_tf_coil_areas_and_masses(self): # The 2.2 factor is used as a scaling factor to fit # to the ITER-FDR value of 450 tonnes; see CCFE note T&M/PKNIGHT/PROCESS/026 - if physics_variables.itart == 1: + if self.data.physics.itart == 1: # tfcoil_variables.len_tf_coil does not include inboard leg # ('centrepost') length in TART tfcoil_variables.m_tf_coil_case = ( @@ -1534,7 +1533,7 @@ def superconducting_tf_coil_areas_and_masses(self): # If spherical tokamak, distribute between centrepost and outboard legs # (in this case, total TF coil length = inboard `cplen` + # outboard `len_tf_coil`) - if physics_variables.itart == 1: + if self.data.physics.itart == 1: tfleng_sph = tfcoil_variables.cplen + tfcoil_variables.len_tf_coil tfcoil_variables.whtcp = tfcoil_variables.m_tf_coils_total * ( tfcoil_variables.cplen / tfleng_sph diff --git a/process/models/vacuum.py b/process/models/vacuum.py index 904cd57ef2..f4815cfce3 100644 --- a/process/models/vacuum.py +++ b/process/models/vacuum.py @@ -8,7 +8,7 @@ from process.core import constants, process_output from process.core import process_output as po from process.core.model import Model -from process.data_structure import physics_variables, tfcoil_variables +from process.data_structure import tfcoil_variables from process.models.build import FwBlktVVShape from process.models.engineering.ivc_functions import dshellvol, eshellvol @@ -49,8 +49,8 @@ def run(self, output: bool = False): # MDK Check this!! gasld = ( 2.0e0 - * physics_variables.molflow_plasma_fuelling_required - * physics_variables.m_fuel_amu + * self.data.physics.molflow_plasma_fuelling_required + * self.data.physics.m_fuel_amu * constants.UMASS ) @@ -66,16 +66,16 @@ def run(self, output: bool = False): self.data.vacuum.m_vv_vacuum_duct_shield, self.data.vacuum.dia_vv_vacuum_ducts, ) = self.vacuum( - physics_variables.p_fusion_total_mw, - physics_variables.rmajor, - physics_variables.rminor, + self.data.physics.p_fusion_total_mw, + self.data.physics.rmajor, + self.data.physics.rminor, 0.5e0 * ( self.data.build.dr_fw_plasma_gap_inboard + self.data.build.dr_fw_plasma_gap_outboard ), - physics_variables.a_plasma_surface, - physics_variables.vol_plasma, + self.data.physics.a_plasma_surface, + self.data.physics.vol_plasma, self.data.build.dr_shld_outboard, self.data.build.dr_shld_inboard, self.data.build.dr_tf_inboard, @@ -84,7 +84,7 @@ def run(self, output: bool = False): - self.data.build.dr_vv_inboard, tfcoil_variables.n_tf_coils, self.data.times.t_plant_pulse_dwell, - physics_variables.nd_plasma_electrons_vol_avg, + self.data.physics.nd_plasma_electrons_vol_avg, self.data.divertor.n_divertors, qtorus, gasld, @@ -117,7 +117,7 @@ def vacuum_simple(self, output) -> float: # One ITER torus cryopump has a throughput of 50 Pa m3/s = 1.2155e+22 molecules/s # Issue #304 n_iter_vacuum_pumps = ( - physics_variables.molflow_plasma_fuelling_required + self.data.physics.molflow_plasma_fuelling_required / self.data.vacuum.molflow_vac_pumps ) @@ -127,11 +127,11 @@ def vacuum_simple(self, output) -> float: self.data.vacuum.volflow_vac_pumps_max * self.data.vacuum.f_a_vac_pump_port_plasma_surface * self.data.vacuum.f_volflow_vac_pumps_impedance - * physics_variables.a_plasma_surface + * self.data.physics.a_plasma_surface / tfcoil_variables.n_tf_coils ) - wallarea = (physics_variables.a_plasma_surface / 1084.0e0) * 2000.0e0 + wallarea = (self.data.physics.a_plasma_surface / 1084.0e0) * 2000.0e0 # Required pumping speed for pump-down pumpdownspeed = ( self.data.vacuum.outgasfactor @@ -162,7 +162,7 @@ def vacuum_simple(self, output) -> float: self.outfile, "Plasma fuelling rate (nucleus-pairs/s)", "(molflow_plasma_fuelling_required)", - physics_variables.molflow_plasma_fuelling_required, + self.data.physics.molflow_plasma_fuelling_required, "OP ", ) process_output.ocmmnt( @@ -468,8 +468,8 @@ def vacuum( else: logger.error( f"Newton's method not converging; check fusion power, te " - f"{physics_variables.p_fusion_total_mw=} " - f"{physics_variables.temp_plasma_electron_vol_avg_kev=}" + f"{self.data.physics.p_fusion_total_mw=} " + f"{self.data.physics.temp_plasma_electron_vol_avg_kev=}" ) theta = math.pi / ntf @@ -741,7 +741,7 @@ def run(self): ) # D-shaped blanket and shield if ( - physics_variables.itart == 1 + self.data.physics.itart == 1 or self.data.fwbs.i_fw_blkt_vv_shape == FwBlktVVShape.D_SHAPED ): ( @@ -763,9 +763,9 @@ def run(self): self.data.blanket.vol_vv_outboard, self.data.fwbs.vol_vv, ) = self.calculate_elliptical_vessel_volumes( - rmajor=physics_variables.rmajor, - rminor=physics_variables.rminor, - triang=physics_variables.triang, + rmajor=self.data.physics.rmajor, + rminor=self.data.physics.rminor, + triang=self.data.physics.triang, r_shld_inboard_inner=self.data.build.r_shld_inboard_inner, r_shld_outboard_outer=self.data.build.r_shld_outboard_outer, dz_vv_half=self.data.blanket.dz_vv_half, diff --git a/tests/unit/models/blankets/test_blanket_library.py b/tests/unit/models/blankets/test_blanket_library.py index 3375df1c08..0d4a7f531a 100644 --- a/tests/unit/models/blankets/test_blanket_library.py +++ b/tests/unit/models/blankets/test_blanket_library.py @@ -3,10 +3,6 @@ import numpy as np import pytest -from process.data_structure import ( - physics_variables, -) - @pytest.fixture def blanket_library(process_models): @@ -971,12 +967,16 @@ def test_liquid_breeder_properties( liquidbreederpropertiesparam.i_blkt_dual_coolant, ) monkeypatch.setattr( - physics_variables, + blanket_library.data.physics, "b_plasma_toroidal_on_axis", liquidbreederpropertiesparam.b_plasma_toroidal_on_axis, ) - monkeypatch.setattr(physics_variables, "aspect", liquidbreederpropertiesparam.aspect) - monkeypatch.setattr(physics_variables, "rmajor", liquidbreederpropertiesparam.rmajor) + monkeypatch.setattr( + blanket_library.data.physics, "aspect", liquidbreederpropertiesparam.aspect + ) + monkeypatch.setattr( + blanket_library.data.physics, "rmajor", liquidbreederpropertiesparam.rmajor + ) monkeypatch.setattr( blanket_library.data.build, "dr_blkt_inboard", @@ -1640,9 +1640,9 @@ def test_liquid_breeder_properties_part_1(monkeypatch, blanket_library): """ # Set var values monkeypatch.setattr(blanket_library.data.fwbs, "a_bz_liq", 0.2) - monkeypatch.setattr(physics_variables, "b_plasma_toroidal_on_axis", 6.0) - monkeypatch.setattr(physics_variables, "rmajor", 8.0) - monkeypatch.setattr(physics_variables, "aspect", 3.0) + monkeypatch.setattr(blanket_library.data.physics, "b_plasma_toroidal_on_axis", 6.0) + monkeypatch.setattr(blanket_library.data.physics, "rmajor", 8.0) + monkeypatch.setattr(blanket_library.data.physics, "aspect", 3.0) monkeypatch.setattr(blanket_library.data.build, "dr_blkt_inboard", 0.1) monkeypatch.setattr(blanket_library.data.build, "dr_blkt_outboard", 0.2) monkeypatch.setattr(blanket_library.data.fwbs, "i_blkt_inboard", 1) @@ -1714,9 +1714,9 @@ def test_liquid_breeder_properties_part_2(monkeypatch, blanket_library): """ # Set var values monkeypatch.setattr(blanket_library.data.fwbs, "a_bz_liq", 0.2) - monkeypatch.setattr(physics_variables, "b_plasma_toroidal_on_axis", 6.0) - monkeypatch.setattr(physics_variables, "rmajor", 8.0) - monkeypatch.setattr(physics_variables, "aspect", 3.0) + monkeypatch.setattr(blanket_library.data.physics, "b_plasma_toroidal_on_axis", 6.0) + monkeypatch.setattr(blanket_library.data.physics, "rmajor", 8.0) + monkeypatch.setattr(blanket_library.data.physics, "aspect", 3.0) monkeypatch.setattr(blanket_library.data.build, "dr_blkt_inboard", 0.0) monkeypatch.setattr(blanket_library.data.build, "dr_blkt_outboard", 0.2) monkeypatch.setattr(blanket_library.data.fwbs, "i_blkt_inboard", 0) @@ -1739,9 +1739,9 @@ def test_liquid_breeder_properties_part_3(monkeypatch, blanket_library): """ # Set var values monkeypatch.setattr(blanket_library.data.fwbs, "a_bz_liq", 0.2) - monkeypatch.setattr(physics_variables, "b_plasma_toroidal_on_axis", 6.0) - monkeypatch.setattr(physics_variables, "rmajor", 8.0) - monkeypatch.setattr(physics_variables, "aspect", 3.0) + monkeypatch.setattr(blanket_library.data.physics, "b_plasma_toroidal_on_axis", 6.0) + monkeypatch.setattr(blanket_library.data.physics, "rmajor", 8.0) + monkeypatch.setattr(blanket_library.data.physics, "aspect", 3.0) monkeypatch.setattr(blanket_library.data.build, "dr_blkt_inboard", 0.1) monkeypatch.setattr(blanket_library.data.build, "dr_blkt_outboard", 0.2) monkeypatch.setattr(blanket_library.data.fwbs, "i_blkt_inboard", 1) diff --git a/tests/unit/models/blankets/test_ccfe_hcpb.py b/tests/unit/models/blankets/test_ccfe_hcpb.py index 045acb558b..e9c2966072 100644 --- a/tests/unit/models/blankets/test_ccfe_hcpb.py +++ b/tests/unit/models/blankets/test_ccfe_hcpb.py @@ -4,7 +4,6 @@ from process.data_structure import ( global_variables, - physics_variables, tfcoil_variables, ) @@ -322,12 +321,14 @@ def test_nuclear_heating_magnets(nuclearheatingmagnetsparam, monkeypatch, ccfe_h ) monkeypatch.setattr( - physics_variables, + ccfe_hcpb.data.physics, "p_fusion_total_mw", nuclearheatingmagnetsparam.p_fusion_total_mw, ) - monkeypatch.setattr(physics_variables, "itart", nuclearheatingmagnetsparam.itart) + monkeypatch.setattr( + ccfe_hcpb.data.physics, "itart", nuclearheatingmagnetsparam.itart + ) monkeypatch.setattr( tfcoil_variables, @@ -485,7 +486,9 @@ def test_nuclear_heating_fw(nuclearheatingfwparam, monkeypatch, ccfe_hcpb): ) monkeypatch.setattr( - physics_variables, "p_fusion_total_mw", nuclearheatingfwparam.p_fusion_total_mw + ccfe_hcpb.data.physics, + "p_fusion_total_mw", + nuclearheatingfwparam.p_fusion_total_mw, ) monkeypatch.setattr( @@ -1019,15 +1022,15 @@ def test_powerflow_calc(powerflowcalcparam, monkeypatch, ccfe_hcpb): ) monkeypatch.setattr( - physics_variables, "p_plasma_rad_mw", powerflowcalcparam.p_plasma_rad_mw + ccfe_hcpb.data.physics, "p_plasma_rad_mw", powerflowcalcparam.p_plasma_rad_mw ) monkeypatch.setattr( - physics_variables, "p_fw_alpha_mw", powerflowcalcparam.p_fw_alpha_mw + ccfe_hcpb.data.physics, "p_fw_alpha_mw", powerflowcalcparam.p_fw_alpha_mw ) monkeypatch.setattr( - physics_variables, + ccfe_hcpb.data.physics, "p_plasma_separatrix_mw", powerflowcalcparam.p_plasma_separatrix_mw, ) @@ -1243,7 +1246,7 @@ def test_st_centrepost_nuclear_heating( """ monkeypatch.setattr( - physics_variables, "rmajor", stcentrepostnuclearheatingparam.rmajor + ccfe_hcpb.data.physics, "rmajor", stcentrepostnuclearheatingparam.rmajor ) monkeypatch.setattr( @@ -1482,13 +1485,13 @@ def test_component_masses(componentmassesparam, monkeypatch, ccfe_hcpb): "den_div_structure", componentmassesparam.den_div_structure, ) - monkeypatch.setattr(physics_variables, "rminor", componentmassesparam.rminor) - monkeypatch.setattr(physics_variables, "rmajor", componentmassesparam.rmajor) + monkeypatch.setattr(ccfe_hcpb.data.physics, "rminor", componentmassesparam.rminor) + monkeypatch.setattr(ccfe_hcpb.data.physics, "rmajor", componentmassesparam.rmajor) monkeypatch.setattr( ccfe_hcpb.data.divertor, "n_divertors", componentmassesparam.n_divertors ) monkeypatch.setattr( - physics_variables, "a_plasma_surface", componentmassesparam.a_plasma_surface + ccfe_hcpb.data.physics, "a_plasma_surface", componentmassesparam.a_plasma_surface ) monkeypatch.setattr( ccfe_hcpb.data.build, "dr_blkt_inboard", componentmassesparam.dr_blkt_inboard diff --git a/tests/unit/models/physics/test_current_drive.py b/tests/unit/models/physics/test_current_drive.py index 20a85b17b6..dd543fb7e1 100644 --- a/tests/unit/models/physics/test_current_drive.py +++ b/tests/unit/models/physics/test_current_drive.py @@ -1,9 +1,6 @@ import pytest from process.core import constants -from process.data_structure import ( - physics_variables, -) @pytest.fixture @@ -22,11 +19,11 @@ def test_current_drive_primary_lower_hybrid(current_drive): current_drive.data.current_drive.i_hcd_calculations = 1 current_drive.data.current_drive.p_hcd_primary_extra_heat_mw = 0.0 current_drive.data.current_drive.eta_cd_hcd_secondary = 0.0 - physics_variables.nd_plasma_electrons_vol_avg = 1e20 - physics_variables.temp_plasma_electron_vol_avg_kev = 10 - physics_variables.rmajor = 6.2 - physics_variables.plasma_current = 15e6 - physics_variables.f_c_plasma_auxiliary = 0.2 + current_drive.data.physics.nd_plasma_electrons_vol_avg = 1e20 + current_drive.data.physics.temp_plasma_electron_vol_avg_kev = 10 + current_drive.data.physics.rmajor = 6.2 + current_drive.data.physics.plasma_current = 15e6 + current_drive.data.physics.f_c_plasma_auxiliary = 0.2 current_drive.data.current_drive.eta_lowhyb_injector_wall_plug = 0.4 current_drive.current_drive() @@ -71,11 +68,11 @@ def test_current_drive_primary_lower_hybrid_with_heat(current_drive): 5.0 # Adding primary heat ) current_drive.data.current_drive.eta_cd_hcd_secondary = 0.0 - physics_variables.nd_plasma_electrons_vol_avg = 1e20 - physics_variables.temp_plasma_electron_vol_avg_kev = 10 - physics_variables.rmajor = 6.2 - physics_variables.plasma_current = 15e6 - physics_variables.f_c_plasma_auxiliary = 0.2 + current_drive.data.physics.nd_plasma_electrons_vol_avg = 1e20 + current_drive.data.physics.temp_plasma_electron_vol_avg_kev = 10 + current_drive.data.physics.rmajor = 6.2 + current_drive.data.physics.plasma_current = 15e6 + current_drive.data.physics.f_c_plasma_auxiliary = 0.2 current_drive.data.current_drive.eta_lowhyb_injector_wall_plug = 0.4 current_drive.current_drive() @@ -127,17 +124,17 @@ def test_current_drive_primary_neutral_beam(current_drive): current_drive.data.current_drive.i_hcd_calculations = 1 current_drive.data.current_drive.p_hcd_primary_extra_heat_mw = 0.0 current_drive.data.current_drive.eta_cd_hcd_secondary = 0.0 - physics_variables.nd_plasma_electrons_vol_avg = 1e20 - physics_variables.temp_plasma_electron_vol_avg_kev = 10 - physics_variables.rmajor = 6.2 - physics_variables.plasma_current = 15e6 - physics_variables.f_c_plasma_auxiliary = 0.2 + current_drive.data.physics.nd_plasma_electrons_vol_avg = 1e20 + current_drive.data.physics.temp_plasma_electron_vol_avg_kev = 10 + current_drive.data.physics.rmajor = 6.2 + current_drive.data.physics.plasma_current = 15e6 + current_drive.data.physics.f_c_plasma_auxiliary = 0.2 current_drive.data.current_drive.eta_beam_injector_wall_plug = 0.3 - physics_variables.m_beam_amu = 2.0 - physics_variables.temp_plasma_electron_density_weighted_kev = 10.0 - physics_variables.n_charge_plasma_effective_vol_avg = 2.0 - physics_variables.dlamie = 1.0 - physics_variables.n_charge_plasma_effective_mass_weighted_vol_avg = 0.4 + current_drive.data.physics.m_beam_amu = 2.0 + current_drive.data.physics.temp_plasma_electron_density_weighted_kev = 10.0 + current_drive.data.physics.n_charge_plasma_effective_vol_avg = 2.0 + current_drive.data.physics.dlamie = 1.0 + current_drive.data.physics.n_charge_plasma_effective_mass_weighted_vol_avg = 0.4 current_drive.current_drive() assert current_drive.data.current_drive.eta_cd_hcd_primary == pytest.approx( @@ -176,14 +173,14 @@ def test_current_drive_primary_electron_cyclotron(current_drive): current_drive.data.current_drive.i_hcd_calculations = 1 current_drive.data.current_drive.p_hcd_primary_extra_heat_mw = 0.0 current_drive.data.current_drive.eta_cd_hcd_secondary = 0.0 - physics_variables.nd_plasma_electrons_vol_avg = 1e20 - physics_variables.temp_plasma_electron_vol_avg_kev = 10 - physics_variables.rmajor = 6.2 - physics_variables.plasma_current = 15e6 - physics_variables.f_c_plasma_auxiliary = 0.2 + current_drive.data.physics.nd_plasma_electrons_vol_avg = 1e20 + current_drive.data.physics.temp_plasma_electron_vol_avg_kev = 10 + current_drive.data.physics.rmajor = 6.2 + current_drive.data.physics.plasma_current = 15e6 + current_drive.data.physics.f_c_plasma_auxiliary = 0.2 current_drive.data.current_drive.eta_ecrh_injector_wall_plug = 0.5 - physics_variables.dlamee = 1.0 - physics_variables.temp_plasma_electron_density_weighted_kev = 10.0 + current_drive.data.physics.dlamee = 1.0 + current_drive.data.physics.temp_plasma_electron_density_weighted_kev = 10.0 current_drive.current_drive() assert current_drive.data.current_drive.eta_cd_hcd_primary == pytest.approx( @@ -225,14 +222,14 @@ def test_current_drive_primary_ion_cyclotron(current_drive): current_drive.data.current_drive.i_hcd_calculations = 1 current_drive.data.current_drive.p_hcd_primary_extra_heat_mw = 0.0 current_drive.data.current_drive.eta_cd_hcd_secondary = 0.0 - physics_variables.nd_plasma_electrons_vol_avg = 1e20 - physics_variables.temp_plasma_electron_vol_avg_kev = 10 - physics_variables.rmajor = 6.2 - physics_variables.plasma_current = 15e6 - physics_variables.f_c_plasma_auxiliary = 0.2 + current_drive.data.physics.nd_plasma_electrons_vol_avg = 1e20 + current_drive.data.physics.temp_plasma_electron_vol_avg_kev = 10 + current_drive.data.physics.rmajor = 6.2 + current_drive.data.physics.plasma_current = 15e6 + current_drive.data.physics.f_c_plasma_auxiliary = 0.2 current_drive.data.current_drive.eta_icrh_injector_wall_plug = 0.35 - physics_variables.n_charge_plasma_effective_vol_avg = 2.0 - physics_variables.temp_plasma_electron_density_weighted_kev = 10.0 + current_drive.data.physics.n_charge_plasma_effective_vol_avg = 2.0 + current_drive.data.physics.temp_plasma_electron_density_weighted_kev = 10.0 current_drive.current_drive() assert current_drive.data.current_drive.eta_cd_hcd_primary == pytest.approx( @@ -271,14 +268,14 @@ def test_current_drive_primary_electron_bernstein(current_drive): current_drive.data.current_drive.i_hcd_calculations = 1 current_drive.data.current_drive.p_hcd_primary_extra_heat_mw = 0.0 current_drive.data.current_drive.eta_cd_hcd_secondary = 0.0 - physics_variables.nd_plasma_electrons_vol_avg = 2e20 - physics_variables.temp_plasma_electron_vol_avg_kev = 10 - physics_variables.rmajor = 6.2 - physics_variables.plasma_current = 15e6 - physics_variables.f_c_plasma_auxiliary = 0.2 + current_drive.data.physics.nd_plasma_electrons_vol_avg = 2e20 + current_drive.data.physics.temp_plasma_electron_vol_avg_kev = 10 + current_drive.data.physics.rmajor = 6.2 + current_drive.data.physics.plasma_current = 15e6 + current_drive.data.physics.f_c_plasma_auxiliary = 0.2 current_drive.data.current_drive.eta_ebw_injector_wall_plug = 0.45 - physics_variables.b_plasma_toroidal_on_axis = 2.0 - physics_variables.temp_plasma_electron_density_weighted_kev = 10.0 + current_drive.data.physics.b_plasma_toroidal_on_axis = 2.0 + current_drive.data.physics.temp_plasma_electron_density_weighted_kev = 10.0 current_drive.data.current_drive.n_ecrh_harmonic = 2 current_drive.data.current_drive.xi_ebw = 0.7 constants.ELECTRON_CHARGE = constants.ELECTRON_CHARGE diff --git a/tests/unit/models/physics/test_fusion_reactions.py b/tests/unit/models/physics/test_fusion_reactions.py index f85557a20e..4bd88f99ee 100644 --- a/tests/unit/models/physics/test_fusion_reactions.py +++ b/tests/unit/models/physics/test_fusion_reactions.py @@ -1,4 +1,4 @@ -"""Unit tests for physics_functions.f90.""" +"""Unit tests for fusion_reactions.py.""" from typing import Any, NamedTuple @@ -6,10 +6,15 @@ import pytest from process.core import constants -from process.data_structure import physics_variables as pv from process.models.physics import fusion_reactions as reactions +@pytest.fixture +def fusion_reaction_rate(process_models): + """Fixture to get the FusionReactionRate instance from process_models.""" + return process_models.fusion_reaction_rate + + class SetFusionPowersParam(NamedTuple): f_p_alpha_plasma_deposited: Any = None @@ -131,7 +136,7 @@ class SetFusionPowersParam(NamedTuple): ), ], ) -def test_set_fusion_powers(setfusionpowersparam, monkeypatch): +def test_set_fusion_powers(setfusionpowersparam, monkeypatch, fusion_reaction_rate): """ Automatically generated Regression Unit Test for set_fusion_powers(). @@ -144,12 +149,14 @@ def test_set_fusion_powers(setfusionpowersparam, monkeypatch): :type monkeypatch: _pytest.monkeypatch.monkeypatch """ monkeypatch.setattr( - pv, + fusion_reaction_rate.data.physics, "f_p_alpha_plasma_deposited", setfusionpowersparam.f_p_alpha_plasma_deposited, ) monkeypatch.setattr( - pv, "f_plasma_fuel_deuterium", setfusionpowersparam.f_plasma_fuel_deuterium + fusion_reaction_rate.data.physics, + "f_plasma_fuel_deuterium", + setfusionpowersparam.f_plasma_fuel_deuterium, ) ( @@ -172,6 +179,7 @@ def test_set_fusion_powers(setfusionpowersparam, monkeypatch): pden_plasma_neutron_mw=setfusionpowersparam.pden_plasma_neutron_mw, vol_plasma=setfusionpowersparam.vol_plasma, pden_plasma_alpha_mw=setfusionpowersparam.pden_plasma_alpha_mw, + f_p_alpha_plasma_deposited=setfusionpowersparam.f_p_alpha_plasma_deposited, ) assert pden_alpha_total_mw == pytest.approx( diff --git a/tests/unit/models/physics/test_l_h_transition.py b/tests/unit/models/physics/test_l_h_transition.py index d68df9bd79..9d7cf0bc40 100644 --- a/tests/unit/models/physics/test_l_h_transition.py +++ b/tests/unit/models/physics/test_l_h_transition.py @@ -1,51 +1,16 @@ import pytest -from process.models.physics.bootstrap_current import PlasmaBootstrapCurrent -from process.models.physics.current_drive import ( - CurrentDrive, - ElectronBernstein, - ElectronCyclotron, - IonCyclotron, - LowerHybrid, - NeutralBeam, -) -from process.models.physics.density_limit import PlasmaDensityLimit -from process.models.physics.exhaust import PlasmaExhaust from process.models.physics.l_h_transition import PlasmaConfinementTransition -from process.models.physics.physics import ( - Physics, - PlasmaBeta, - PlasmaInductance, -) -from process.models.physics.plasma_geometry import PlasmaGeom -from process.models.physics.plasma_profiles import PlasmaProfile @pytest.fixture -def physics(): +def physics(process_models): """Provides Physics object for testing. :returns: initialised Physics object :rtype: process.physics.Physics """ - return Physics( - PlasmaProfile(), - CurrentDrive( - PlasmaProfile(), - electron_cyclotron=ElectronCyclotron(plasma_profile=PlasmaProfile()), - ion_cyclotron=IonCyclotron(plasma_profile=PlasmaProfile()), - neutral_beam=NeutralBeam(plasma_profile=PlasmaProfile()), - electron_bernstein=ElectronBernstein(plasma_profile=PlasmaProfile()), - lower_hybrid=LowerHybrid(plasma_profile=PlasmaProfile()), - ), - PlasmaBeta(), - PlasmaInductance(), - PlasmaDensityLimit(), - PlasmaExhaust(), - PlasmaBootstrapCurrent(plasma_profile=PlasmaProfile()), - PlasmaConfinementTransition(), - plasma_geometry=PlasmaGeom(), - ) + return process_models.physics @pytest.mark.parametrize( diff --git a/tests/unit/models/physics/test_physics.py b/tests/unit/models/physics/test_physics.py index 27d4d5e010..1dfcb860b3 100644 --- a/tests/unit/models/physics/test_physics.py +++ b/tests/unit/models/physics/test_physics.py @@ -6,7 +6,6 @@ import pytest from process.core import constants -from process.data_structure import physics_variables from process.models.physics.impurity_radiation import initialise_imprad from process.models.physics.physics import ( DetailedPhysics, @@ -17,7 +16,6 @@ res_diff_time, rether, ) -from process.models.physics.plasma_profiles import PlasmaProfile @pytest.fixture @@ -200,13 +198,13 @@ def test_bootstrap_fraction_nevins(bootstrapfractionnevinsparam, monkeypatch, ph """ monkeypatch.setattr( - physics_variables, + physics.data.physics, "temp_plasma_electron_on_axis_kev", bootstrapfractionnevinsparam.temp_plasma_electron_on_axis_kev, ) monkeypatch.setattr( - physics_variables, + physics.data.physics, "nd_plasma_electron_on_axis", bootstrapfractionnevinsparam.nd_plasma_electron_on_axis, ) @@ -409,126 +407,140 @@ def test_bootstrap_fraction_sauter(bootstrapfractionsauterparam, monkeypatch, ph """ monkeypatch.setattr( - physics_variables, + physics.data.physics, "nd_plasma_ions_total_vol_avg", bootstrapfractionsauterparam.nd_plasma_ions_total_vol_avg, ) - monkeypatch.setattr(physics_variables, "rminor", bootstrapfractionsauterparam.rminor) + monkeypatch.setattr( + physics.data.physics, "rminor", bootstrapfractionsauterparam.rminor + ) monkeypatch.setattr( - physics_variables, + physics.data.physics, "temp_plasma_separatrix_kev", bootstrapfractionsauterparam.temp_plasma_separatrix_kev, ) monkeypatch.setattr( - physics_variables, + physics.data.physics, "temp_plasma_ion_vol_avg_kev", bootstrapfractionsauterparam.temp_plasma_ion_vol_avg_kev, ) - monkeypatch.setattr(physics_variables, "triang", bootstrapfractionsauterparam.triang) + monkeypatch.setattr( + physics.data.physics, "triang", bootstrapfractionsauterparam.triang + ) - monkeypatch.setattr(physics_variables, "q0", bootstrapfractionsauterparam.q0) + monkeypatch.setattr(physics.data.physics, "q0", bootstrapfractionsauterparam.q0) monkeypatch.setattr( - physics_variables, + physics.data.physics, "m_ions_total_amu", bootstrapfractionsauterparam.m_ions_total_amu, ) monkeypatch.setattr( - physics_variables, + physics.data.physics, "n_charge_plasma_effective_vol_avg", bootstrapfractionsauterparam.zeff, ) monkeypatch.setattr( - physics_variables, + physics.data.physics, "radius_plasma_pedestal_density_norm", bootstrapfractionsauterparam.radius_plasma_pedestal_density_norm, ) monkeypatch.setattr( - physics_variables, + physics.data.physics, "b_plasma_toroidal_on_axis", bootstrapfractionsauterparam.b_plasma_toroidal_on_axis, ) monkeypatch.setattr( - physics_variables, "plasma_current", bootstrapfractionsauterparam.plasma_current + physics.data.physics, + "plasma_current", + bootstrapfractionsauterparam.plasma_current, ) monkeypatch.setattr( - physics_variables, + physics.data.physics, "a_plasma_poloidal", bootstrapfractionsauterparam.a_plasma_poloidal, ) monkeypatch.setattr( - physics_variables, + physics.data.physics, "f_plasma_fuel_helium3", bootstrapfractionsauterparam.f_plasma_fuel_helium3, ) monkeypatch.setattr( - physics_variables, + physics.data.physics, "temp_plasma_pedestal_kev", bootstrapfractionsauterparam.temp_plasma_pedestal_kev, ) monkeypatch.setattr( - physics_variables, + physics.data.physics, "nd_plasma_electrons_vol_avg", bootstrapfractionsauterparam.nd_plasma_electrons_vol_avg, ) monkeypatch.setattr( - physics_variables, + physics.data.physics, "temp_plasma_electron_vol_avg_kev", bootstrapfractionsauterparam.te, ) - monkeypatch.setattr(physics_variables, "rmajor", bootstrapfractionsauterparam.rmajor) + monkeypatch.setattr( + physics.data.physics, "rmajor", bootstrapfractionsauterparam.rmajor + ) - monkeypatch.setattr(physics_variables, "q95", bootstrapfractionsauterparam.q95) + monkeypatch.setattr(physics.data.physics, "q95", bootstrapfractionsauterparam.q95) monkeypatch.setattr( - physics_variables, + physics.data.physics, "nd_plasma_separatrix_electron", bootstrapfractionsauterparam.nd_plasma_separatrix_electron, ) monkeypatch.setattr( - physics_variables, + physics.data.physics, "temp_plasma_electron_on_axis_kev", bootstrapfractionsauterparam.temp_plasma_electron_on_axis_kev, ) monkeypatch.setattr( - physics_variables, + physics.data.physics, "nd_plasma_pedestal_electron", bootstrapfractionsauterparam.nd_plasma_pedestal_electron, ) - monkeypatch.setattr(physics_variables, "tbeta", bootstrapfractionsauterparam.tbeta) + monkeypatch.setattr( + physics.data.physics, "tbeta", bootstrapfractionsauterparam.tbeta + ) monkeypatch.setattr( - physics_variables, + physics.data.physics, "nd_plasma_electron_on_axis", bootstrapfractionsauterparam.nd_plasma_electron_on_axis, ) - monkeypatch.setattr(physics_variables, "alphan", bootstrapfractionsauterparam.alphan) + monkeypatch.setattr( + physics.data.physics, "alphan", bootstrapfractionsauterparam.alphan + ) monkeypatch.setattr( - physics_variables, + physics.data.physics, "radius_plasma_pedestal_temp_norm", bootstrapfractionsauterparam.radius_plasma_pedestal_temp_norm, ) - monkeypatch.setattr(physics_variables, "alphat", bootstrapfractionsauterparam.alphat) + monkeypatch.setattr( + physics.data.physics, "alphat", bootstrapfractionsauterparam.alphat + ) physics.plasma_profile.run() bfs, _ = physics.plasma_bootstrap_current.bootstrap_fraction_sauter( physics.plasma_profile @@ -596,23 +608,27 @@ def test_bootstrap_fraction_sakai(bootstrapfractionsakaiparam, monkeypatch, phys """ monkeypatch.setattr( - physics_variables, + physics.data.physics, "beta_poloidal_vol_avg", bootstrapfractionsakaiparam.beta_poloidal, ) - monkeypatch.setattr(physics_variables, "q95", bootstrapfractionsakaiparam.q95) + monkeypatch.setattr(physics.data.physics, "q95", bootstrapfractionsakaiparam.q95) - monkeypatch.setattr(physics_variables, "q0", bootstrapfractionsakaiparam.q0) + monkeypatch.setattr(physics.data.physics, "q0", bootstrapfractionsakaiparam.q0) - monkeypatch.setattr(physics_variables, "alphan", bootstrapfractionsakaiparam.alphan) + monkeypatch.setattr( + physics.data.physics, "alphan", bootstrapfractionsakaiparam.alphan + ) - monkeypatch.setattr(physics_variables, "alphat", bootstrapfractionsakaiparam.alphat) + monkeypatch.setattr( + physics.data.physics, "alphat", bootstrapfractionsakaiparam.alphat + ) - monkeypatch.setattr(physics_variables, "eps", bootstrapfractionsakaiparam.eps) + monkeypatch.setattr(physics.data.physics, "eps", bootstrapfractionsakaiparam.eps) monkeypatch.setattr( - physics_variables, + physics.data.physics, "ind_plasma_internal_norm", bootstrapfractionsakaiparam.ind_plasma_internal_norm, ) @@ -1191,7 +1207,9 @@ def test_calculate_plasma_current(plasmacurrentparam, monkeypatch, physics): :type monkeypatch: _pytest.monkeypatch.monkeypatch """ - monkeypatch.setattr(physics_variables, "beta_total_vol_avg", plasmacurrentparam.beta) + monkeypatch.setattr( + physics.data.physics, "beta_total_vol_avg", plasmacurrentparam.beta + ) plasma_current = physics.current.calculate_plasma_current( i_plasma_current=plasmacurrentparam.i_plasma_current, @@ -1725,190 +1743,196 @@ def test_plasma_composition(plasmacompositionparam, monkeypatch, physics): plasmacompositionparam.m_impurity_amu_array, ) - monkeypatch.setattr(physics_variables, "alphat", plasmacompositionparam.alphat) + monkeypatch.setattr(physics.data.physics, "alphat", plasmacompositionparam.alphat) monkeypatch.setattr( - physics_variables, "i_plasma_ignited", plasmacompositionparam.i_plasma_ignited + physics.data.physics, "i_plasma_ignited", plasmacompositionparam.i_plasma_ignited ) monkeypatch.setattr( - physics_variables, "f_alpha_electron", plasmacompositionparam.f_alpha_electron + physics.data.physics, "f_alpha_electron", plasmacompositionparam.f_alpha_electron ) monkeypatch.setattr( - physics_variables, "m_fuel_amu", plasmacompositionparam.m_fuel_amu + physics.data.physics, "m_fuel_amu", plasmacompositionparam.m_fuel_amu ) monkeypatch.setattr( - physics_variables, + physics.data.physics, "f_plasma_fuel_tritium", plasmacompositionparam.f_plasma_fuel_tritium, ) monkeypatch.setattr( - physics_variables, + physics.data.physics, "nd_plasma_fuel_ions_vol_avg", plasmacompositionparam.nd_plasma_fuel_ions_vol_avg, ) monkeypatch.setattr( - physics_variables, "m_ions_total_amu", plasmacompositionparam.m_ions_total_amu + physics.data.physics, "m_ions_total_amu", plasmacompositionparam.m_ions_total_amu ) monkeypatch.setattr( - physics_variables, + physics.data.physics, "nd_plasma_ions_total_vol_avg", plasmacompositionparam.nd_plasma_ions_total_vol_avg, ) monkeypatch.setattr( - physics_variables, + physics.data.physics, "f_nd_protium_electrons", plasmacompositionparam.f_nd_protium_electrons, ) monkeypatch.setattr( - physics_variables, + physics.data.physics, "n_charge_plasma_effective_mass_weighted_vol_avg", plasmacompositionparam.n_charge_plasma_effective_mass_weighted_vol_avg, ) monkeypatch.setattr( - physics_variables, + physics.data.physics, "f_nd_plasma_carbon_electron", plasmacompositionparam.f_nd_plasma_carbon_electron, ) monkeypatch.setattr( - physics_variables, + physics.data.physics, "f_nd_plasma_oxygen_electron", plasmacompositionparam.f_nd_plasma_oxygen_electron, ) monkeypatch.setattr( - physics_variables, "f_alpha_ion", plasmacompositionparam.f_alpha_ion + physics.data.physics, "f_alpha_ion", plasmacompositionparam.f_alpha_ion ) monkeypatch.setattr( - physics_variables, + physics.data.physics, "f_nd_alpha_electron", plasmacompositionparam.f_nd_alpha_electron, ) - monkeypatch.setattr(physics_variables, "dlamee", plasmacompositionparam.dlamee) + monkeypatch.setattr(physics.data.physics, "dlamee", plasmacompositionparam.dlamee) monkeypatch.setattr( - physics_variables, + physics.data.physics, "f_nd_beam_electron", plasmacompositionparam.f_nd_beam_electron, ) monkeypatch.setattr( - physics_variables, + physics.data.physics, "n_charge_plasma_effective_vol_avg", plasmacompositionparam.zeff, ) monkeypatch.setattr( - physics_variables, + physics.data.physics, "nd_plasma_impurities_vol_avg", plasmacompositionparam.nd_plasma_impurities_vol_avg, ) monkeypatch.setattr( - physics_variables, + physics.data.physics, "f_temp_plasma_electron_density_vol_avg", plasmacompositionparam.f_temp_plasma_electron_density_vol_avg, ) monkeypatch.setattr( - physics_variables, + physics.data.physics, "fusden_alpha_total", plasmacompositionparam.fusden_alpha_total, ) monkeypatch.setattr( - physics_variables, + physics.data.physics, "f_nd_plasma_iron_argon_electron", plasmacompositionparam.f_nd_plasma_iron_argon_electron, ) monkeypatch.setattr( - physics_variables, "m_beam_amu", plasmacompositionparam.m_beam_amu + physics.data.physics, "m_beam_amu", plasmacompositionparam.m_beam_amu ) monkeypatch.setattr( - physics_variables, "temp_plasma_electron_vol_avg_kev", plasmacompositionparam.te + physics.data.physics, + "temp_plasma_electron_vol_avg_kev", + plasmacompositionparam.te, ) monkeypatch.setattr( - physics_variables, + physics.data.physics, "proton_rate_density", plasmacompositionparam.proton_rate_density, ) monkeypatch.setattr( - physics_variables, + physics.data.physics, "f_plasma_fuel_deuterium", plasmacompositionparam.f_plasma_fuel_deuterium, ) - monkeypatch.setattr(physics_variables, "alphan", plasmacompositionparam.alphan) + monkeypatch.setattr(physics.data.physics, "alphan", plasmacompositionparam.alphan) monkeypatch.setattr( - physics_variables, "nd_beam_ions", plasmacompositionparam.nd_beam_ions + physics.data.physics, "nd_beam_ions", plasmacompositionparam.nd_beam_ions ) monkeypatch.setattr( - physics_variables, + physics.data.physics, "f_plasma_fuel_helium3", plasmacompositionparam.f_plasma_fuel_helium3, ) monkeypatch.setattr( - physics_variables, + physics.data.physics, "nd_plasma_alphas_vol_avg", plasmacompositionparam.nd_plasma_alphas_vol_avg, ) monkeypatch.setattr( - physics_variables, + physics.data.physics, "nd_plasma_electrons_vol_avg", plasmacompositionparam.nd_plasma_electrons_vol_avg, ) monkeypatch.setattr( - physics_variables, + physics.data.physics, "nd_plasma_protons_vol_avg", plasmacompositionparam.nd_plasma_protons_vol_avg, ) - monkeypatch.setattr(physics_variables, "iscz", plasmacompositionparam.iscz) + monkeypatch.setattr(physics.data.physics, "iscz", plasmacompositionparam.iscz) - monkeypatch.setattr(physics_variables, "err242", plasmacompositionparam.err242) + monkeypatch.setattr(physics.data.physics, "err242", plasmacompositionparam.err242) - monkeypatch.setattr(physics_variables, "err243", plasmacompositionparam.err243) + monkeypatch.setattr(physics.data.physics, "err243", plasmacompositionparam.err243) - monkeypatch.setattr(physics_variables, "ptarmw", plasmacompositionparam.ptarmw) + monkeypatch.setattr(physics.data.physics, "ptarmw", plasmacompositionparam.ptarmw) - monkeypatch.setattr(physics_variables, "lambdaio", plasmacompositionparam.lambdaio) + monkeypatch.setattr( + physics.data.physics, "lambdaio", plasmacompositionparam.lambdaio + ) - monkeypatch.setattr(physics_variables, "drsep", plasmacompositionparam.drsep) + monkeypatch.setattr(physics.data.physics, "drsep", plasmacompositionparam.drsep) - monkeypatch.setattr(physics_variables, "fio", plasmacompositionparam.fio) + monkeypatch.setattr(physics.data.physics, "fio", plasmacompositionparam.fio) - monkeypatch.setattr(physics_variables, "rho_star", plasmacompositionparam.rho_star) + monkeypatch.setattr( + physics.data.physics, "rho_star", plasmacompositionparam.rho_star + ) - monkeypatch.setattr(physics_variables, "nu_star", plasmacompositionparam.nu_star) + monkeypatch.setattr(physics.data.physics, "nu_star", plasmacompositionparam.nu_star) monkeypatch.setattr( - physics_variables, "beta_mcdonald", plasmacompositionparam.beta_mcdonald + physics.data.physics, "beta_mcdonald", plasmacompositionparam.beta_mcdonald ) - monkeypatch.setattr(physics_variables, "itart_r", plasmacompositionparam.itart_r) + monkeypatch.setattr(physics.data.physics, "itart_r", plasmacompositionparam.itart_r) monkeypatch.setattr( - physics_variables, "first_call", plasmacompositionparam.first_call + physics.data.physics, "first_call", plasmacompositionparam.first_call ) physics.plasma_composition() @@ -1917,56 +1941,56 @@ def test_plasma_composition(plasmacompositionparam, monkeypatch, physics): plasmacompositionparam.expected_impurity_arr_frac ) - assert physics_variables.f_alpha_electron == pytest.approx( + assert physics.data.physics.f_alpha_electron == pytest.approx( plasmacompositionparam.expected_f_alpha_electron ) - assert physics_variables.m_fuel_amu == pytest.approx( + assert physics.data.physics.m_fuel_amu == pytest.approx( plasmacompositionparam.expected_m_fuel_amu ) - assert physics_variables.nd_plasma_fuel_ions_vol_avg == pytest.approx( + assert physics.data.physics.nd_plasma_fuel_ions_vol_avg == pytest.approx( plasmacompositionparam.expected_nd_fuel_ions ) - assert physics_variables.m_ions_total_amu == pytest.approx( + assert physics.data.physics.m_ions_total_amu == pytest.approx( plasmacompositionparam.expected_m_ions_total_amu ) - assert physics_variables.nd_plasma_ions_total_vol_avg == pytest.approx( + assert physics.data.physics.nd_plasma_ions_total_vol_avg == pytest.approx( plasmacompositionparam.expected_nd_ions_total ) assert ( - physics_variables.n_charge_plasma_effective_mass_weighted_vol_avg + physics.data.physics.n_charge_plasma_effective_mass_weighted_vol_avg == pytest.approx(plasmacompositionparam.expected_zeffai) ) - assert physics_variables.f_alpha_ion == pytest.approx( + assert physics.data.physics.f_alpha_ion == pytest.approx( plasmacompositionparam.expected_f_alpha_ion ) - assert physics_variables.n_charge_plasma_effective_vol_avg == pytest.approx( + assert physics.data.physics.n_charge_plasma_effective_vol_avg == pytest.approx( plasmacompositionparam.expected_zeff ) - assert physics_variables.nd_plasma_impurities_vol_avg == pytest.approx( + assert physics.data.physics.nd_plasma_impurities_vol_avg == pytest.approx( plasmacompositionparam.expected_nd_impurities ) - assert physics_variables.m_beam_amu == pytest.approx( + assert physics.data.physics.m_beam_amu == pytest.approx( plasmacompositionparam.expected_m_beam_amu ) - assert physics_variables.nd_plasma_alphas_vol_avg == pytest.approx( + assert physics.data.physics.nd_plasma_alphas_vol_avg == pytest.approx( plasmacompositionparam.expected_nd_alphas ) - assert physics_variables.nd_plasma_protons_vol_avg == pytest.approx( + assert physics.data.physics.nd_plasma_protons_vol_avg == pytest.approx( plasmacompositionparam.expected_nd_protons ) - assert physics_variables.first_call == pytest.approx( + assert physics.data.physics.first_call == pytest.approx( plasmacompositionparam.expected_first_call ) @@ -2224,9 +2248,9 @@ def test_phyaux(phyauxparam, monkeypatch, physics): :type monkeypatch: _pytest.monkeypatch.monkeypatch """ - monkeypatch.setattr(physics_variables, "tauratio", phyauxparam.tauratio) + monkeypatch.setattr(physics.data.physics, "tauratio", phyauxparam.tauratio) - monkeypatch.setattr(physics_variables, "burnup_in", phyauxparam.burnup_in) + monkeypatch.setattr(physics.data.physics, "burnup_in", phyauxparam.burnup_in) ( burnup, @@ -2334,10 +2358,10 @@ def test_pohm(pohmparam, monkeypatch, physics): :type monkeypatch: _pytest.monkeypatch.monkeypatch """ - monkeypatch.setattr(physics_variables, "aspect", pohmparam.aspect) + monkeypatch.setattr(physics.data.physics, "aspect", pohmparam.aspect) monkeypatch.setattr( - physics_variables, "plasma_res_factor", pohmparam.plasma_res_factor + physics.data.physics, "plasma_res_factor", pohmparam.plasma_res_factor ) ( @@ -3240,22 +3264,28 @@ def test_calculate_confinement_time(confinementtimeparam, monkeypatch, physics): :type monkeypatch: _pytest.monkeypatch.monkeypatch """ - monkeypatch.setattr(physics_variables, "i_rad_loss", confinementtimeparam.i_rad_loss) + monkeypatch.setattr( + physics.data.physics, "i_rad_loss", confinementtimeparam.i_rad_loss + ) - monkeypatch.setattr(physics_variables, "tauee_in", confinementtimeparam.tauee_in) + monkeypatch.setattr(physics.data.physics, "tauee_in", confinementtimeparam.tauee_in) monkeypatch.setattr( - physics_variables, "pden_plasma_rad_mw", confinementtimeparam.pden_plasma_rad_mw + physics.data.physics, + "pden_plasma_rad_mw", + confinementtimeparam.pden_plasma_rad_mw, ) - monkeypatch.setattr(physics_variables, "kappa_ipb", confinementtimeparam.kappa_ipb) + monkeypatch.setattr( + physics.data.physics, "kappa_ipb", confinementtimeparam.kappa_ipb + ) monkeypatch.setattr( - physics_variables, "p_plasma_ohmic_mw", confinementtimeparam.p_plasma_ohmic_mw + physics.data.physics, "p_plasma_ohmic_mw", confinementtimeparam.p_plasma_ohmic_mw ) monkeypatch.setattr( - physics_variables, + physics.data.physics, "f_p_alpha_plasma_deposited", confinementtimeparam.f_p_alpha_plasma_deposited, ) @@ -3295,7 +3325,7 @@ def test_calculate_confinement_time(confinementtimeparam, monkeypatch, physics): zeff=confinementtimeparam.zeff, ) - assert physics_variables.kappa_ipb == pytest.approx( + assert physics.data.physics.kappa_ipb == pytest.approx( confinementtimeparam.expected_kappa_ipb ) @@ -3568,139 +3598,142 @@ def test_calculate_debye_length_parametrized(temp_keV, nd, expected): assert result == pytest.approx(expected, rel=1e-12) -def test_detailed_physics_run_computes_profiles(monkeypatch): +def test_detailed_physics_run_computes_profiles(monkeypatch, physics): # Minimal plasma profile - plasma = PlasmaProfile() + plasma = physics.data.plasma_profile plasma.teprofile.profile_x = np.array([0.0, 0.5, 1.0]) plasma.teprofile.profile_y = np.array([1.0, 2.0, 3.0]) # keV plasma.neprofile.profile_x = plasma.teprofile.profile_x plasma.neprofile.profile_y = np.array([1.0e19, 2.0e19, 3.0e19]) # m^-3 monkeypatch.setattr( - physics_variables, + physics.data.physics, "temp_plasma_electron_vol_avg_kev", np.mean(plasma.teprofile.profile_y), ) monkeypatch.setattr( - physics_variables, + physics.data.physics, "nd_plasma_electrons_vol_avg", np.mean(plasma.neprofile.profile_y), ) monkeypatch.setattr( - physics_variables, + physics.data.physics, "b_plasma_toroidal_profile", np.ones(2 * len(plasma.neprofile.profile_y)) * 5.0, ) monkeypatch.setattr( - physics_variables, + physics.data.physics, "b_plasma_toroidal_on_axis", 5.0, ) monkeypatch.setattr( - physics_variables, + physics.data.physics, "f_temp_plasma_ion_electron", 1.0, ) monkeypatch.setattr( - physics_variables, + physics.data.physics, "f_plasma_fuel_deuterium", 0.5, ) monkeypatch.setattr( - physics_variables, + physics.data.physics, "f_plasma_fuel_tritium", 0.5, ) monkeypatch.setattr( - physics_variables, + physics.data.physics, "nd_plasma_fuel_ions_vol_avg", np.mean(plasma.neprofile.profile_y), ) monkeypatch.setattr( - physics_variables, + physics.data.physics, "nd_plasma_alphas_vol_avg", np.mean(plasma.neprofile.profile_y) * 0.1, ) # Set global physics variables required by DetailedPhysics.run - physics_variables.temp_plasma_electron_vol_avg_kev = float( + physics.data.physics.temp_plasma_electron_vol_avg_kev = float( np.mean(plasma.teprofile.profile_y) ) - physics_variables.nd_plasma_electrons_vol_avg = float( + physics.data.physics.nd_plasma_electrons_vol_avg = float( np.mean(plasma.neprofile.profile_y) ) # toroidal field profile for larmor frequency calc - physics_variables.b_plasma_toroidal_profile = ( + physics.data.physics.b_plasma_toroidal_profile = ( np.ones(2 * len(plasma.neprofile.profile_y)) * 5.0 ) dp = DetailedPhysics(plasma) - # Run should complete without error and populate physics_variables + # Run should complete without error and populate physics.data.physics dp.run() n = len(plasma.teprofile.profile_y) - assert physics_variables.len_plasma_debye_electron_vol_avg > 0 - assert hasattr(physics_variables, "len_plasma_debye_electron_profile") - assert np.shape(physics_variables.len_plasma_debye_electron_profile)[0] == n + assert physics.data.physics.len_plasma_debye_electron_vol_avg > 0 + assert hasattr(physics.data.physics, "len_plasma_debye_electron_profile") + assert np.shape(physics.data.physics.len_plasma_debye_electron_profile)[0] == n - assert np.shape(physics_variables.vel_plasma_electron_profile)[0] == n - assert np.all(np.isfinite(physics_variables.vel_plasma_electron_profile)) + assert np.shape(physics.data.physics.vel_plasma_electron_profile)[0] == n + assert np.all(np.isfinite(physics.data.physics.vel_plasma_electron_profile)) - assert np.shape(physics_variables.freq_plasma_electron_profile)[0] == n - assert np.all(np.isfinite(physics_variables.freq_plasma_electron_profile)) + assert np.shape(physics.data.physics.freq_plasma_electron_profile)[0] == n + assert np.all(np.isfinite(physics.data.physics.freq_plasma_electron_profile)) assert ( - np.shape(physics_variables.freq_plasma_larmor_toroidal_electron_profile)[0] + np.shape(physics.data.physics.freq_plasma_larmor_toroidal_electron_profile)[0] == n * 2 ) assert np.all( - np.isfinite(physics_variables.freq_plasma_larmor_toroidal_electron_profile) + np.isfinite(physics.data.physics.freq_plasma_larmor_toroidal_electron_profile) ) assert ( - np.shape(physics_variables.plasma_coulomb_log_electron_electron_profile)[0] == n + np.shape(physics.data.physics.plasma_coulomb_log_electron_electron_profile)[0] + == n ) assert np.all( - np.isfinite(physics_variables.plasma_coulomb_log_electron_electron_profile) + np.isfinite(physics.data.physics.plasma_coulomb_log_electron_electron_profile) ) assert ( - np.shape(physics_variables.t_plasma_electron_electron_collision_profile)[0] == n + np.shape(physics.data.physics.t_plasma_electron_electron_collision_profile)[0] + == n ) assert np.all( - np.isfinite(physics_variables.t_plasma_electron_electron_collision_profile) + np.isfinite(physics.data.physics.t_plasma_electron_electron_collision_profile) ) assert ( - np.shape(physics_variables.freq_plasma_electron_electron_collision_profile)[0] + np.shape(physics.data.physics.freq_plasma_electron_electron_collision_profile)[0] == n ) assert np.all( - np.isfinite(physics_variables.freq_plasma_electron_electron_collision_profile) + np.isfinite(physics.data.physics.freq_plasma_electron_electron_collision_profile) ) assert ( - np.shape(physics_variables.len_plasma_electron_electron_mean_free_path_profile)[ - 0 - ] + np.shape( + physics.data.physics.len_plasma_electron_electron_mean_free_path_profile + )[0] == n ) assert np.all( np.isfinite( - physics_variables.len_plasma_electron_electron_mean_free_path_profile + physics.data.physics.len_plasma_electron_electron_mean_free_path_profile ) ) assert ( - np.shape(physics_variables.t_plasma_electron_alpha_spitzer_slow_profile)[0] == n + np.shape(physics.data.physics.t_plasma_electron_alpha_spitzer_slow_profile)[0] + == n ) assert np.all( - np.isfinite(physics_variables.t_plasma_electron_alpha_spitzer_slow_profile) + np.isfinite(physics.data.physics.t_plasma_electron_alpha_spitzer_slow_profile) ) - assert np.shape(physics_variables.res_plasma_fuel_spitzer_profile)[0] == n - assert np.all(np.isfinite(physics_variables.res_plasma_fuel_spitzer_profile)) + assert np.shape(physics.data.physics.res_plasma_fuel_spitzer_profile)[0] == n + assert np.all(np.isfinite(physics.data.physics.res_plasma_fuel_spitzer_profile)) @pytest.mark.parametrize( diff --git a/tests/unit/models/physics/test_plasma_profiles.py b/tests/unit/models/physics/test_plasma_profiles.py index 562792b275..c630b03758 100644 --- a/tests/unit/models/physics/test_plasma_profiles.py +++ b/tests/unit/models/physics/test_plasma_profiles.py @@ -3,7 +3,6 @@ import numpy as np import pytest -from process.data_structure import physics_variables from process.models.physics.profiles import NeProfile, TeProfile @@ -60,8 +59,13 @@ def test_neprofile(neprofileparam: ProfileParam, monkeypatch): assert neprofile.profile_y == pytest.approx(neprofileparam.expected_neprofile) -def test_ncore(): - neprofile = NeProfile(10) +def test_ncore(monkeypatch, plasmaprofile): + monkeypatch.setattr( + plasmaprofile.data.physics, + "n_plasma_profile_elements", + 10, + ) + neprofile = NeProfile() radius_plasma_pedestal_density_norm = 0.94 nped = 5.8300851381352219e19 nsep = 3.4294618459618943e19 @@ -108,17 +112,22 @@ class TeProfileParam(NamedTuple): ], ids=["baseline_2018"], ) -def test_teprofile(teprofileparam: ProfileParam, monkeypatch): +def test_teprofile(teprofileparam: ProfileParam, monkeypatch, plasmaprofile): monkeypatch.setattr( - physics_variables, "i_plasma_pedestal", teprofileparam.i_plasma_pedestal + plasmaprofile.data.physics, "i_plasma_pedestal", teprofileparam.i_plasma_pedestal ) - teprofile = TeProfile(10) + monkeypatch.setattr( + plasmaprofile.data.physics, + "n_plasma_profile_elements", + 10, + ) + teprofile = TeProfile() teprofile.run() assert teprofile.profile_y == pytest.approx(teprofileparam.expected_teprofile) def test_tcore(): - teprofile = TeProfile(10) + teprofile = TeProfile() radius_plasma_pedestal_temp_norm = 0.94 tped = 3.7775374842470044 tsep = 0.1 @@ -327,154 +336,165 @@ def test_plasma_profiles(plasmaprofilesparam, monkeypatch, plasmaprofile): :param monkeypatch: pytest fixture used to mock module/class variables :type monkeypatch: _pytest.monkeypatch.monkeypatch """ - monkeypatch.setattr(plasmaprofile.data.divertor, "prn1", plasmaprofilesparam.prn1) monkeypatch.setattr( - physics_variables, + plasmaprofile.data.physics, "radius_plasma_pedestal_temp_norm", plasmaprofilesparam.radius_plasma_pedestal_temp_norm, ) monkeypatch.setattr( - physics_variables, + plasmaprofile.data.physics, "temp_plasma_electron_density_weighted_kev", plasmaprofilesparam.temp_plasma_electron_density_weighted_kev, ) monkeypatch.setattr( - physics_variables, + plasmaprofile.data.physics, "temp_plasma_ion_density_weighted_kev", plasmaprofilesparam.temp_plasma_ion_density_weighted_kev, ) - monkeypatch.setattr(physics_variables, "alphap", plasmaprofilesparam.alphap) + monkeypatch.setattr(plasmaprofile.data.physics, "alphap", plasmaprofilesparam.alphap) - monkeypatch.setattr(physics_variables, "tbeta", plasmaprofilesparam.tbeta) + monkeypatch.setattr(plasmaprofile.data.physics, "tbeta", plasmaprofilesparam.tbeta) monkeypatch.setattr( - physics_variables, + plasmaprofile.data.physics, "temp_plasma_electron_on_axis_kev", plasmaprofilesparam.temp_plasma_electron_on_axis_kev, ) monkeypatch.setattr( - physics_variables, + plasmaprofile.data.physics, "pres_plasma_thermal_on_axis", plasmaprofilesparam.pres_plasma_thermal_on_axis, ) monkeypatch.setattr( - physics_variables, + plasmaprofile.data.physics, "nd_plasma_separatrix_electron", plasmaprofilesparam.nd_plasma_separatrix_electron, ) monkeypatch.setattr( - physics_variables, + plasmaprofile.data.physics, "temp_plasma_separatrix_kev", plasmaprofilesparam.temp_plasma_separatrix_kev, ) monkeypatch.setattr( - physics_variables, + plasmaprofile.data.physics, "f_temp_plasma_electron_density_vol_avg", plasmaprofilesparam.f_temp_plasma_electron_density_vol_avg, ) monkeypatch.setattr( - physics_variables, "i_plasma_pedestal", plasmaprofilesparam.i_plasma_pedestal + plasmaprofile.data.physics, + "i_plasma_pedestal", + plasmaprofilesparam.i_plasma_pedestal, ) monkeypatch.setattr( - physics_variables, + plasmaprofile.data.physics, "nd_plasma_ions_on_axis", plasmaprofilesparam.nd_plasma_ions_on_axis, ) monkeypatch.setattr( - physics_variables, + plasmaprofile.data.physics, "nd_plasma_electron_on_axis", plasmaprofilesparam.nd_plasma_electron_on_axis, ) monkeypatch.setattr( - physics_variables, + plasmaprofile.data.physics, "temp_plasma_ion_on_axis_kev", plasmaprofilesparam.temp_plasma_ion_on_axis_kev, ) monkeypatch.setattr( - physics_variables, + plasmaprofile.data.physics, "f_temp_plasma_ion_electron", plasmaprofilesparam.f_temp_plasma_ion_electron, ) monkeypatch.setattr( - physics_variables, + plasmaprofile.data.physics, "nd_plasma_electron_line", plasmaprofilesparam.nd_plasma_electron_line, ) - monkeypatch.setattr(physics_variables, "alphat", plasmaprofilesparam.alphat) + monkeypatch.setattr(plasmaprofile.data.physics, "alphat", plasmaprofilesparam.alphat) monkeypatch.setattr( - physics_variables, + plasmaprofile.data.physics, "nd_plasma_ions_total_vol_avg", plasmaprofilesparam.nd_plasma_ions_total_vol_avg, ) monkeypatch.setattr( - physics_variables, + plasmaprofile.data.physics, "nd_plasma_pedestal_electron", plasmaprofilesparam.nd_plasma_pedestal_electron, ) monkeypatch.setattr( - physics_variables, + plasmaprofile.data.physics, "temp_plasma_ion_vol_avg_kev", plasmaprofilesparam.temp_plasma_ion_vol_avg_kev, ) monkeypatch.setattr( - physics_variables, + plasmaprofile.data.physics, "radius_plasma_pedestal_density_norm", plasmaprofilesparam.radius_plasma_pedestal_density_norm, ) monkeypatch.setattr( - physics_variables, + plasmaprofile.data.physics, "nd_plasma_electrons_vol_avg", plasmaprofilesparam.nd_plasma_electrons_vol_avg, ) monkeypatch.setattr( - physics_variables, + plasmaprofile.data.physics, "temp_plasma_pedestal_kev", plasmaprofilesparam.temp_plasma_pedestal_kev, ) - monkeypatch.setattr(physics_variables, "alphan", plasmaprofilesparam.alphan) + monkeypatch.setattr(plasmaprofile.data.physics, "alphan", plasmaprofilesparam.alphan) monkeypatch.setattr( - physics_variables, "temp_plasma_electron_vol_avg_kev", plasmaprofilesparam.te + plasmaprofile.data.physics, + "temp_plasma_electron_vol_avg_kev", + plasmaprofilesparam.te, ) - monkeypatch.setattr(physics_variables, "rho_ne_max", plasmaprofilesparam.rho_ne_max) + monkeypatch.setattr( + plasmaprofile.data.physics, "rho_ne_max", plasmaprofilesparam.rho_ne_max + ) - monkeypatch.setattr(physics_variables, "rho_te_max", plasmaprofilesparam.rho_te_max) + monkeypatch.setattr( + plasmaprofile.data.physics, "rho_te_max", plasmaprofilesparam.rho_te_max + ) monkeypatch.setattr( - physics_variables, "gradient_length_ne", plasmaprofilesparam.gradient_length_ne + plasmaprofile.data.physics, + "gradient_length_ne", + plasmaprofilesparam.gradient_length_ne, ) monkeypatch.setattr( - physics_variables, "gradient_length_te", plasmaprofilesparam.gradient_length_te + plasmaprofile.data.physics, + "gradient_length_te", + plasmaprofilesparam.gradient_length_te, ) - monkeypatch.setattr(physics_variables, "rminor", plasmaprofilesparam.rminor) + monkeypatch.setattr(plasmaprofile.data.physics, "rminor", plasmaprofilesparam.rminor) - monkeypatch.setattr(physics_variables, "a_plasma_poloidal", 4.0) + monkeypatch.setattr(plasmaprofile.data.physics, "a_plasma_poloidal", 4.0) plasmaprofile.run() @@ -482,44 +502,49 @@ def test_plasma_profiles(plasmaprofilesparam, monkeypatch, plasmaprofile): plasmaprofilesparam.expected_prn1 ) - assert physics_variables.temp_plasma_electron_density_weighted_kev == pytest.approx( - plasmaprofilesparam.expected_ten + assert ( + plasmaprofile.data.physics.temp_plasma_electron_density_weighted_kev + == pytest.approx(plasmaprofilesparam.expected_ten) ) - assert physics_variables.temp_plasma_ion_density_weighted_kev == pytest.approx( - plasmaprofilesparam.expected_tin + assert ( + plasmaprofile.data.physics.temp_plasma_ion_density_weighted_kev + == pytest.approx(plasmaprofilesparam.expected_tin) ) - assert physics_variables.alphap == pytest.approx(plasmaprofilesparam.expected_alphap) + assert plasmaprofile.data.physics.alphap == pytest.approx( + plasmaprofilesparam.expected_alphap + ) - assert physics_variables.temp_plasma_electron_on_axis_kev == pytest.approx( + assert plasmaprofile.data.physics.temp_plasma_electron_on_axis_kev == pytest.approx( plasmaprofilesparam.expected_te0 ) - assert physics_variables.pres_plasma_thermal_on_axis == pytest.approx( + assert plasmaprofile.data.physics.pres_plasma_thermal_on_axis == pytest.approx( plasmaprofilesparam.expected_p0 ) - assert physics_variables.f_temp_plasma_electron_density_vol_avg == pytest.approx( - plasmaprofilesparam.expected_pcoef + assert ( + plasmaprofile.data.physics.f_temp_plasma_electron_density_vol_avg + == pytest.approx(plasmaprofilesparam.expected_pcoef) ) - assert physics_variables.nd_plasma_ions_on_axis == pytest.approx( + assert plasmaprofile.data.physics.nd_plasma_ions_on_axis == pytest.approx( plasmaprofilesparam.expected_ni0 ) - assert physics_variables.nd_plasma_electron_on_axis == pytest.approx( + assert plasmaprofile.data.physics.nd_plasma_electron_on_axis == pytest.approx( plasmaprofilesparam.expected_ne0 ) - assert physics_variables.temp_plasma_ion_on_axis_kev == pytest.approx( + assert plasmaprofile.data.physics.temp_plasma_ion_on_axis_kev == pytest.approx( plasmaprofilesparam.expected_ti0 ) - assert physics_variables.nd_plasma_electron_line == pytest.approx( + assert plasmaprofile.data.physics.nd_plasma_electron_line == pytest.approx( plasmaprofilesparam.expected_nd_electron_line ) - assert physics_variables.temp_plasma_ion_vol_avg_kev == pytest.approx( + assert plasmaprofile.data.physics.temp_plasma_ion_vol_avg_kev == pytest.approx( plasmaprofilesparam.expected_ti ) diff --git a/tests/unit/models/stellarator/test_neoclassics.py b/tests/unit/models/stellarator/test_neoclassics.py index b96e0eefcf..e789d0dc39 100644 --- a/tests/unit/models/stellarator/test_neoclassics.py +++ b/tests/unit/models/stellarator/test_neoclassics.py @@ -3,12 +3,10 @@ import numpy as np import pytest -from process.data_structure import physics_variables - @pytest.fixture def neoclassics(process_models): - """Provides Neoclassics object for testing. + """Fixture to get the Neoclassics instance from process_models. :returns: initialised Neoclassics object :rtype: process.stellerator.Neoclassics @@ -971,57 +969,59 @@ def test_init_neoclassics(initneoclassicsparam, monkeypatch, neoclassics): :type monkeypatch: _pytest.monkeypatch.monkeypatch """ monkeypatch.setattr( - physics_variables, + neoclassics.data.physics, "nd_plasma_electron_on_axis", initneoclassicsparam.nd_plasma_electron_on_axis, ) monkeypatch.setattr( - physics_variables, + neoclassics.data.physics, "temp_plasma_electron_on_axis_kev", initneoclassicsparam.temp_plasma_electron_on_axis_kev, ) - monkeypatch.setattr(physics_variables, "alphan", initneoclassicsparam.alphan) - monkeypatch.setattr(physics_variables, "alphat", initneoclassicsparam.alphat) + monkeypatch.setattr(neoclassics.data.physics, "alphan", initneoclassicsparam.alphan) + monkeypatch.setattr(neoclassics.data.physics, "alphat", initneoclassicsparam.alphat) monkeypatch.setattr( - physics_variables, + neoclassics.data.physics, "temp_plasma_ion_on_axis_kev", initneoclassicsparam.temp_plasma_ion_on_axis_kev, ) monkeypatch.setattr( - physics_variables, + neoclassics.data.physics, "nd_plasma_ions_on_axis", initneoclassicsparam.nd_plasma_ions_on_axis, ) monkeypatch.setattr( - physics_variables, + neoclassics.data.physics, "f_plasma_fuel_deuterium", initneoclassicsparam.f_plasma_fuel_deuterium, ) monkeypatch.setattr( - physics_variables, + neoclassics.data.physics, "nd_plasma_alphas_vol_avg", initneoclassicsparam.nd_plasma_alphas_vol_avg, ) - monkeypatch.setattr(physics_variables, "rminor", initneoclassicsparam.rminor) - monkeypatch.setattr(physics_variables, "rmajor", initneoclassicsparam.rmajor) + monkeypatch.setattr(neoclassics.data.physics, "rminor", initneoclassicsparam.rminor) + monkeypatch.setattr(neoclassics.data.physics, "rmajor", initneoclassicsparam.rmajor) monkeypatch.setattr( - physics_variables, + neoclassics.data.physics, "b_plasma_toroidal_on_axis", initneoclassicsparam.b_plasma_toroidal_on_axis, ) monkeypatch.setattr( - physics_variables, "temp_plasma_electron_vol_avg_kev", initneoclassicsparam.te + neoclassics.data.physics, + "temp_plasma_electron_vol_avg_kev", + initneoclassicsparam.te, ) monkeypatch.setattr( - physics_variables, "temp_plasma_ion_vol_avg_kev", initneoclassicsparam.ti + neoclassics.data.physics, "temp_plasma_ion_vol_avg_kev", initneoclassicsparam.ti ) monkeypatch.setattr( - physics_variables, + neoclassics.data.physics, "nd_plasma_electrons_vol_avg", initneoclassicsparam.nd_plasma_electrons_vol_avg, ) monkeypatch.setattr( - physics_variables, + neoclassics.data.physics, "nd_plasma_fuel_ions_vol_avg", initneoclassicsparam.nd_plasma_fuel_ions_vol_avg, ) diff --git a/tests/unit/models/stellarator/test_stellarator.py b/tests/unit/models/stellarator/test_stellarator.py index bd9359394b..4aece6ac68 100644 --- a/tests/unit/models/stellarator/test_stellarator.py +++ b/tests/unit/models/stellarator/test_stellarator.py @@ -3,7 +3,7 @@ import numpy as np import pytest -from process.data_structure import physics_variables, tfcoil_variables +from process.data_structure import tfcoil_variables from process.models.stellarator.build import st_build from process.models.stellarator.coils.coils import bmax_from_awp, intersect from process.models.stellarator.coils.quench import ( @@ -114,30 +114,30 @@ def test_stgeom(stgeomparam, monkeypatch, stellarator): :type monkeypatch: _pytest.monkeypatch.monkeypatch """ - monkeypatch.setattr(physics_variables, "aspect", stgeomparam.aspect) + monkeypatch.setattr(stellarator.data.physics, "aspect", stgeomparam.aspect) - monkeypatch.setattr(physics_variables, "rmajor", stgeomparam.rmajor) + monkeypatch.setattr(stellarator.data.physics, "rmajor", stgeomparam.rmajor) - monkeypatch.setattr(physics_variables, "rminor", stgeomparam.rminor) + monkeypatch.setattr(stellarator.data.physics, "rminor", stgeomparam.rminor) monkeypatch.setattr( - physics_variables, "a_plasma_surface", stgeomparam.a_plasma_surface + stellarator.data.physics, "a_plasma_surface", stgeomparam.a_plasma_surface ) monkeypatch.setattr( - physics_variables, + stellarator.data.physics, "a_plasma_surface_outboard", stgeomparam.a_plasma_surface_outboard, ) - monkeypatch.setattr(physics_variables, "vol_plasma", stgeomparam.vol_plasma) + monkeypatch.setattr(stellarator.data.physics, "vol_plasma", stgeomparam.vol_plasma) monkeypatch.setattr( - physics_variables, "a_plasma_poloidal", stgeomparam.a_plasma_poloidal + stellarator.data.physics, "a_plasma_poloidal", stgeomparam.a_plasma_poloidal ) monkeypatch.setattr( - physics_variables, + stellarator.data.physics, "b_plasma_toroidal_on_axis", stgeomparam.b_plasma_toroidal_on_axis, ) @@ -164,17 +164,17 @@ def test_stgeom(stgeomparam, monkeypatch, stellarator): stellarator.st_geom() - assert physics_variables.a_plasma_surface == pytest.approx( + assert stellarator.data.physics.a_plasma_surface == pytest.approx( stgeomparam.expected_a_plasma_surface ) - assert physics_variables.a_plasma_surface_outboard == pytest.approx( + assert stellarator.data.physics.a_plasma_surface_outboard == pytest.approx( stgeomparam.expected_a_plasma_surface_outboard ) - assert physics_variables.vol_plasma == pytest.approx(stgeomparam.expected_vol) + assert stellarator.data.physics.vol_plasma == pytest.approx(stgeomparam.expected_vol) - assert physics_variables.a_plasma_poloidal == pytest.approx( + assert stellarator.data.physics.a_plasma_poloidal == pytest.approx( stgeomparam.expected_a_plasma_poloidal ) @@ -623,12 +623,12 @@ def test_stbild(stbildparam, monkeypatch, stellarator): stellarator.data.heat_transport, "ipowerflow", stbildparam.ipowerflow ) - monkeypatch.setattr(physics_variables, "rmajor", stbildparam.rmajor) + monkeypatch.setattr(stellarator.data.physics, "rmajor", stbildparam.rmajor) - monkeypatch.setattr(physics_variables, "rminor", stbildparam.rminor) + monkeypatch.setattr(stellarator.data.physics, "rminor", stbildparam.rminor) monkeypatch.setattr( - physics_variables, "a_plasma_surface", stbildparam.a_plasma_surface + stellarator.data.physics, "a_plasma_surface", stbildparam.a_plasma_surface ) monkeypatch.setattr( @@ -1900,19 +1900,19 @@ def test_stdlim(stdlimparam, monkeypatch, stellarator): """ monkeypatch.setattr( - physics_variables, + stellarator.data.physics, "nd_plasma_electrons_vol_avg", stdlimparam.nd_plasma_electrons_vol_avg, ) monkeypatch.setattr( - physics_variables, + stellarator.data.physics, "nd_plasma_electron_line", stdlimparam.nd_plasma_electron_line, ) monkeypatch.setattr( - physics_variables, + stellarator.data.physics, "nd_plasma_electrons_max", stdlimparam.nd_plasma_electrons_max, ) @@ -1922,9 +1922,10 @@ def test_stdlim(stdlimparam, monkeypatch, stellarator): powht=stdlimparam.powht, rmajor=stdlimparam.rmajor, rminor=stdlimparam.rminor, + data=stellarator.data, ) - assert physics_variables.nd_plasma_electrons_max == pytest.approx( + assert stellarator.data.physics.nd_plasma_electrons_max == pytest.approx( stdlimparam.expected_dnelimt ) @@ -1955,7 +1956,7 @@ class StdlimEcrhParam(NamedTuple): ), ], ) -def test_stdlim_ecrh(stdlimecrhparam, monkeypatch): +def test_stdlim_ecrh(stdlimecrhparam, monkeypatch, stellarator): """ Automatically generated Regression Unit Test for stdlim_ecrh. @@ -1969,12 +1970,13 @@ def test_stdlim_ecrh(stdlimecrhparam, monkeypatch): """ monkeypatch.setattr( - physics_variables, "i_plasma_pedestal", stdlimecrhparam.i_plasma_pedestal + stellarator.data.physics, "i_plasma_pedestal", stdlimecrhparam.i_plasma_pedestal ) dlimit_ecrh, bt_max = st_d_limit_ecrh( bt_input=stdlimecrhparam.bt_input, gyro_frequency_max=stdlimecrhparam.gyro_frequency_max, + i_plasma_pedestal=stellarator.data.physics.i_plasma_pedestal, ) assert dlimit_ecrh == pytest.approx(stdlimecrhparam.expected_dlimit_ecrh) @@ -2064,46 +2066,48 @@ def test_st_calc_eff_chi(stcalceffchiparam, monkeypatch, stellarator): """ monkeypatch.setattr( - physics_variables, + stellarator.data.physics, "temp_plasma_electron_on_axis_kev", stcalceffchiparam.temp_plasma_electron_on_axis_kev, ) monkeypatch.setattr( - physics_variables, + stellarator.data.physics, "nd_plasma_electron_on_axis", stcalceffchiparam.nd_plasma_electron_on_axis, ) monkeypatch.setattr( - physics_variables, + stellarator.data.physics, "f_p_alpha_plasma_deposited", stcalceffchiparam.f_p_alpha_plasma_deposited, ) monkeypatch.setattr( - physics_variables, + stellarator.data.physics, "pden_alpha_total_mw", stcalceffchiparam.pden_alpha_total_mw, ) monkeypatch.setattr( - physics_variables, + stellarator.data.physics, "pden_plasma_core_rad_mw", stcalceffchiparam.pden_plasma_core_rad_mw, ) - monkeypatch.setattr(physics_variables, "alphan", stcalceffchiparam.alphan) + monkeypatch.setattr(stellarator.data.physics, "alphan", stcalceffchiparam.alphan) - monkeypatch.setattr(physics_variables, "alphat", stcalceffchiparam.alphat) + monkeypatch.setattr(stellarator.data.physics, "alphat", stcalceffchiparam.alphat) - monkeypatch.setattr(physics_variables, "vol_plasma", stcalceffchiparam.vol_plasma) + monkeypatch.setattr( + stellarator.data.physics, "vol_plasma", stcalceffchiparam.vol_plasma + ) monkeypatch.setattr( - physics_variables, "a_plasma_surface", stcalceffchiparam.a_plasma_surface + stellarator.data.physics, "a_plasma_surface", stcalceffchiparam.a_plasma_surface ) - monkeypatch.setattr(physics_variables, "rminor", stcalceffchiparam.rminor) + monkeypatch.setattr(stellarator.data.physics, "rminor", stcalceffchiparam.rminor) monkeypatch.setattr( stellarator.data.impurity_radiation, @@ -2241,7 +2245,7 @@ def test_sctfcoil_nuclear_heating_iter90( sctfcoilnuclearheatingiter90param.life_plant, ) monkeypatch.setattr( - physics_variables, + stellarator.data.physics, "pflux_fw_neutron_mw", sctfcoilnuclearheatingiter90param.pflux_fw_neutron_mw, ) diff --git a/tests/unit/models/test_availability.py b/tests/unit/models/test_availability.py index 80b695fed9..05d1bc8d85 100644 --- a/tests/unit/models/test_availability.py +++ b/tests/unit/models/test_availability.py @@ -3,7 +3,6 @@ import pytest from process.core.init import init_all_module_vars -from process.data_structure import physics_variables as pv from process.data_structure import tfcoil_variables as tfv @@ -32,11 +31,11 @@ def test_avail_0(monkeypatch, availability, life_fw_fpy, ibkt_life, bktlife_exp_ # Mock module vars monkeypatch.setattr(availability.data.ife, "ife", 0) - monkeypatch.setattr(pv, "p_fusion_total_mw", 4.0e3) + monkeypatch.setattr(availability.data.physics, "p_fusion_total_mw", 4.0e3) monkeypatch.setattr(availability.data.fwbs, "life_fw_fpy", life_fw_fpy) monkeypatch.setattr(availability.data.costs, "ibkt_life", ibkt_life) monkeypatch.setattr(availability.data.costs, "abktflnc", 4.0) - monkeypatch.setattr(pv, "pflux_fw_neutron_mw", 10.0) + monkeypatch.setattr(availability.data.physics, "pflux_fw_neutron_mw", 10.0) monkeypatch.setattr(availability.data.costs, "life_plant", 30.0) monkeypatch.setattr(availability.data.costs, "life_dpa", 40.0) monkeypatch.setattr(availability.data.costs, "adivflnc", 8.0) @@ -45,7 +44,7 @@ def test_avail_0(monkeypatch, availability, life_fw_fpy, ibkt_life, bktlife_exp_ monkeypatch.setattr(availability.data.costs, "i_plant_availability", 0) monkeypatch.setattr(availability.data.costs, "f_t_plant_available", 0.8) monkeypatch.setattr(availability.data.times, "t_plant_pulse_burn", 500.0) - monkeypatch.setattr(pv, "itart", 1) + monkeypatch.setattr(availability.data.physics, "itart", 1) availability.avail(output=False) cpfact_obs = availability.data.costs.cpfact @@ -203,8 +202,10 @@ def calc_u_planned_fix(availability, request, monkeypatch): param["pflux_div_heat_load_mw"], ) monkeypatch.setattr(availability.data.fwbs, "life_blkt_fpy", 0.0) - monkeypatch.setattr(pv, "pflux_fw_neutron_mw", param["pflux_fw_neutron_mw"]) - monkeypatch.setattr(pv, "itart", param["itart"]) + monkeypatch.setattr( + availability.data.physics, "pflux_fw_neutron_mw", param["pflux_fw_neutron_mw"] + ) + monkeypatch.setattr(availability.data.physics, "itart", param["itart"]) monkeypatch.setattr(availability.data.costs, "life_plant", param["life_plant"]) monkeypatch.setattr(availability.data.costs, "life_div_fpy", 0.0) monkeypatch.setattr(availability.data.costs, "adivflnc", param["adivflnc"]) @@ -552,7 +553,7 @@ def mock_calc_u_unplanned_vacuum(*args, **kwargs): monkeypatch.setattr(availability.data.times, "t_plant_pulse_burn", 5.0) monkeypatch.setattr(availability.data.times, "t_plant_pulse_total", 50.0) monkeypatch.setattr(availability.data.ife, "ife", 0) - monkeypatch.setattr(pv, "itart", 1) + monkeypatch.setattr(availability.data.physics, "itart", 1) monkeypatch.setattr(availability.data.fwbs, "life_blkt_fpy", 5.0) monkeypatch.setattr(availability.data.costs, "life_div_fpy", 10.0) monkeypatch.setattr(availability.data.costs, "cplife", 15.0) @@ -600,7 +601,7 @@ def test_avail_st(monkeypatch, availability): monkeypatch.setattr(availability.data.divertor, "pflux_div_heat_load_mw", 10.0) monkeypatch.setattr(availability.data.costs, "ibkt_life", 0) monkeypatch.setattr(availability.data.costs, "abktflnc", 10.0) - monkeypatch.setattr(pv, "pflux_fw_neutron_mw", 10.0) + monkeypatch.setattr(availability.data.physics, "pflux_fw_neutron_mw", 10.0) monkeypatch.setattr(availability.data.costs, "cplife", 5.0) monkeypatch.setattr(availability.data.costs, "life_hcd_fpy", 15.0) @@ -626,7 +627,7 @@ def test_cp_lifetime(monkeypatch, availability, i_tf_sup, exp): monkeypatch.setattr(availability.data.constraints, "nflutfmax", 1.0e23) monkeypatch.setattr(availability.data.fwbs, "neut_flux_cp", 5.0e14) monkeypatch.setattr(availability.data.costs, "cpstflnc", 20.0) - monkeypatch.setattr(pv, "pflux_fw_neutron_mw", 5.0) + monkeypatch.setattr(availability.data.physics, "pflux_fw_neutron_mw", 5.0) monkeypatch.setattr(availability.data.costs, "life_plant", 30.0) cplife = availability.cp_lifetime() diff --git a/tests/unit/models/test_build.py b/tests/unit/models/test_build.py index d832bafc8a..d567cba25c 100644 --- a/tests/unit/models/test_build.py +++ b/tests/unit/models/test_build.py @@ -2,8 +2,6 @@ import pytest -from process.data_structure import physics_variables - @pytest.fixture def build(process_models): @@ -111,17 +109,17 @@ def test_divgeom(divgeomparam, monkeypatch, build): monkeypatch.setattr(build.data.divertor, "betai", divgeomparam.betai) - monkeypatch.setattr(physics_variables, "itart", divgeomparam.itart) + monkeypatch.setattr(build.data.physics, "itart", divgeomparam.itart) - monkeypatch.setattr(physics_variables, "rmajor", divgeomparam.rmajor) + monkeypatch.setattr(build.data.physics, "rmajor", divgeomparam.rmajor) - monkeypatch.setattr(physics_variables, "rminor", divgeomparam.rminor) + monkeypatch.setattr(build.data.physics, "rminor", divgeomparam.rminor) monkeypatch.setattr(build.data.divertor, "n_divertors", divgeomparam.n_divertors) - monkeypatch.setattr(physics_variables, "kappa", divgeomparam.kappa) + monkeypatch.setattr(build.data.physics, "kappa", divgeomparam.kappa) - monkeypatch.setattr(physics_variables, "triang", divgeomparam.triang) + monkeypatch.setattr(build.data.physics, "triang", divgeomparam.triang) divht = build.divgeom(output=False) diff --git a/tests/unit/models/test_buildings.py b/tests/unit/models/test_buildings.py index 96a8a8628b..fe01dc9e74 100644 --- a/tests/unit/models/test_buildings.py +++ b/tests/unit/models/test_buildings.py @@ -2,10 +2,7 @@ import pytest -from process.data_structure import ( - physics_variables, - tfcoil_variables, -) +from process.data_structure import tfcoil_variables @pytest.fixture @@ -808,8 +805,8 @@ def test_bldgs_sizes(buildings, bldgssizesparam, monkeypatch): monkeypatch.setattr( buildings.data.divertor, "dz_divertor", bldgssizesparam.dz_divertor ) - monkeypatch.setattr(physics_variables, "rmajor", bldgssizesparam.rmajor) - monkeypatch.setattr(physics_variables, "rminor", bldgssizesparam.rminor) + monkeypatch.setattr(buildings.data.physics, "rmajor", bldgssizesparam.rmajor) + monkeypatch.setattr(buildings.data.physics, "rminor", bldgssizesparam.rminor) buildings.bldgs_sizes( tf_radial_dim=bldgssizesparam.tf_radial_dim, diff --git a/tests/unit/models/test_costs_1990.py b/tests/unit/models/test_costs_1990.py index 164c7c4145..d8c4866223 100644 --- a/tests/unit/models/test_costs_1990.py +++ b/tests/unit/models/test_costs_1990.py @@ -6,10 +6,7 @@ import pytest from process import data_structure -from process.data_structure import ( - physics_variables, - tfcoil_variables, -) +from process.data_structure import tfcoil_variables @pytest.fixture @@ -147,8 +144,8 @@ def test_acc2272(monkeypatch, costs): :param monkeypatch: Mock fixture :type monkeypatch: object """ - monkeypatch.setattr(physics_variables, "rndfuel", 7.158e20) - monkeypatch.setattr(physics_variables, "m_fuel_amu", 2.5) + monkeypatch.setattr(costs.data.physics, "rndfuel", 7.158e20) + monkeypatch.setattr(costs.data.physics, "m_fuel_amu", 2.5) monkeypatch.setattr(costs.data.costs, "fkind", 1) monkeypatch.setattr(costs.data.costs, "c2271", 0) @@ -212,7 +209,7 @@ def acc2273_fix(request, monkeypatch, costs): monkeypatch.setattr(costs.data.buildings, "wsvol", param["wsvol"]) monkeypatch.setattr(costs.data.buildings, "volrci", param["volrci"]) monkeypatch.setattr( - physics_variables, "f_plasma_fuel_tritium", param["f_plasma_fuel_tritium"] + costs.data.physics, "f_plasma_fuel_tritium", param["f_plasma_fuel_tritium"] ) # Mock result var as negative, as an expected result is 0 @@ -603,7 +600,7 @@ def acc26_params(): acc26_param(), acc26_param( ireactor=1, - p_fusion_total_mw=physics_variables.p_fusion_total_mw, + p_fusion_total_mw=costs.data.physics.p_fusion_total_mw, p_hcd_electric_total_mw=0.0, tfcmw=data_structure.tfcoil_variables.tfcmw, p_plant_primary_heat_mw=3000.0, @@ -630,7 +627,7 @@ def acc26_fix(request, monkeypatch, costs): monkeypatch.setattr(costs.data.costs, "lsa", 4) monkeypatch.setattr(costs.data.costs, "ireactor", param["ireactor"]) monkeypatch.setattr( - physics_variables, + costs.data.physics, "p_fusion_total_mw", param["p_fusion_total_mw"], ) @@ -1944,7 +1941,7 @@ def test_acc2221(acc2221param, monkeypatch, costs): monkeypatch.setattr(costs.data.costs, "cconfix", acc2221param.cconfix) - monkeypatch.setattr(physics_variables, "itart", acc2221param.itart) + monkeypatch.setattr(costs.data.physics, "itart", acc2221param.itart) monkeypatch.setattr(costs.data.structure, "clgsmass", acc2221param.clgsmass) @@ -4464,11 +4461,11 @@ def test_acc2272_rut(acc2272param, monkeypatch, costs): monkeypatch.setattr(costs.data.ife, "edrive", acc2272param.edrive) - monkeypatch.setattr(physics_variables, "wtgpd", acc2272param.wtgpd) + monkeypatch.setattr(costs.data.physics, "wtgpd", acc2272param.wtgpd) - monkeypatch.setattr(physics_variables, "rndfuel", acc2272param.rndfuel) + monkeypatch.setattr(costs.data.physics, "rndfuel", acc2272param.rndfuel) - monkeypatch.setattr(physics_variables, "m_fuel_amu", acc2272param.m_fuel_amu) + monkeypatch.setattr(costs.data.physics, "m_fuel_amu", acc2272param.m_fuel_amu) monkeypatch.setattr(costs.data.costs, "c227", acc2272param.c227) @@ -4478,7 +4475,7 @@ def test_acc2272_rut(acc2272param, monkeypatch, costs): costs.acc2272() - assert physics_variables.wtgpd == pytest.approx(acc2272param.expected_wtgpd) + assert costs.data.physics.wtgpd == pytest.approx(acc2272param.expected_wtgpd) assert costs.data.costs.c2272 == pytest.approx(acc2272param.expected_c2272) @@ -4546,7 +4543,7 @@ def test_acc2273_rut(acc2273param, monkeypatch, costs): monkeypatch.setattr(costs.data.costs, "fkind", acc2273param.fkind) monkeypatch.setattr( - physics_variables, "f_plasma_fuel_tritium", acc2273param.f_plasma_fuel_tritium + costs.data.physics, "f_plasma_fuel_tritium", acc2273param.f_plasma_fuel_tritium ) monkeypatch.setattr(costs.data.costs, "c227", acc2273param.c227) @@ -5308,7 +5305,7 @@ def test_acc26_rut(acc26param, monkeypatch, costs): ) monkeypatch.setattr( - physics_variables, + costs.data.physics, "p_fusion_total_mw", acc26param.p_fusion_total_mw, ) @@ -5920,12 +5917,12 @@ def test_coelc(coelcparam, monkeypatch, costs): coelcparam.p_plant_electric_net_mw, ) - monkeypatch.setattr(physics_variables, "itart", coelcparam.itart) + monkeypatch.setattr(costs.data.physics, "itart", coelcparam.itart) - monkeypatch.setattr(physics_variables, "wtgpd", coelcparam.wtgpd) + monkeypatch.setattr(costs.data.physics, "wtgpd", coelcparam.wtgpd) monkeypatch.setattr( - physics_variables, "f_plasma_fuel_helium3", coelcparam.f_plasma_fuel_helium3 + costs.data.physics, "f_plasma_fuel_helium3", coelcparam.f_plasma_fuel_helium3 ) monkeypatch.setattr( diff --git a/tests/unit/models/test_costs_2015.py b/tests/unit/models/test_costs_2015.py index f619c7ef4f..21f3f11a7c 100644 --- a/tests/unit/models/test_costs_2015.py +++ b/tests/unit/models/test_costs_2015.py @@ -5,10 +5,7 @@ import numpy as np import pytest -from process.data_structure import ( - physics_variables, - tfcoil_variables, -) +from process.data_structure import tfcoil_variables @pytest.fixture @@ -15921,19 +15918,19 @@ def test_calc_remaining_subsystems(calcremainingsubsystemsparam, monkeypatch, co ) monkeypatch.setattr( - physics_variables, + costs2015.data.physics, "p_plasma_separatrix_mw", calcremainingsubsystemsparam.p_plasma_separatrix_mw, ) monkeypatch.setattr( - physics_variables, + costs2015.data.physics, "p_fusion_total_mw", calcremainingsubsystemsparam.p_fusion_total_mw, ) monkeypatch.setattr( - physics_variables, + costs2015.data.physics, "t_plasma_res_diffusion", calcremainingsubsystemsparam.t_plasma_res_diffusion, ) diff --git a/tests/unit/models/test_dcll.py b/tests/unit/models/test_dcll.py index cb28809e0f..ae43764d4a 100644 --- a/tests/unit/models/test_dcll.py +++ b/tests/unit/models/test_dcll.py @@ -2,8 +2,6 @@ import pytest -from process.data_structure import physics_variables - @pytest.fixture def dcll(process_models): @@ -264,19 +262,19 @@ def test_dcll_neutronics_and_power(dcllneutronicsandpowerparam, monkeypatch, dcl ) monkeypatch.setattr( - physics_variables, + dcll.data.physics, "p_neutron_total_mw", dcllneutronicsandpowerparam.p_neutron_total_mw, ) monkeypatch.setattr( - physics_variables, + dcll.data.physics, "p_plasma_rad_mw", dcllneutronicsandpowerparam.p_plasma_rad_mw, ) monkeypatch.setattr( - physics_variables, "p_fw_alpha_mw", dcllneutronicsandpowerparam.p_fw_alpha_mw + dcll.data.physics, "p_fw_alpha_mw", dcllneutronicsandpowerparam.p_fw_alpha_mw ) dcll.dcll_neutronics_and_power(False) @@ -821,11 +819,11 @@ def test_dcll_masses(dcllmassesparam, monkeypatch, dcll): monkeypatch.setattr(dcll.data.build, "blbmoth", dcllmassesparam.blbmoth) monkeypatch.setattr( - physics_variables, "a_plasma_surface", dcllmassesparam.a_plasma_surface + dcll.data.physics, "a_plasma_surface", dcllmassesparam.a_plasma_surface ) monkeypatch.setattr( - physics_variables, + dcll.data.physics, "a_plasma_surface_outboard", dcllmassesparam.a_plasma_surface_outboard, ) diff --git a/tests/unit/models/test_ife.py b/tests/unit/models/test_ife.py index 1802a4cb4f..a348363b83 100644 --- a/tests/unit/models/test_ife.py +++ b/tests/unit/models/test_ife.py @@ -5,8 +5,6 @@ import numpy as np import pytest -from process.data_structure import physics_variables - @pytest.fixture def ife(process_models): @@ -1609,7 +1607,7 @@ def test_ifefbs(ifefbsparam, monkeypatch, ife): monkeypatch.setattr(ife.data.ife, "fbreed", ifefbsparam.fbreed) monkeypatch.setattr(ife.data.ife, "ifetyp", ifefbsparam.ifetyp) monkeypatch.setattr( - physics_variables, "pflux_fw_neutron_mw", ifefbsparam.pflux_fw_neutron_mw + ife.data.physics, "pflux_fw_neutron_mw", ifefbsparam.pflux_fw_neutron_mw ) ife.ifefbs(output=False) @@ -2237,7 +2235,7 @@ def test_ifepw1(ifepw1param, monkeypatch, ife): monkeypatch.setattr(ife.data.ife, "etadrv", ifepw1param.etadrv) monkeypatch.setattr(ife.data.ife, "pifecr", ifepw1param.pifecr) monkeypatch.setattr( - physics_variables, "p_fusion_total_mw", ifepw1param.p_fusion_total_mw + ife.data.physics, "p_fusion_total_mw", ifepw1param.p_fusion_total_mw ) ife.ifepw1() diff --git a/tests/unit/models/test_pfcoil.py b/tests/unit/models/test_pfcoil.py index 5ca0ba00ed..2b3d08631c 100644 --- a/tests/unit/models/test_pfcoil.py +++ b/tests/unit/models/test_pfcoil.py @@ -16,7 +16,6 @@ from numpy.testing import assert_array_almost_equal from process.core import constants -from process.data_structure import physics_variables as pv from process.data_structure import superconducting_tf_coil_variables from process.data_structure import tfcoil_variables as tfv from process.data_structure.pfcoil_variables import N_PF_COILS_IN_GROUP_MAX @@ -2534,19 +2533,19 @@ def test_pfcoil(monkeypatch, pfcoil): monkeypatch.setattr(pfcoil.data.pf_coil, "i_pf_current", 1) monkeypatch.setattr(pfcoil.data.pf_coil, "ccl0_ma", np.full(10, 0.0)) monkeypatch.setattr(pfcoil.data.pf_coil, "ccls_ma", np.full(10, 0.0)) - monkeypatch.setattr(pv, "b_plasma_vertical_required", -6.51e-1) - monkeypatch.setattr(pv, "kappa", 1.727) - monkeypatch.setattr(pv, "ind_plasma_internal_norm", 1.693) - monkeypatch.setattr(pv, "itartpf", 0) - monkeypatch.setattr(pv, "vs_plasma_res_ramp", 6.151e1) - monkeypatch.setattr(pv, "plasma_current", 1.8254e7) - monkeypatch.setattr(pv, "triang", 0.413) - monkeypatch.setattr(pv, "rminor", 2.883) - monkeypatch.setattr(pv, "rmajor", 8.938) - monkeypatch.setattr(pv, "vs_plasma_ind_ramp", 3.497e2) - monkeypatch.setattr(pv, "aspect", 3.1) - monkeypatch.setattr(pv, "itart", 0) - monkeypatch.setattr(pv, "beta_poloidal_vol_avg", 6.313e-1) + monkeypatch.setattr(pfcoil.data.physics, "b_plasma_vertical_required", -6.51e-1) + monkeypatch.setattr(pfcoil.data.physics, "kappa", 1.727) + monkeypatch.setattr(pfcoil.data.physics, "ind_plasma_internal_norm", 1.693) + monkeypatch.setattr(pfcoil.data.physics, "itartpf", 0) + monkeypatch.setattr(pfcoil.data.physics, "vs_plasma_res_ramp", 6.151e1) + monkeypatch.setattr(pfcoil.data.physics, "plasma_current", 1.8254e7) + monkeypatch.setattr(pfcoil.data.physics, "triang", 0.413) + monkeypatch.setattr(pfcoil.data.physics, "rminor", 2.883) + monkeypatch.setattr(pfcoil.data.physics, "rmajor", 8.938) + monkeypatch.setattr(pfcoil.data.physics, "vs_plasma_ind_ramp", 3.497e2) + monkeypatch.setattr(pfcoil.data.physics, "aspect", 3.1) + monkeypatch.setattr(pfcoil.data.physics, "itart", 0) + monkeypatch.setattr(pfcoil.data.physics, "beta_poloidal_vol_avg", 6.313e-1) monkeypatch.setattr(tfv, "tftmp", 4.750) monkeypatch.setattr(tfv, "dcond", np.full(9, 9.0e3)) monkeypatch.setattr(tfv, "i_tf_sup", 1) @@ -2571,7 +2570,7 @@ def test_pfcoil(monkeypatch, pfcoil): pfcoil.pfcoil() - assert pytest.approx(pv.b_plasma_vertical_required) == -0.65121393 + assert pytest.approx(pfcoil.data.physics.b_plasma_vertical_required) == -0.65121393 assert pytest.approx(pfcoil.data.pf_coil.z_pf_coil_middle) == np.array([ 4.86, -4.86, @@ -2675,8 +2674,8 @@ def test_ohcalc(monkeypatch, reinitialise_error_module, cs_coil): "c_pf_cs_coil_pulse_end_ma", np.full(22, -175.84911993600002), ) - monkeypatch.setattr(pv, "rmajor", 8.938) - monkeypatch.setattr(pv, "plasma_current", 1.8254e7) + monkeypatch.setattr(cs_coil.data.physics, "rmajor", 8.938) + monkeypatch.setattr(cs_coil.data.physics, "plasma_current", 1.8254e7) # Mocks for hoop_stress() monkeypatch.setattr(tfv, "poisson_steel", 3.0e-1) @@ -3553,8 +3552,8 @@ def test_peakb(monkeypatch: pytest.MonkeyPatch, pfcoil: PFCoil): *np.zeros(16), ]), ) - monkeypatch.setattr(pv, "rmajor", 8.8901000000000003) - monkeypatch.setattr(pv, "plasma_current", 17721306.969367817) + monkeypatch.setattr(pfcoil.data.physics, "rmajor", 8.8901000000000003) + monkeypatch.setattr(pfcoil.data.physics, "plasma_current", 17721306.969367817) i = 1 ii = 1 @@ -3745,8 +3744,8 @@ def test_induct(pfcoil: PFCoil, monkeypatch: pytest.MonkeyPatch): *np.zeros(14), ]), ) - monkeypatch.setattr(pv, "rmajor", 8.8901000000000003) - monkeypatch.setattr(pv, "ind_plasma", 1.6039223939491056e-05) + monkeypatch.setattr(pfcoil.data.physics, "rmajor", 8.8901000000000003) + monkeypatch.setattr(pfcoil.data.physics, "ind_plasma", 1.6039223939491056e-05) ind_pf_cs_plasma_mutual_exp = np.zeros((22, 22)) ind_pf_cs_plasma_mutual_exp[0, :8] = [ diff --git a/tests/unit/models/test_power.py b/tests/unit/models/test_power.py index f2e9f140ac..ed99f7f088 100644 --- a/tests/unit/models/test_power.py +++ b/tests/unit/models/test_power.py @@ -5,7 +5,6 @@ from process.data_structure import ( numerics, - physics_variables, tfcoil_variables, ) @@ -1845,10 +1844,10 @@ def test_pfpwr(pfpwrparam, monkeypatch, power): ) monkeypatch.setattr( - physics_variables, "p_plasma_ohmic_mw", pfpwrparam.p_plasma_ohmic_mw + power.data.physics, "p_plasma_ohmic_mw", pfpwrparam.p_plasma_ohmic_mw ) - monkeypatch.setattr(physics_variables, "rmajor", pfpwrparam.rmajor) + monkeypatch.setattr(power.data.physics, "rmajor", pfpwrparam.rmajor) monkeypatch.setattr(numerics, "active_constraints", pfpwrparam.active_constraints) @@ -2771,51 +2770,51 @@ def test_power2(power2param, monkeypatch, power): ) monkeypatch.setattr( - physics_variables, "p_alpha_total_mw", power2param.p_alpha_total_mw + power.data.physics, "p_alpha_total_mw", power2param.p_alpha_total_mw ) monkeypatch.setattr( - physics_variables, "i_plasma_ignited", power2param.i_plasma_ignited + power.data.physics, "i_plasma_ignited", power2param.i_plasma_ignited ) monkeypatch.setattr( - physics_variables, "p_plasma_inner_rad_mw", power2param.p_plasma_inner_rad_mw + power.data.physics, "p_plasma_inner_rad_mw", power2param.p_plasma_inner_rad_mw ) monkeypatch.setattr( - physics_variables, "p_plasma_rad_mw", power2param.p_plasma_rad_mw + power.data.physics, "p_plasma_rad_mw", power2param.p_plasma_rad_mw ) - monkeypatch.setattr(physics_variables, "itart", power2param.itart) + monkeypatch.setattr(power.data.physics, "itart", power2param.itart) monkeypatch.setattr( - physics_variables, "p_plasma_separatrix_mw", power2param.p_plasma_separatrix_mw + power.data.physics, "p_plasma_separatrix_mw", power2param.p_plasma_separatrix_mw ) - monkeypatch.setattr(physics_variables, "p_fw_alpha_mw", power2param.p_fw_alpha_mw) + monkeypatch.setattr(power.data.physics, "p_fw_alpha_mw", power2param.p_fw_alpha_mw) monkeypatch.setattr(power.data.divertor, "n_divertors", power2param.n_divertors) monkeypatch.setattr( - physics_variables, "p_plasma_ohmic_mw", power2param.p_plasma_ohmic_mw + power.data.physics, "p_plasma_ohmic_mw", power2param.p_plasma_ohmic_mw ) - monkeypatch.setattr(physics_variables, "i_rad_loss", power2param.i_rad_loss) + monkeypatch.setattr(power.data.physics, "i_rad_loss", power2param.i_rad_loss) monkeypatch.setattr( - physics_variables, "p_fusion_total_mw", power2param.p_fusion_total_mw + power.data.physics, "p_fusion_total_mw", power2param.p_fusion_total_mw ) monkeypatch.setattr( - physics_variables, + power.data.physics, "p_non_alpha_charged_mw", power2param.p_non_alpha_charged_mw, ) - monkeypatch.setattr(physics_variables, "pscalingmw", power2param.pscalingmw) + monkeypatch.setattr(power.data.physics, "pscalingmw", power2param.pscalingmw) monkeypatch.setattr( - physics_variables, + power.data.physics, "f_p_alpha_plasma_deposited", power2param.f_p_alpha_plasma_deposited, ) diff --git a/tests/unit/models/test_pulse.py b/tests/unit/models/test_pulse.py index b0f1c96bfe..119e4b69ed 100644 --- a/tests/unit/models/test_pulse.py +++ b/tests/unit/models/test_pulse.py @@ -3,10 +3,7 @@ import numpy as np import pytest -from process.data_structure import ( - numerics, - physics_variables, -) +from process.data_structure import numerics @pytest.fixture @@ -1237,9 +1234,9 @@ def test_tohswg(tohswgparam, monkeypatch, pulse): tohswgparam.c_pf_coil_turn_peak_input, ) - monkeypatch.setattr(physics_variables, "plasma_current", tohswgparam.plasma_current) + monkeypatch.setattr(pulse.data.physics, "plasma_current", tohswgparam.plasma_current) - monkeypatch.setattr(physics_variables, "rmajor", tohswgparam.rmajor) + monkeypatch.setattr(pulse.data.physics, "rmajor", tohswgparam.rmajor) monkeypatch.setattr(numerics, "active_constraints", tohswgparam.active_constraints) diff --git a/tests/unit/models/test_vacuum.py b/tests/unit/models/test_vacuum.py index 7273cae578..30b27cde0a 100644 --- a/tests/unit/models/test_vacuum.py +++ b/tests/unit/models/test_vacuum.py @@ -2,7 +2,6 @@ import pytest -from process.data_structure import physics_variables as pv from process.data_structure import tfcoil_variables as tfv @@ -39,9 +38,11 @@ def test_simple_model(self, monkeypatch, vacuum): :type tfcoil: tests.unit.test_tfcoil.tfcoil (functional fixture) """ monkeypatch.setattr( - pv, "molflow_plasma_fuelling_required", 7.5745668997694112e22 + vacuum.data.physics, + "molflow_plasma_fuelling_required", + 7.5745668997694112e22, ) - monkeypatch.setattr(pv, "a_plasma_surface", 1500.3146527709359) + monkeypatch.setattr(vacuum.data.physics, "a_plasma_surface", 1500.3146527709359) monkeypatch.setattr(tfv, "n_tf_coils", 18) monkeypatch.setattr(vacuum.data.times, "t_plant_pulse_dwell", 500) monkeypatch.setattr(vacuum.data.vacuum, "outgasfactor", 0.0235) @@ -63,8 +64,10 @@ def test_old_model(self, monkeypatch, vacuum): Values taken from first calling of the model in G-L_Nb-Ti regression test. """ - monkeypatch.setattr(pv, "p_fusion_total_mw", 2115.3899563651776) - monkeypatch.setattr(pv, "temp_plasma_electron_vol_avg_kev", 15.872999999999999) + monkeypatch.setattr(vacuum.data.physics, "p_fusion_total_mw", 2115.3899563651776) + monkeypatch.setattr( + vacuum.data.physics, "temp_plasma_electron_vol_avg_kev", 15.872999999999999 + ) monkeypatch.setattr(vacuum.data.times, "t_plant_pulse_coil_precharge", 30) monkeypatch.setattr(vacuum.data.vacuum, "i_vac_pump_dwell", 0) monkeypatch.setattr(vacuum.data.vacuum, "i_vacuum_pump_type", 1) diff --git a/tests/unit/models/tfcoil/test_resistive_tf_coil.py b/tests/unit/models/tfcoil/test_resistive_tf_coil.py index b8cdeb480b..b99d7134aa 100644 --- a/tests/unit/models/tfcoil/test_resistive_tf_coil.py +++ b/tests/unit/models/tfcoil/test_resistive_tf_coil.py @@ -3,7 +3,6 @@ import pytest from process.data_structure import ( - physics_variables, superconducting_tf_coil_variables, tfcoil_variables, ) @@ -236,7 +235,9 @@ def test_res_tf_internal_geom(restfinternalgeomparam, monkeypatch, resistive_tf_ resistive_tf_coil.data.build, "r_cp_top", restfinternalgeomparam.r_cp_top ) - monkeypatch.setattr(physics_variables, "itart", restfinternalgeomparam.itart) + monkeypatch.setattr( + resistive_tf_coil.data.physics, "itart", restfinternalgeomparam.itart + ) resistive_tf_coil.res_tf_internal_geom() @@ -580,7 +581,7 @@ def test_tf_res_heating(tfresheatingparam, monkeypatch, resistive_tf_coil): tfresheatingparam.r_tf_inboard_out, ) - monkeypatch.setattr(physics_variables, "itart", tfresheatingparam.itart) + monkeypatch.setattr(resistive_tf_coil.data.physics, "itart", tfresheatingparam.itart) monkeypatch.setattr( superconducting_tf_coil_variables, "z_cp_top", tfresheatingparam.z_cp_top diff --git a/tests/unit/models/tfcoil/test_sctfcoil.py b/tests/unit/models/tfcoil/test_sctfcoil.py index 8bcf506d04..64eb4fd171 100644 --- a/tests/unit/models/tfcoil/test_sctfcoil.py +++ b/tests/unit/models/tfcoil/test_sctfcoil.py @@ -5,7 +5,6 @@ from process.data_structure import ( global_variables, - physics_variables, superconducting_tf_coil_variables, tfcoil_variables, ) @@ -1933,7 +1932,7 @@ def test_superconducting_tf_coil_area_and_masses( monkeypatch.setattr( sctfcoil.data.fwbs, "den_steel", tfcoilareaandmassesparam.den_steel ) - monkeypatch.setattr(physics_variables, "itart", tfcoilareaandmassesparam.itart) + monkeypatch.setattr(sctfcoil.data.physics, "itart", tfcoilareaandmassesparam.itart) for name, val in ( ("hr1", tfcoilareaandmassesparam.hr1), From 10c0be6dd761aafda72b30d481f7f5c1f2ea5558 Mon Sep 17 00:00:00 2001 From: Clair Mould <86794332+clmould@users.noreply.github.com> Date: Wed, 20 May 2026 15:28:01 +0100 Subject: [PATCH 02/13] trying to fix test failures --- .../source/physics-models/plasma_beta/plasma_beta.md | 2 +- process/core/io/plot/summary.py | 4 ++-- process/main.py | 2 ++ tests/unit/models/physics/test_physics.py | 8 ++++---- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/documentation/source/physics-models/plasma_beta/plasma_beta.md b/documentation/source/physics-models/plasma_beta/plasma_beta.md index c93f6acbf1..b8ffd0f58e 100644 --- a/documentation/source/physics-models/plasma_beta/plasma_beta.md +++ b/documentation/source/physics-models/plasma_beta/plasma_beta.md @@ -345,7 +345,7 @@ Found as a reasonable fit to the computed no wall limit at $f_{\text{BS}} \appro --------- -#### Tholerus Relation | `calculate_beta_norm_max_thloreus()` +#### Tholerus Relation | `calculate_beta_norm_max_tholerus()` This can be activated by stating `i_beta_norm_max = 4` in the input file. diff --git a/process/core/io/plot/summary.py b/process/core/io/plot/summary.py index e658fb6724..866224a4fb 100644 --- a/process/core/io/plot/summary.py +++ b/process/core/io/plot/summary.py @@ -11904,7 +11904,7 @@ def plot_max_normalised_beta_comparison(axis: plt.Axes, mfile: MFile, scan: int) "beta_norm_max_original_scaling", scan=scan ) beta_norm_max_menard = mfile.get("beta_norm_max_menard", scan=scan) - beta_norm_max_thloreus = mfile.get("beta_norm_max_thloreus", scan=scan) + beta_norm_max_tholerus = mfile.get("beta_norm_max_tholerus", scan=scan) beta_norm_max_stambaugh = mfile.get("beta_norm_max_stambaugh", scan=scan) # Data for the box plot @@ -11912,7 +11912,7 @@ def plot_max_normalised_beta_comparison(axis: plt.Axes, mfile: MFile, scan: int) f"{BetaNormMaxModel.WESSON.full_name}": beta_norm_max_wesson, f"{BetaNormMaxModel.ORIGINAL_SCALING.full_name}": beta_norm_max_original_scaling, f"{BetaNormMaxModel.MENARD.full_name}": beta_norm_max_menard, - f"{BetaNormMaxModel.THOLERUS.full_name}": beta_norm_max_thloreus, + f"{BetaNormMaxModel.THOLERUS.full_name}": beta_norm_max_tholerus, f"{BetaNormMaxModel.STAMBAUGH.full_name}": beta_norm_max_stambaugh, } diff --git a/process/main.py b/process/main.py index f20e4b1d24..116c5e0933 100644 --- a/process/main.py +++ b/process/main.py @@ -754,6 +754,8 @@ def models(self) -> tuple[Model, ...]: self.neoclassics, self.plasma_inductance, self.fusion_reaction_rate, + self.ne_profile, + self.te_profile, ) def setup_data_structure(self): diff --git a/tests/unit/models/physics/test_physics.py b/tests/unit/models/physics/test_physics.py index 1dfcb860b3..fcada17a87 100644 --- a/tests/unit/models/physics/test_physics.py +++ b/tests/unit/models/physics/test_physics.py @@ -3430,19 +3430,19 @@ def test_calculate_beta_norm_max_menard(): assert result == pytest.approx(4.197251361676802, abs=0.000001) -def test_calculate_beta_norm_max_thloreus(): - """Test calculate_beta_norm_max_thloreus()""" +def test_calculate_beta_norm_max_tholerus(): + """Test calculate_beta_norm_max_tholerus()""" c_beta = 0.5 pres_plasma_on_axis = 2.0 pres_plasma_vol_avg = 1.0 - result = PlasmaBeta.calculate_beta_norm_max_thloreus( + result = PlasmaBeta.calculate_beta_norm_max_tholerus( c_beta, pres_plasma_on_axis, pres_plasma_vol_avg ) assert result == pytest.approx(5.075, abs=0.00001) def test_calculate_beta_norm_max_stambaugh(): - """Test calculate_beta_norm_max_thloreus()""" + """Test calculate_beta_norm_max_tholerus()""" f_c_plasma_bootstrap = 0.7 kappa = 2.0 aspect = 2.5 From afc5fc7a7eb9deeae809d6d908594307d5deeabc Mon Sep 17 00:00:00 2001 From: Clair Mould <86794332+clmould@users.noreply.github.com> Date: Thu, 21 May 2026 15:31:29 +0100 Subject: [PATCH 03/13] wip --- process/data_structure/physics_variables.py | 1 - process/main.py | 26 ++++++++++---- process/models/physics/bootstrap_current.py | 23 ++++++++----- process/models/physics/fusion_reactions.py | 24 ++++++++----- process/models/physics/impurity_radiation.py | 34 +++++++++++++------ process/models/physics/l_h_transition.py | 3 +- process/models/physics/physics.py | 9 ++--- process/models/physics/plasma_profiles.py | 2 -- process/models/physics/profiles.py | 14 +++++--- process/models/stellarator/stellarator.py | 9 ++--- tests/unit/models/physics/test_physics.py | 10 ++++-- .../models/physics/test_plasma_profiles.py | 19 ++++++----- tests/unit/models/test_costs_1990.py | 2 +- 13 files changed, 114 insertions(+), 62 deletions(-) diff --git a/process/data_structure/physics_variables.py b/process/data_structure/physics_variables.py index 3871591b1a..8817f489dd 100644 --- a/process/data_structure/physics_variables.py +++ b/process/data_structure/physics_variables.py @@ -1,6 +1,5 @@ """Module containing tokamak plasma physics routines -N/A This module contains all the primary plasma physics routines for a tokamak device. diff --git a/process/main.py b/process/main.py index 116c5e0933..61cae0c347 100644 --- a/process/main.py +++ b/process/main.py @@ -70,7 +70,10 @@ from process.models.fw import FirstWall from process.models.ife import IFE from process.models.pfcoil import CSCoil, PFCoil -from process.models.physics.bootstrap_current import PlasmaBootstrapCurrent +from process.models.physics.bootstrap_current import ( + PlasmaBootstrapCurrent, + SauterBootstrapCurrent, +) from process.models.physics.confinement_time import PlasmaConfinementTime from process.models.physics.current_drive import ( CurrentDrive, @@ -83,7 +86,9 @@ from process.models.physics.density_limit import PlasmaDensityLimit from process.models.physics.exhaust import PlasmaExhaust from process.models.physics.fusion_reactions import FusionReactionRate -from process.models.physics.impurity_radiation import initialise_imprad +from process.models.physics.impurity_radiation import ( + initialise_imprad, +) from process.models.physics.l_h_transition import PlasmaConfinementTransition from process.models.physics.physics import ( DetailedPhysics, @@ -635,14 +640,19 @@ def __init__(self, data: DataStructure): self.plasma_inductance = PlasmaInductance() self.plasma_density_limit = PlasmaDensityLimit() self.plasma_exhaust = PlasmaExhaust() + self.sauter_bootstrap_current = SauterBootstrapCurrent() self.plasma_bootstrap_current = PlasmaBootstrapCurrent( - plasma_profile=self.plasma_profile + plasma_profile=self.plasma_profile, + sauter_bootstrap=self.sauter_bootstrap_current, ) self.plasma_confinement = PlasmaConfinementTime() self.plasma_transition = PlasmaConfinementTransition() self.plasma_current = PlasmaCurrent() self.plasma_fields = PlasmaFields() self.plasma_dia_current = PlasmaDiamagneticCurrent() + self.fusion_reaction_rate = FusionReactionRate( + plasma_profile=self.plasma_profile + ) self.physics = Physics( plasma_profile=self.plasma_profile, current_drive=self.current_drive, @@ -657,6 +667,7 @@ def __init__(self, data: DataStructure): plasma_fields=self.plasma_fields, plasma_dia_current=self.plasma_dia_current, plasma_geometry=self.plasma_geom, + fusion_reactions=self.fusion_reaction_rate, ) self.physics_detailed = DetailedPhysics( plasma_profile=self.plasma_profile, @@ -675,13 +686,10 @@ def __init__(self, data: DataStructure): neoclassics=self.neoclassics, plasma_beta=self.plasma_beta, plasma_bootstrap=self.plasma_bootstrap_current, + fusion_reactions=self.fusion_reaction_rate, ) self.dcll = DCLL(fw=self.fw) - self.fusion_reaction_rate = FusionReactionRate( - plasma_profile=self.plasma_profile - ) - self.setup_data_structure() @property @@ -756,6 +764,10 @@ def models(self) -> tuple[Model, ...]: self.fusion_reaction_rate, self.ne_profile, self.te_profile, + self.plasma_fields, + self.sauter_bootstrap_current, + self.plasma_transition, + self.physics_detailed, ) def setup_data_structure(self): diff --git a/process/models/physics/bootstrap_current.py b/process/models/physics/bootstrap_current.py index a9036d59f6..209a3f66a2 100644 --- a/process/models/physics/bootstrap_current.py +++ b/process/models/physics/bootstrap_current.py @@ -1,8 +1,11 @@ """Bootstrap current models and calculations for plasma physics simulations.""" +from __future__ import annotations + import logging from enum import IntEnum from types import DynamicClassAttribute +from typing import TYPE_CHECKING import numba as nb import numpy as np @@ -13,7 +16,9 @@ from process.core import process_output as po from process.core.exceptions import ProcessValueError from process.core.model import Model -from process.models.physics.plasma_profiles import PlasmaProfile + +if TYPE_CHECKING: + from process.models.physics.plasma_profiles import PlasmaProfile logger = logging.getLogger(__name__) @@ -65,11 +70,13 @@ def full_name(self): class PlasmaBootstrapCurrent(Model): """Class to hold plasma bootstrap current for plasma processing.""" - def __init__(self, plasma_profile: PlasmaProfile) -> None: + def __init__( + self, plasma_profile: PlasmaProfile, sauter_bootstrap: SauterBootstrapCurrent + ) -> None: self.outfile = constants.NOUT self.mfile = constants.MFILE self.plasma_profile = plasma_profile - self.sauter_bootstrap = SauterBootstrapCurrent() + self.sauter_bootstrap = sauter_bootstrap def run(self) -> None: """Calculate bootstrap current fraction using various models. @@ -1443,7 +1450,7 @@ def run(self): def output(self): """This model doesn't have any output""" - def bootstrap_fraction_sauter(self, plasma_profile: float) -> float: + def bootstrap_fraction_sauter(self, plasma_profile: PlasmaProfile) -> float: """Calculate the bootstrap current fraction from the Sauter et al scaling. Parameters @@ -1519,7 +1526,7 @@ def bootstrap_fraction_sauter(self, plasma_profile: float) -> float: # Calculate total bootstrap current (MA) by summing along profiles # Looping from 2 because _calculate_l31_coefficient() etc should return 0 # @ j == 1 - radial_elements = np.arange(2, plasma_profile.profile_size) + radial_elements = np.arange(2, self.data.physics.n_plasma_profile_elements) # Change in localised minor radius to be used as delta term in derivative drho = rho[radial_elements] - rho[radial_elements - 1] @@ -1537,7 +1544,7 @@ def bootstrap_fraction_sauter(self, plasma_profile: float) -> float: * ( self._calculate_l31_coefficient( radial_elements, - plasma_profile.profile_size, + self.data.physics.n_plasma_profile_elements, self.data.physics.rmajor, self.data.physics.b_plasma_toroidal_on_axis, self.data.physics.triang, @@ -1553,7 +1560,7 @@ def bootstrap_fraction_sauter(self, plasma_profile: float) -> float: * dlogne_drho + self._calculate_l31_32_coefficient( radial_elements, - plasma_profile.profile_size, + self.data.physics.n_plasma_profile_elements, self.data.physics.rmajor, self.data.physics.b_plasma_toroidal_on_axis, self.data.physics.triang, @@ -1569,7 +1576,7 @@ def bootstrap_fraction_sauter(self, plasma_profile: float) -> float: * dlogte_drho + self._calculate_l34_alpha_31_coefficient( radial_elements, - plasma_profile.profile_size, + self.data.physics.n_plasma_profile_elements, self.data.physics.rmajor, self.data.physics.b_plasma_toroidal_on_axis, self.data.physics.triang, diff --git a/process/models/physics/fusion_reactions.py b/process/models/physics/fusion_reactions.py index 4ad5305d52..d8c9d3d98c 100644 --- a/process/models/physics/fusion_reactions.py +++ b/process/models/physics/fusion_reactions.py @@ -210,10 +210,11 @@ def dt_reaction(self): # Calculate the fusion reaction rate integral using Simpson's rule sigmav = integrate.simpson( - fusion_rate_integral(self.plasma_profile, dt), + fusion_rate_integral( + self.plasma_profile, dt, physics_data=self.data.physics + ), x=self.plasma_profile.neprofile.profile_x, dx=self.plasma_profile.neprofile.profile_dx, - physics_data=self.data.physics, ) # Store the average fusion reaction rate @@ -290,10 +291,11 @@ def dhe3_reaction(self): # Calculate the fusion reaction rate integral using Simpson's rule sigmav = integrate.simpson( - fusion_rate_integral(self.plasma_profile, dhe3), + fusion_rate_integral( + self.plasma_profile, dhe3, physics_data=self.data.physics + ), x=self.plasma_profile.neprofile.profile_x, dx=self.plasma_profile.neprofile.profile_dx, - physics_data=self.data.physics, ) self.data.physics.fusrat_plasma_dhe3_profile = ( @@ -388,10 +390,13 @@ def dd_helion_reaction(self): # Calculate the fusion reaction rate integral using Simpson's rule sigmav = integrate.simpson( - fusion_rate_integral(self.plasma_profile, dd1), + fusion_rate_integral( + self.plasma_profile, + dd1, + physics_data=self.data.physics, + ), x=self.plasma_profile.neprofile.profile_x, dx=self.plasma_profile.neprofile.profile_dx, - physics_data=self.data.physics, ) self.data.physics.fusrat_plasma_dd_helion_profile = ( @@ -489,10 +494,13 @@ def dd_triton_reaction(self): # Calculate the fusion reaction rate integral using Simpson's rule sigmav = integrate.simpson( - fusion_rate_integral(self.plasma_profile, dd2), + fusion_rate_integral( + self.plasma_profile, + dd2, + physics_data=self.data.physics, + ), x=self.plasma_profile.neprofile.profile_x, dx=self.plasma_profile.neprofile.profile_dx, - physics_data=self.data.physics, ) self.data.physics.fusrat_plasma_dd_triton_profile = ( diff --git a/process/models/physics/impurity_radiation.py b/process/models/physics/impurity_radiation.py index b5138ff369..f4b5363134 100644 --- a/process/models/physics/impurity_radiation.py +++ b/process/models/physics/impurity_radiation.py @@ -575,19 +575,27 @@ def __init__(self, plasma_profile: PlasmaProfile, data_structure: DataStructure) """ self.data = data_structure self.plasma_profile = plasma_profile - self.rho = plasma_profile.neprofile.profile_x - self.rhodx = plasma_profile.neprofile.profile_dx self.imp = np.nonzero( self.data.impurity_radiation.f_nd_impurity_electron_array > 1.0e-30 )[0] - self.pimp_profile = np.zeros(self.plasma_profile.profile_size) - self.pden_impurity_rad_profile = np.zeros(self.plasma_profile.profile_size) - self.pden_impurity_core_rad_profile = np.zeros(self.plasma_profile.profile_size) + self.pimp_profile = np.zeros(self.data.physics.n_plasma_profile_elements) + self.pden_impurity_rad_profile = np.zeros( + self.data.physics.n_plasma_profile_elements + ) + self.pden_impurity_core_rad_profile = np.zeros( + self.data.physics.n_plasma_profile_elements + ) self.pden_impurity_rad_total_mw = 0.0 self.pden_impurity_core_rad_total_mw = 0.0 + def run(self): + """This model isn't run""" + + def output(self): + """This model has no output""" + def map_imprad_profile(self): """Map imprad_profile() over each impurity element index.""" list(map(self.imprad_profile, self.imp)) @@ -624,11 +632,13 @@ def calculate_radiation_loss_profiles(self): radiation (pden_impurity_rad_total_mw). Update the stored arrays with the values. """ - pden_impurity_rad_total = self.pimp_profile * self.rho + pden_impurity_rad_total = ( + self.pimp_profile * self.plasma_profile.neprofile.profile_x + ) pden_impurity_core_rad_total = self.pimp_profile * ( - self.rho + self.plasma_profile.neprofile.profile_x * fradcore( - self.rho, + self.plasma_profile.neprofile.profile_x, self.data.impurity_radiation.radius_plasma_core_norm, self.data.impurity_radiation.f_p_plasma_core_rad_reduction, ) @@ -648,10 +658,14 @@ def integrate_radiation_loss_profiles(self): # 2.0e-6 converts from W/m^3 to MW/m^3 and also accounts for both sides of the # plasma self.pden_impurity_rad_total_mw = 2.0e-6 * integrate.simpson( - self.pden_impurity_rad_profile, x=self.rho, dx=self.rhodx + self.pden_impurity_rad_profile, + x=self.plasma_profile.neprofile.profile_x, + dx=self.plasma_profile.neprofile.profile_dx, ) self.pden_impurity_core_rad_total_mw = 2.0e-6 * integrate.simpson( - self.pden_impurity_core_rad_profile, x=self.rho, dx=self.rhodx + self.pden_impurity_core_rad_profile, + x=self.plasma_profile.neprofile.profile_x, + dx=self.plasma_profile.neprofile.profile_dx, ) def calculate_imprad(self): diff --git a/process/models/physics/l_h_transition.py b/process/models/physics/l_h_transition.py index ac9fb80ee5..48b8760af0 100644 --- a/process/models/physics/l_h_transition.py +++ b/process/models/physics/l_h_transition.py @@ -5,6 +5,7 @@ from process.core import constants from process.core import process_output as po +from process.core.model import Model from process.data_structure import numerics logger = logging.getLogger(__name__) @@ -56,7 +57,7 @@ def __new__(cls, value: int, full_name: str): return obj -class PlasmaConfinementTransition: +class PlasmaConfinementTransition(Model): """Class to calculate plasma L -> H and L -> I transition power thresholds.""" def __init__(self): diff --git a/process/models/physics/physics.py b/process/models/physics/physics.py index 7613bfb768..c5538fb220 100644 --- a/process/models/physics/physics.py +++ b/process/models/physics/physics.py @@ -189,6 +189,7 @@ def __init__( plasma_fields: PlasmaFields, plasma_dia_current: PlasmaDiamagneticCurrent, plasma_geometry: PlasmaGeom, + fusion_reactions: reactions.FusionReactionRate, ): self.outfile = constants.NOUT self.mfile = constants.MFILE @@ -205,6 +206,7 @@ def __init__( self.fields = plasma_fields self.dia_current = plasma_dia_current self.geometry = plasma_geometry + self.fusion_reactions = fusion_reactions def output(self) -> None: """Output plasma physics information.""" @@ -566,12 +568,11 @@ def run(self): # Calculate fusion power + components - fusion_reactions = reactions.FusionReactionRate(self.plasma_profile) - fusion_reactions.deuterium_branching( + self.fusion_reactions.deuterium_branching( self.data.physics.temp_plasma_ion_vol_avg_kev ) - fusion_reactions.calculate_fusion_rates() - fusion_reactions.set_physics_variables() + self.fusion_reactions.calculate_fusion_rates() + self.fusion_reactions.set_physics_variables() # This neglects the power from the beam self.data.physics.p_plasma_dt_mw = ( diff --git a/process/models/physics/plasma_profiles.py b/process/models/physics/plasma_profiles.py index f716aacf14..f2c46857c4 100644 --- a/process/models/physics/plasma_profiles.py +++ b/process/models/physics/plasma_profiles.py @@ -33,8 +33,6 @@ def __init__(self, ne_profile, te_profile): teprofile (TeProfile): An instance of the TeProfile class. """ # Default profile_size = 501, but it's possible to experiment with this value. - self.profile_size = self.data.physics.n_plasma_profile_elements - self.data.physics.n_plasma_profile_elements = self.profile_size self.outfile = constants.NOUT self.neprofile = ne_profile self.teprofile = te_profile diff --git a/process/models/physics/profiles.py b/process/models/physics/profiles.py index 03cf25efce..3fc53ccaea 100644 --- a/process/models/physics/profiles.py +++ b/process/models/physics/profiles.py @@ -51,14 +51,14 @@ def __init__(self): - profile_integ (int): The integral of the profile_y array. - profile_dx (int): The step size between consecutive values in profile_x. """ - self.profile_size = self.data.physics.n_plasma_profile_elements - self.profile_x = np.arange(self.profile_size, dtype=float) - self.profile_y = np.zeros(self.profile_size) self.profile_integ = 0 self.profile_dx = 0 def run(self): - """This model isn't run""" + self.profile_x = np.arange( + self.data.physics.n_plasma_profile_elements, dtype=float + ) + self.profile_y = np.zeros(self.data.physics.n_plasma_profile_elements) def output(self): """This model doesn't have any output""" @@ -87,7 +87,9 @@ def calculate_profile_dx(self): dividing the maximum x value in the profile by the difference in size between the points. The result is stored in the `profile_dx` attribute. """ - self.profile_dx = max(self.profile_x) / (self.profile_size - 1) + self.profile_dx = max(self.profile_x) / ( + self.data.physics.n_plasma_profile_elements - 1 + ) @abstractmethod def calculate_profile_y(self): @@ -114,6 +116,7 @@ class NeProfile(Profile): def run(self): """Subroutine which calls profile functions and stores neprofile data.""" + super().run() self.normalise_profile_x() self.calculate_profile_dx() self.set_physics_variables() @@ -287,6 +290,7 @@ class TeProfile(Profile): def run(self): """Subroutine to initialise neprofile and execute calculations.""" + super().run() self.normalise_profile_x() self.calculate_profile_dx() self.set_physics_variables() diff --git a/process/models/stellarator/stellarator.py b/process/models/stellarator/stellarator.py index 8d60b8f2f7..12e3cc4b61 100644 --- a/process/models/stellarator/stellarator.py +++ b/process/models/stellarator/stellarator.py @@ -91,6 +91,7 @@ def __init__( neoclassics: Neoclassics, plasma_beta, plasma_bootstrap, + fusion_reactions: reactions.FusionReactionRate, ) -> None: self.outfile: int = constants.NOUT self.first_call_stfwbs = True @@ -107,6 +108,7 @@ def __init__( self.neoclassics = neoclassics self.beta = plasma_beta self.bootstrap = plasma_bootstrap + self.fusion_reactions = fusion_reactions def output(self): self.run(output=True) @@ -2006,12 +2008,11 @@ def st_phys(self, output): # Calculate fusion power - fusion_reactions = reactions.FusionReactionRate(self.plasma_profile) - fusion_reactions.deuterium_branching( + self.fusion_reactions.deuterium_branching( self.data.physics.temp_plasma_ion_vol_avg_kev ) - fusion_reactions.calculate_fusion_rates() - fusion_reactions.set_physics_variables() + self.fusion_reactions.calculate_fusion_rates() + self.fusion_reactions.set_physics_variables() # D-T power density is named differently to differentiate it from the beam given component self.data.physics.p_plasma_dt_mw = ( diff --git a/tests/unit/models/physics/test_physics.py b/tests/unit/models/physics/test_physics.py index fcada17a87..b41e11b9b8 100644 --- a/tests/unit/models/physics/test_physics.py +++ b/tests/unit/models/physics/test_physics.py @@ -2270,6 +2270,8 @@ def test_phyaux(phyauxparam, monkeypatch, physics): sbar=phyauxparam.sbar, t_energy_confinement=phyauxparam.t_energy_confinement, vol_plasma=phyauxparam.vol_plasma, + burnup_in=phyauxparam.burnup_in, + tauratio=phyauxparam.tauratio, ) assert burnup == pytest.approx(phyauxparam.expected_burnup) @@ -2378,6 +2380,8 @@ def test_pohm(pohmparam, monkeypatch, physics): temp_plasma_electron_density_weighted_kev=pohmparam.temp_plasma_electron_density_weighted_kev, vol_plasma=pohmparam.vol_plasma, zeff=pohmparam.zeff, + plasma_res_factor=pohmparam.plasma_res_factor, + aspect=pohmparam.aspect, ) assert pden_plasma_ohmic_mw == pytest.approx(pohmparam.expected_pden_plasma_ohmic_mw) @@ -3598,9 +3602,9 @@ def test_calculate_debye_length_parametrized(temp_keV, nd, expected): assert result == pytest.approx(expected, rel=1e-12) -def test_detailed_physics_run_computes_profiles(monkeypatch, physics): +def test_detailed_physics_run_computes_profiles(monkeypatch, physics, process_models): # Minimal plasma profile - plasma = physics.data.plasma_profile + plasma = process_models.plasma_profile plasma.teprofile.profile_x = np.array([0.0, 0.5, 1.0]) plasma.teprofile.profile_y = np.array([1.0, 2.0, 3.0]) # keV plasma.neprofile.profile_x = plasma.teprofile.profile_x @@ -3664,7 +3668,7 @@ def test_detailed_physics_run_computes_profiles(monkeypatch, physics): np.ones(2 * len(plasma.neprofile.profile_y)) * 5.0 ) - dp = DetailedPhysics(plasma) + dp = process_models.physics_detailed # Run should complete without error and populate physics.data.physics dp.run() diff --git a/tests/unit/models/physics/test_plasma_profiles.py b/tests/unit/models/physics/test_plasma_profiles.py index c630b03758..e836abb508 100644 --- a/tests/unit/models/physics/test_plasma_profiles.py +++ b/tests/unit/models/physics/test_plasma_profiles.py @@ -3,8 +3,6 @@ import numpy as np import pytest -from process.models.physics.profiles import NeProfile, TeProfile - @pytest.fixture def plasmaprofile(process_models): @@ -53,8 +51,13 @@ class NeProfileParam(NamedTuple): ], ids=["baseline_2018"], ) -def test_neprofile(neprofileparam: ProfileParam, monkeypatch): - neprofile = NeProfile(10) +def test_neprofile(neprofileparam: ProfileParam, monkeypatch, plasmaprofile): + monkeypatch.setattr( + plasmaprofile.data.physics, + "n_plasma_profile_elements", + 10, + ) + neprofile = plasmaprofile.neprofile neprofile.run() assert neprofile.profile_y == pytest.approx(neprofileparam.expected_neprofile) @@ -65,7 +68,7 @@ def test_ncore(monkeypatch, plasmaprofile): "n_plasma_profile_elements", 10, ) - neprofile = NeProfile() + neprofile = plasmaprofile.neprofile radius_plasma_pedestal_density_norm = 0.94 nped = 5.8300851381352219e19 nsep = 3.4294618459618943e19 @@ -121,13 +124,13 @@ def test_teprofile(teprofileparam: ProfileParam, monkeypatch, plasmaprofile): "n_plasma_profile_elements", 10, ) - teprofile = TeProfile() + teprofile = plasmaprofile.teprofile teprofile.run() assert teprofile.profile_y == pytest.approx(teprofileparam.expected_teprofile) -def test_tcore(): - teprofile = TeProfile() +def test_tcore(plasmaprofile): + teprofile = plasmaprofile.teprofile radius_plasma_pedestal_temp_norm = 0.94 tped = 3.7775374842470044 tsep = 0.1 diff --git a/tests/unit/models/test_costs_1990.py b/tests/unit/models/test_costs_1990.py index d8c4866223..1975b01849 100644 --- a/tests/unit/models/test_costs_1990.py +++ b/tests/unit/models/test_costs_1990.py @@ -600,7 +600,7 @@ def acc26_params(): acc26_param(), acc26_param( ireactor=1, - p_fusion_total_mw=costs.data.physics.p_fusion_total_mw, + p_fusion_total_mw=0.0, p_hcd_electric_total_mw=0.0, tfcmw=data_structure.tfcoil_variables.tfcmw, p_plant_primary_heat_mw=3000.0, From 537144db6e4150f8a3e4aedaf3db0b14a19442a9 Mon Sep 17 00:00:00 2001 From: Timothy Nunn Date: Fri, 22 May 2026 09:07:36 +0100 Subject: [PATCH 04/13] Remove FusionReactionRate as a model --- process/data_structure/physics_variables.py | 8 +++++++- process/main.py | 7 ------- process/models/physics/fusion_reactions.py | 14 +++++--------- process/models/physics/physics.py | 9 ++++----- process/models/physics/plasma_current.py | 4 ++-- process/models/physics/plasma_fields.py | 2 +- process/models/physics/plasma_profiles.py | 2 -- process/models/stellarator/stellarator.py | 9 ++++----- 8 files changed, 23 insertions(+), 32 deletions(-) diff --git a/process/data_structure/physics_variables.py b/process/data_structure/physics_variables.py index 8817f489dd..6ded110158 100644 --- a/process/data_structure/physics_variables.py +++ b/process/data_structure/physics_variables.py @@ -24,7 +24,7 @@ class DivertorNumberModels(IntEnum): """number of energy confinement time scaling laws""" -@dataclass +@dataclass(slots=True) class PhysicsData: iscz: int = 0 @@ -1273,5 +1273,11 @@ class PhysicsData: res_plasma_fuel_spitzer_vol_avg: float = 0.0 """Volume averaged plasma Spitzer resistivity due to fuel ions (ohm m)""" + dt_power_density_plasma: float = 0.0 + sigmav_dt_average: float = 0.0 + dhe3_power_density: float = 0.0 + dd_power_density: float = 0.0 + fusrat: float = 0.0 + CREATE_DICTS_FROM_DATACLASS = PhysicsData diff --git a/process/main.py b/process/main.py index 61cae0c347..6fdfef1d8a 100644 --- a/process/main.py +++ b/process/main.py @@ -85,7 +85,6 @@ ) from process.models.physics.density_limit import PlasmaDensityLimit from process.models.physics.exhaust import PlasmaExhaust -from process.models.physics.fusion_reactions import FusionReactionRate from process.models.physics.impurity_radiation import ( initialise_imprad, ) @@ -650,9 +649,6 @@ def __init__(self, data: DataStructure): self.plasma_current = PlasmaCurrent() self.plasma_fields = PlasmaFields() self.plasma_dia_current = PlasmaDiamagneticCurrent() - self.fusion_reaction_rate = FusionReactionRate( - plasma_profile=self.plasma_profile - ) self.physics = Physics( plasma_profile=self.plasma_profile, current_drive=self.current_drive, @@ -667,7 +663,6 @@ def __init__(self, data: DataStructure): plasma_fields=self.plasma_fields, plasma_dia_current=self.plasma_dia_current, plasma_geometry=self.plasma_geom, - fusion_reactions=self.fusion_reaction_rate, ) self.physics_detailed = DetailedPhysics( plasma_profile=self.plasma_profile, @@ -686,7 +681,6 @@ def __init__(self, data: DataStructure): neoclassics=self.neoclassics, plasma_beta=self.plasma_beta, plasma_bootstrap=self.plasma_bootstrap_current, - fusion_reactions=self.fusion_reaction_rate, ) self.dcll = DCLL(fw=self.fw) @@ -761,7 +755,6 @@ def models(self) -> tuple[Model, ...]: self.plasma_current, self.neoclassics, self.plasma_inductance, - self.fusion_reaction_rate, self.ne_profile, self.te_profile, self.plasma_fields, diff --git a/process/models/physics/fusion_reactions.py b/process/models/physics/fusion_reactions.py index d8c9d3d98c..c81e069e50 100644 --- a/process/models/physics/fusion_reactions.py +++ b/process/models/physics/fusion_reactions.py @@ -7,7 +7,7 @@ from scipy import integrate from process.core import constants -from process.core.model import Model +from process.core.model import DataStructure from process.data_structure.physics_variables import PhysicsData from process.models.physics.plasma_profiles import PlasmaProfile @@ -63,7 +63,7 @@ } -class FusionReactionRate(Model): +class FusionReactionRate: """Calculate the fusion reaction rate for each reaction case (DT, DHE3, DD1, DD2). This class provides methods to numerically integrate over the plasma cross-section @@ -102,7 +102,7 @@ class FusionReactionRate(Model): Apr. 1992, doi: https://doi.org/10.1088/0029-5515/32/4/i07. """ - def __init__(self, plasma_profile: PlasmaProfile): + def __init__(self, plasma_profile: PlasmaProfile, data: DataStructure): """ Initialize the FusionReactionRate class with the given plasma profile. @@ -114,6 +114,8 @@ def __init__(self, plasma_profile: PlasmaProfile): """ self.plasma_profile = plasma_profile + self.data = data + self.sigmav_dt_average = 0.0 self.dhe3_power_density = 0.0 self.dd_power_density = 0.0 @@ -126,12 +128,6 @@ def __init__(self, plasma_profile: PlasmaProfile): self.proton_rate_density = 0.0 self.f_dd_branching_trit = 0.0 - def run(self): - """This model isn't run""" - - def output(self): - """This model has no output""" - def deuterium_branching(self, ion_temperature: float) -> float: """Calculate the relative rate of tritium producing D-D reactions to 3He ones based on the volume averaged ion temperature diff --git a/process/models/physics/physics.py b/process/models/physics/physics.py index c5538fb220..573ab73acf 100644 --- a/process/models/physics/physics.py +++ b/process/models/physics/physics.py @@ -189,7 +189,6 @@ def __init__( plasma_fields: PlasmaFields, plasma_dia_current: PlasmaDiamagneticCurrent, plasma_geometry: PlasmaGeom, - fusion_reactions: reactions.FusionReactionRate, ): self.outfile = constants.NOUT self.mfile = constants.MFILE @@ -206,7 +205,6 @@ def __init__( self.fields = plasma_fields self.dia_current = plasma_dia_current self.geometry = plasma_geometry - self.fusion_reactions = fusion_reactions def output(self) -> None: """Output plasma physics information.""" @@ -568,11 +566,12 @@ def run(self): # Calculate fusion power + components - self.fusion_reactions.deuterium_branching( + fusion_reactions = reactions.FusionReactionRate(self.plasma_profile, self.data) + fusion_reactions.deuterium_branching( self.data.physics.temp_plasma_ion_vol_avg_kev ) - self.fusion_reactions.calculate_fusion_rates() - self.fusion_reactions.set_physics_variables() + fusion_reactions.calculate_fusion_rates() + fusion_reactions.set_physics_variables() # This neglects the power from the beam self.data.physics.p_plasma_dt_mw = ( diff --git a/process/models/physics/plasma_current.py b/process/models/physics/plasma_current.py index 8f3ae395be..7e41214605 100644 --- a/process/models/physics/plasma_current.py +++ b/process/models/physics/plasma_current.py @@ -743,7 +743,7 @@ def calculate_poloidal_field( ff1, ff2, _, _ = self.plascar_bpol(aspect, eps, kappa, delta) # Transform q95 to qbar - qbar = q95 * 1.3e0 * (1.0e0 - self.data.physics.eps) ** 0.6e0 + qbar = q95 * 1.3e0 * (1.0e0 - eps) ** 0.6e0 return b_plasma_toroidal_on_axis * (ff1 + ff2) / (2.0 * np.pi * qbar) @@ -820,7 +820,7 @@ def calculate_plasma_current_peng( 1729-1738. https://doi.org/10.13182/FST92-A29971 """ # Transform q95 to qbar - qbar = q95 * 1.3e0 * (1.0e0 - self.data.physics.eps) ** 0.6e0 + qbar = q95 * 1.3e0 * (1.0e0 - eps) ** 0.6e0 ff1, ff2, d1, d2 = self.plascar_bpol(aspect, eps, kappa, delta) diff --git a/process/models/physics/plasma_fields.py b/process/models/physics/plasma_fields.py index fe1a3e78c8..d7cb2e3f00 100644 --- a/process/models/physics/plasma_fields.py +++ b/process/models/physics/plasma_fields.py @@ -88,7 +88,7 @@ def calculate_surface_averaged_poloidal_field( ff1, ff2, _, _ = self.current.plascar_bpol(aspect, eps, kappa, delta) # Transform q95 to qbar - qbar = q95 * 1.3e0 * (1.0e0 - self.data.physics.eps) ** 0.6e0 + qbar = q95 * 1.3e0 * (1.0e0 - eps) ** 0.6e0 return b_plasma_toroidal_on_axis * (ff1 + ff2) / (2.0 * np.pi * qbar) diff --git a/process/models/physics/plasma_profiles.py b/process/models/physics/plasma_profiles.py index f2c46857c4..79e2027596 100644 --- a/process/models/physics/plasma_profiles.py +++ b/process/models/physics/plasma_profiles.py @@ -204,8 +204,6 @@ def pedestal_parameterisation(self): integ1 = sp.integrate.simpson(arg1, x=rho, dx=drho) integ2 = sp.integrate.simpson(arg2, x=rho, dx=drho) - self.data.physics.integ1 = integ1 - self.data.physics.integ2 = integ2 # Density-weighted temperatures self.data.physics.temp_plasma_electron_density_weighted_kev = integ1 / integ2 self.data.physics.temp_plasma_ion_density_weighted_kev = ( diff --git a/process/models/stellarator/stellarator.py b/process/models/stellarator/stellarator.py index 12e3cc4b61..0b5fd80dc5 100644 --- a/process/models/stellarator/stellarator.py +++ b/process/models/stellarator/stellarator.py @@ -91,7 +91,6 @@ def __init__( neoclassics: Neoclassics, plasma_beta, plasma_bootstrap, - fusion_reactions: reactions.FusionReactionRate, ) -> None: self.outfile: int = constants.NOUT self.first_call_stfwbs = True @@ -108,7 +107,6 @@ def __init__( self.neoclassics = neoclassics self.beta = plasma_beta self.bootstrap = plasma_bootstrap - self.fusion_reactions = fusion_reactions def output(self): self.run(output=True) @@ -2008,11 +2006,12 @@ def st_phys(self, output): # Calculate fusion power - self.fusion_reactions.deuterium_branching( + fusion_reactions = reactions.FusionReactionRate(self.plasma_profile, self.data) + fusion_reactions.deuterium_branching( self.data.physics.temp_plasma_ion_vol_avg_kev ) - self.fusion_reactions.calculate_fusion_rates() - self.fusion_reactions.set_physics_variables() + fusion_reactions.calculate_fusion_rates() + fusion_reactions.set_physics_variables() # D-T power density is named differently to differentiate it from the beam given component self.data.physics.p_plasma_dt_mw = ( From 4b4d8676b57a76d26ecf1c4ebff45d9997cc1ed0 Mon Sep 17 00:00:00 2001 From: Clair Mould <86794332+clmould@users.noreply.github.com> Date: Fri, 22 May 2026 10:16:20 +0100 Subject: [PATCH 05/13] missed errors --- process/main.py | 8 ++++++-- process/models/build.py | 4 ++-- process/models/physics/current_drive.py | 16 ++++++++++++++-- process/models/stellarator/denisty_limits.py | 2 ++ process/models/stellarator/stellarator.py | 1 + 5 files changed, 25 insertions(+), 6 deletions(-) diff --git a/process/main.py b/process/main.py index 6fdfef1d8a..3420c01e12 100644 --- a/process/main.py +++ b/process/main.py @@ -627,11 +627,13 @@ def __init__(self, data: DataStructure): self.blanket_library = BlanketLibrary(fw=self.fw) self.ccfe_hcpb = CCFE_HCPB(fw=self.fw) self.neutral_beam = NeutralBeam(plasma_profile=self.plasma_profile) + self.electron_cyclotron = ElectronCyclotron(plasma_profile=self.plasma_profile) + self.lower_hybrid = LowerHybrid(plasma_profile=self.plasma_profile) self.current_drive = CurrentDrive( plasma_profile=self.plasma_profile, - electron_cyclotron=ElectronCyclotron(plasma_profile=self.plasma_profile), + electron_cyclotron=self.electron_cyclotron, ion_cyclotron=IonCyclotron(plasma_profile=self.plasma_profile), - lower_hybrid=LowerHybrid(plasma_profile=self.plasma_profile), + lower_hybrid=self.lower_hybrid, neutral_beam=self.neutral_beam, electron_bernstein=ElectronBernstein(plasma_profile=self.plasma_profile), ) @@ -761,6 +763,8 @@ def models(self) -> tuple[Model, ...]: self.sauter_bootstrap_current, self.plasma_transition, self.physics_detailed, + self.electron_cyclotron, + self.lower_hybrid, ) def setup_data_structure(self): diff --git a/process/models/build.py b/process/models/build.py index 46580ffff4..9ccddc2937 100644 --- a/process/models/build.py +++ b/process/models/build.py @@ -851,7 +851,7 @@ def divgeom(self, output: bool): if self.data.physics.itart == 1: return 1.75e0 * self.data.physics.rminor # Conventional tokamak divertor model - # options for seperate upper and lower self.data.physics.triangularity + # options for separate upper and lower self.data.physics.triangularity kap = self.data.physics.kappa triu = self.data.physics.triang @@ -1182,7 +1182,7 @@ def divgeom(self, output: bool): ) po.ovarrf( self.outfile, - "Plasma self.data.physics.triangularity", + "Plasma data.physics.triangularity", "(tril)", tril, "OP ", diff --git a/process/models/physics/current_drive.py b/process/models/physics/current_drive.py index ab76724940..af0b49527d 100644 --- a/process/models/physics/current_drive.py +++ b/process/models/physics/current_drive.py @@ -783,13 +783,19 @@ def xlmbdabi(mb, mth, eb, t, nelec): return 23.7 + np.log(x2 * np.sqrt(x1)) -class ElectronCyclotron: +class ElectronCyclotron(Model): """Class for calculating electron cyclotron current drive parameters""" def __init__(self, plasma_profile: PlasmaProfile): self.outfile = constants.NOUT self.plasma_profile = plasma_profile + def run(self): + """This model isn't run""" + + def output(self): + """This has no output""" + def culecd(self): """Routine to calculate Electron Cyclotron current drive efficiency @@ -1300,13 +1306,19 @@ def electron_bernstein_freethy( return eta_cd * density_factor -class LowerHybrid: +class LowerHybrid(Model): """Class to calculate Lower Hybrid current drive efficiency.""" def __init__(self, plasma_profile: PlasmaProfile): self.outfile = constants.NOUT self.plasma_profile = plasma_profile + def run(self): + """This isn't run""" + + def output(self): + """This has no output""" + def cullhy(self): """Calculate Culham Lower Hybrid current drive efficiency. diff --git a/process/models/stellarator/denisty_limits.py b/process/models/stellarator/denisty_limits.py index 4e6363393f..9435532883 100644 --- a/process/models/stellarator/denisty_limits.py +++ b/process/models/stellarator/denisty_limits.py @@ -117,6 +117,8 @@ def st_d_limit_ecrh(gyro_frequency_max, bt_input, i_plasma_pedestal): Maximal available Gyrotron frequency (1/s) NOT (rad/s) bt_input : Maximal magnetic field on axis (T) + i_plasma_pedestal: int + switch for pedestal profiles Returns ------- diff --git a/process/models/stellarator/stellarator.py b/process/models/stellarator/stellarator.py index 0b5fd80dc5..c20162d24e 100644 --- a/process/models/stellarator/stellarator.py +++ b/process/models/stellarator/stellarator.py @@ -182,6 +182,7 @@ def run(self, output: bool = False): self.data.stellarator.powerht_constraint, self.data.stellarator.powerscaling_constraint, ) = power_at_ignition_point( + self, self.data.stellarator.max_gyrotron_frequency, self.data.stellarator.te0_ecrh_achievable, self.data, From 79525538a4af70c9f3ef2a92b9cee72631f8ae70 Mon Sep 17 00:00:00 2001 From: Clair Mould <86794332+clmould@users.noreply.github.com> Date: Fri, 22 May 2026 11:57:10 +0100 Subject: [PATCH 06/13] fixing test failures --- examples/single_model_evaluation.ex.py | 20 +++++++------------ process/models/physics/plasma_current.py | 4 ++-- process/models/physics/plasma_fields.py | 2 +- .../models/physics/test_fusion_reactions.py | 18 +---------------- 4 files changed, 11 insertions(+), 33 deletions(-) diff --git a/examples/single_model_evaluation.ex.py b/examples/single_model_evaluation.ex.py index 7497cd7b88..9e08629c2b 100644 --- a/examples/single_model_evaluation.ex.py +++ b/examples/single_model_evaluation.ex.py @@ -22,7 +22,7 @@ import matplotlib.pyplot as plt import numpy as np -from process import data_structure +from process.data_structure.physics_variables import PhysicsData from process.main import SingleRun # %% [markdown] @@ -30,9 +30,7 @@ # First, inspect a variable to check its uninitialised value: # %% -print( - f"p_plasma_separatrix_mw = {data_structure.physics_variables.p_plasma_separatrix_mw}" -) +print(f"p_plasma_separatrix_mw = {PhysicsData.p_plasma_separatrix_mw}") # %% [markdown] # In order to initialise all variables in Process with their values at a given point (design parameter vector), run an evaluation input file (one with no optimisation) to initialise values in all models. The "large tokamak" regression test solution is used here. @@ -53,9 +51,9 @@ def print_values(): print( f"W frac = {single_run.data.impurity_radiation.f_nd_impurity_electron_array[13]:.3e}" ) - print(f"p_plasma_rad_mw = {data_structure.physics_variables.p_plasma_rad_mw:.3e}") + print(f"p_plasma_rad_mw = {single_run.data.physics.p_plasma_rad_mw:.3e}") print( - f"p_plasma_separatrix_mw = {data_structure.physics_variables.p_plasma_separatrix_mw:.3e}" + f"p_plasma_separatrix_mw = {single_run.data.physics.p_plasma_separatrix_mw:.3e}" ) @@ -99,13 +97,9 @@ def run_impurities(w_imp_fracs): ).normalised_residual # Need to copy values - p_plasma_rad_mw[i] = data_structure.physics_variables.p_plasma_rad_mw.item() - p_plasma_separatrix_mw[i] = ( - data_structure.physics_variables.p_plasma_separatrix_mw.item() - ) - p_l_h_threshold_mw[i] = ( - data_structure.physics_variables.p_l_h_threshold_mw.item() - ) + p_plasma_rad_mw[i] = single_run.data.physics.p_plasma_rad_mw.item() + p_plasma_separatrix_mw[i] = single_run.data.physics.p_plasma_separatrix_mw.item() + p_l_h_threshold_mw[i] = single_run.data.physics.p_l_h_threshold_mw.item() # Need to flip sign of constraint so negative means violated con15[i] = -con15_value diff --git a/process/models/physics/plasma_current.py b/process/models/physics/plasma_current.py index 7e41214605..8f3ae395be 100644 --- a/process/models/physics/plasma_current.py +++ b/process/models/physics/plasma_current.py @@ -743,7 +743,7 @@ def calculate_poloidal_field( ff1, ff2, _, _ = self.plascar_bpol(aspect, eps, kappa, delta) # Transform q95 to qbar - qbar = q95 * 1.3e0 * (1.0e0 - eps) ** 0.6e0 + qbar = q95 * 1.3e0 * (1.0e0 - self.data.physics.eps) ** 0.6e0 return b_plasma_toroidal_on_axis * (ff1 + ff2) / (2.0 * np.pi * qbar) @@ -820,7 +820,7 @@ def calculate_plasma_current_peng( 1729-1738. https://doi.org/10.13182/FST92-A29971 """ # Transform q95 to qbar - qbar = q95 * 1.3e0 * (1.0e0 - eps) ** 0.6e0 + qbar = q95 * 1.3e0 * (1.0e0 - self.data.physics.eps) ** 0.6e0 ff1, ff2, d1, d2 = self.plascar_bpol(aspect, eps, kappa, delta) diff --git a/process/models/physics/plasma_fields.py b/process/models/physics/plasma_fields.py index d7cb2e3f00..fe1a3e78c8 100644 --- a/process/models/physics/plasma_fields.py +++ b/process/models/physics/plasma_fields.py @@ -88,7 +88,7 @@ def calculate_surface_averaged_poloidal_field( ff1, ff2, _, _ = self.current.plascar_bpol(aspect, eps, kappa, delta) # Transform q95 to qbar - qbar = q95 * 1.3e0 * (1.0e0 - eps) ** 0.6e0 + qbar = q95 * 1.3e0 * (1.0e0 - self.data.physics.eps) ** 0.6e0 return b_plasma_toroidal_on_axis * (ff1 + ff2) / (2.0 * np.pi * qbar) diff --git a/tests/unit/models/physics/test_fusion_reactions.py b/tests/unit/models/physics/test_fusion_reactions.py index 4bd88f99ee..f96a27cf8d 100644 --- a/tests/unit/models/physics/test_fusion_reactions.py +++ b/tests/unit/models/physics/test_fusion_reactions.py @@ -9,12 +9,6 @@ from process.models.physics import fusion_reactions as reactions -@pytest.fixture -def fusion_reaction_rate(process_models): - """Fixture to get the FusionReactionRate instance from process_models.""" - return process_models.fusion_reaction_rate - - class SetFusionPowersParam(NamedTuple): f_p_alpha_plasma_deposited: Any = None @@ -136,7 +130,7 @@ class SetFusionPowersParam(NamedTuple): ), ], ) -def test_set_fusion_powers(setfusionpowersparam, monkeypatch, fusion_reaction_rate): +def test_set_fusion_powers(setfusionpowersparam): """ Automatically generated Regression Unit Test for set_fusion_powers(). @@ -148,16 +142,6 @@ def test_set_fusion_powers(setfusionpowersparam, monkeypatch, fusion_reaction_ra :param monkeypatch: pytest fixture used to mock module/class variables :type monkeypatch: _pytest.monkeypatch.monkeypatch """ - monkeypatch.setattr( - fusion_reaction_rate.data.physics, - "f_p_alpha_plasma_deposited", - setfusionpowersparam.f_p_alpha_plasma_deposited, - ) - monkeypatch.setattr( - fusion_reaction_rate.data.physics, - "f_plasma_fuel_deuterium", - setfusionpowersparam.f_plasma_fuel_deuterium, - ) ( pden_neutron_total_mw, From 9684801e31f371316095903bd8b33dd409e00a04 Mon Sep 17 00:00:00 2001 From: clmould <86794332+clmould@users.noreply.github.com> Date: Fri, 22 May 2026 15:46:50 +0100 Subject: [PATCH 07/13] Update documentation/source/eng-models/heating_and_current_drive/RF/culham_lower_hybrid.md Co-authored-by: Timothy <75321887+timothy-nunn@users.noreply.github.com> --- .../heating_and_current_drive/RF/culham_lower_hybrid.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/source/eng-models/heating_and_current_drive/RF/culham_lower_hybrid.md b/documentation/source/eng-models/heating_and_current_drive/RF/culham_lower_hybrid.md index cf885906c2..2dcf5ec356 100644 --- a/documentation/source/eng-models/heating_and_current_drive/RF/culham_lower_hybrid.md +++ b/documentation/source/eng-models/heating_and_current_drive/RF/culham_lower_hybrid.md @@ -15,7 +15,7 @@ AEA FUS 172: Physics Assessment for the European Reactor Study[^1] 6. Calculate the parallel refractive index, `nplacc`, which is needed for plasma access. It uses the local density `dlocal` and the local magnetic field `blocal` to calculate a fraction `frac`. `nplacc` is then obtained by adding `frac` to the square root of `1.0 + frac * frac`. 7. Calculate the local inverse aspect ratio, `epslh`, by dividing `rpenet` by `rmajor`. 8. Calculate the LH normalised efficiency, `x`, using the formula `24.0 / (nplacc * sqrt(tlocal))`. -9. Calculate several intermediate terms, `term01`, `term02`, `term03`, and `term04`, using different formulas involving `nplacc`, `data.physics.zeff`, `tlocal`, `epslh`, and `x`. +9. Calculate several intermediate terms, `term01`, `term02`, `term03`, and `term04`, using different formulas involving `nplacc`, `zeff`, `tlocal`, `epslh`, and `x`. 10. Calculate the current drive efficiency, `gamlh`, using the formula `term01 * term02 * (1.0e0 - term03 / term04)`. 11. Return the current drive efficiency normalised by the product of `0.1e0 * dlocal` and `data.physics`. From 3d9ee05ff50e0183237c12854c10b49668b82ec0 Mon Sep 17 00:00:00 2001 From: clmould <86794332+clmould@users.noreply.github.com> Date: Fri, 22 May 2026 15:47:09 +0100 Subject: [PATCH 08/13] Update documentation/source/eng-models/heating_and_current_drive/RF/culham_lower_hybrid.md Co-authored-by: Timothy <75321887+timothy-nunn@users.noreply.github.com> --- .../heating_and_current_drive/RF/culham_lower_hybrid.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/source/eng-models/heating_and_current_drive/RF/culham_lower_hybrid.md b/documentation/source/eng-models/heating_and_current_drive/RF/culham_lower_hybrid.md index 2dcf5ec356..dda49d59e0 100644 --- a/documentation/source/eng-models/heating_and_current_drive/RF/culham_lower_hybrid.md +++ b/documentation/source/eng-models/heating_and_current_drive/RF/culham_lower_hybrid.md @@ -17,7 +17,7 @@ AEA FUS 172: Physics Assessment for the European Reactor Study[^1] 8. Calculate the LH normalised efficiency, `x`, using the formula `24.0 / (nplacc * sqrt(tlocal))`. 9. Calculate several intermediate terms, `term01`, `term02`, `term03`, and `term04`, using different formulas involving `nplacc`, `zeff`, `tlocal`, `epslh`, and `x`. 10. Calculate the current drive efficiency, `gamlh`, using the formula `term01 * term02 * (1.0e0 - term03 / term04)`. -11. Return the current drive efficiency normalised by the product of `0.1e0 * dlocal` and `data.physics`. +11. Return the current drive efficiency normalised by the product of `0.1e0 * dlocal` and `rmajor`. [^1]: T. C. Hender, M. K. Bevir, M. Cox, R. J. Hastie, P. J. Knight, C. N. Lashmore-Davies, B. Lloyd, G. P. Maddison, A. W. Morris, M. R. O'Brien, M.F. Turner abd H. R. Wilson, *"Physics Assessment for the European Reactor Study"*, AEA Fusion Report AEA FUS 172 (1992) From 5113fea5946cccbb750e15b7ce2e838acb7a24da Mon Sep 17 00:00:00 2001 From: clmould <86794332+clmould@users.noreply.github.com> Date: Fri, 22 May 2026 15:47:26 +0100 Subject: [PATCH 09/13] Update documentation/source/physics-models/fusion_reactions/plasma_reactions.md Co-authored-by: Timothy <75321887+timothy-nunn@users.noreply.github.com> --- .../source/physics-models/fusion_reactions/plasma_reactions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/source/physics-models/fusion_reactions/plasma_reactions.md b/documentation/source/physics-models/fusion_reactions/plasma_reactions.md index f2ebb04db9..f192f120dc 100644 --- a/documentation/source/physics-models/fusion_reactions/plasma_reactions.md +++ b/documentation/source/physics-models/fusion_reactions/plasma_reactions.md @@ -177,7 +177,7 @@ It updates the instance attributes for the cumulative power densities and reacti ### Set global physics variables | `set_physics_variables()` -This method sets the required physics variables in the `physics_variables` and `physics` module. It updates the global physics variables and module variables with the current instance's fusion power densities and reaction rates. +This method sets the required physics variables on the `physics` data structure with the current instance's fusion power densities and reaction rates. #### Updates: - `physics_variables.pden_plasma_alpha_mw`: Updated with `self.alpha_power_density` From 4bfce8882741476422fda2359a2b5f46bac5371e Mon Sep 17 00:00:00 2001 From: Clair Mould <86794332+clmould@users.noreply.github.com> Date: Fri, 22 May 2026 16:04:06 +0100 Subject: [PATCH 10/13] pr comment fix for stellarator --- process/models/stellarator/denisty_limits.py | 37 +++++++++----------- process/models/stellarator/stellarator.py | 1 - 2 files changed, 17 insertions(+), 21 deletions(-) diff --git a/process/models/stellarator/denisty_limits.py b/process/models/stellarator/denisty_limits.py index 9435532883..4f38318788 100644 --- a/process/models/stellarator/denisty_limits.py +++ b/process/models/stellarator/denisty_limits.py @@ -146,7 +146,7 @@ def st_d_limit_ecrh(gyro_frequency_max, bt_input, i_plasma_pedestal): return dlimit_ecrh, bt_max -def power_at_ignition_point(stellarator, gyro_frequency_max, te0_available, data): +def power_at_ignition_point(stellarator, gyro_frequency_max, te0_available): """Routine to calculate if the plasma is ignitable with the current values for the B field. Assumes current ECRH achievable peak temperature (which is inaccurate as the cordey pass should be calculated) @@ -163,8 +163,6 @@ def power_at_ignition_point(stellarator, gyro_frequency_max, te0_available, data te0_available : Reachable peak electron temperature, reached by ECRH (KEV) - data: DataStructure - data structure object Returns ------- @@ -174,27 +172,27 @@ def power_at_ignition_point(stellarator, gyro_frequency_max, te0_available, data Heating Power loss at ignition point (MW) """ - te_old = copy(data.physics.temp_plasma_electron_vol_avg_kev) + te_old = copy(stellarator.data.physics.temp_plasma_electron_vol_avg_kev) # Volume averaged data.physics.te from te0_achievable - data.physics.temp_plasma_electron_vol_avg_kev = te0_available / ( - 1.0e0 + data.physics.alphat + stellarator.data.physics.temp_plasma_electron_vol_avg_kev = te0_available / ( + 1.0e0 + stellarator.data.physics.alphat ) ne0_max, bt_ecrh_max = st_d_limit_ecrh( gyro_frequency_max, - data.physics.b_plasma_toroidal_on_axis, - data.physics.i_plasma_pedestal, + stellarator.data.physics.b_plasma_toroidal_on_axis, + stellarator.data.physics.i_plasma_pedestal, ) # Now go to point where ECRH is still available # In density.. - dene_old = copy(data.physics.nd_plasma_electrons_vol_avg) - data.physics.nd_plasma_electrons_vol_avg = min( - dene_old, ne0_max / (1.0e0 + data.physics.alphan) + dene_old = copy(stellarator.data.physics.nd_plasma_electrons_vol_avg) + stellarator.data.physics.nd_plasma_electrons_vol_avg = min( + dene_old, ne0_max / (1.0e0 + stellarator.data.physics.alphan) ) # And B-field.. - bt_old = copy(data.physics.b_plasma_toroidal_on_axis) - data.physics.b_plasma_toroidal_on_axis = min( - bt_ecrh_max, data.physics.b_plasma_toroidal_on_axis + bt_old = copy(stellarator.data.physics.b_plasma_toroidal_on_axis) + stellarator.data.physics.b_plasma_toroidal_on_axis = min( + bt_ecrh_max, stellarator.data.physics.b_plasma_toroidal_on_axis ) stellarator.st_phys(False) @@ -203,15 +201,15 @@ def power_at_ignition_point(stellarator, gyro_frequency_max, te0_available, data ) # The second call seems to be necessary for all values to "converge" (and is sufficient) powerht_out = max( - copy(data.physics.p_plasma_loss_mw), 0.00001e0 + copy(stellarator.data.physics.p_plasma_loss_mw), 0.00001e0 ) # the radiation module sometimes returns negative heating power - pscalingmw_out = copy(data.physics.pscalingmw) + pscalingmw_out = copy(stellarator.data.physics.pscalingmw) # Reverse it and do it again because anything more efficiently isn't suitable with the current implementation # This is bad practice but seems to be necessary as of now: - data.physics.temp_plasma_electron_vol_avg_kev = te_old - data.physics.nd_plasma_electrons_vol_avg = dene_old - data.physics.b_plasma_toroidal_on_axis = bt_old + stellarator.data.physics.temp_plasma_electron_vol_avg_kev = te_old + stellarator.data.physics.nd_plasma_electrons_vol_avg = dene_old + stellarator.data.physics.b_plasma_toroidal_on_axis = bt_old # The second call seems to be necessary for all values to "converge" (and is sufficient) stellarator.st_phys(False) @@ -268,7 +266,6 @@ def output(stellarator, bt_ecrh, ne0_max_ECRH, data): stellarator, data.stellarator.max_gyrotron_frequency, data.stellarator.te0_ecrh_achievable, - data, ) po.ovarre( stellarator.outfile, diff --git a/process/models/stellarator/stellarator.py b/process/models/stellarator/stellarator.py index c20162d24e..e9d65132f9 100644 --- a/process/models/stellarator/stellarator.py +++ b/process/models/stellarator/stellarator.py @@ -185,7 +185,6 @@ def run(self, output: bool = False): self, self.data.stellarator.max_gyrotron_frequency, self.data.stellarator.te0_ecrh_achievable, - self.data, ) self.data.stellarator.first_call = False From a7404bcc0f5763c1a0ae5f05ddd92470803ac69e Mon Sep 17 00:00:00 2001 From: Clair Mould <86794332+clmould@users.noreply.github.com> Date: Fri, 22 May 2026 16:33:52 +0100 Subject: [PATCH 11/13] tidy up fusion reaction test --- .../models/physics/test_fusion_reactions.py | 42 ------------------- 1 file changed, 42 deletions(-) diff --git a/tests/unit/models/physics/test_fusion_reactions.py b/tests/unit/models/physics/test_fusion_reactions.py index f96a27cf8d..ff7652e13d 100644 --- a/tests/unit/models/physics/test_fusion_reactions.py +++ b/tests/unit/models/physics/test_fusion_reactions.py @@ -12,20 +12,6 @@ class SetFusionPowersParam(NamedTuple): f_p_alpha_plasma_deposited: Any = None - f_plasma_fuel_deuterium: Any = None - - i_beta_fast_alpha: Any = None - - b_plasma_poloidal_average: Any = None - - b_plasma_toroidal_on_axis: Any = None - - nd_plasma_electrons_vol_avg: Any = None - - nd_plasma_fuel_ions_vol_avg: Any = None - - nd_plasma_ions_total_vol_avg: Any = None - f_alpha_electron: Any = None f_alpha_ion: Any = None @@ -34,10 +20,6 @@ class SetFusionPowersParam(NamedTuple): pden_non_alpha_charged_mw: Any = None - temp_plasma_electron_density_weighted_kev: Any = None - - temp_plasma_ion_density_weighted_kev: Any = None - vol_plasma: Any = None pden_plasma_alpha_mw: Any = None @@ -54,8 +36,6 @@ class SetFusionPowersParam(NamedTuple): expected_non_alpha_charged_power: Any = None - expected_beta_fast_alpha: Any = None - expected_alpha_power_electron_density: Any = None expected_alpha_power_ion_density: Any = None @@ -70,7 +50,6 @@ class SetFusionPowersParam(NamedTuple): [ SetFusionPowersParam( f_p_alpha_plasma_deposited=0.95, - f_plasma_fuel_deuterium=0.5, f_alpha_electron=0.68, f_alpha_ion=0.32, p_beam_alpha_mw=0, @@ -90,7 +69,6 @@ class SetFusionPowersParam(NamedTuple): ), SetFusionPowersParam( f_p_alpha_plasma_deposited=0.95, - f_plasma_fuel_deuterium=0.5, f_alpha_electron=0.68, f_alpha_ion=0.32, p_beam_alpha_mw=100.5, @@ -108,26 +86,6 @@ class SetFusionPowersParam(NamedTuple): expected_charged_particle_power=497.580075, expected_fusion_power=2483.04427258794345, ), - SetFusionPowersParam( - f_p_alpha_plasma_deposited=0.95, - f_plasma_fuel_deuterium=2.5, - f_alpha_electron=0.68, - f_alpha_ion=0.32, - p_beam_alpha_mw=100.5, - pden_non_alpha_charged_mw=0.00066, - vol_plasma=2426.25, - pden_plasma_alpha_mw=0.163, - pden_plasma_neutron_mw=0.654, - expected_alpha_power_density=0.20442195, - expected_neutron_power_density=0.8183263050336705, - expected_alpha_power_total=495.97875, - expected_neutron_power_total=1985.464197587943, - expected_non_alpha_charged_power=1.601325, - expected_alpha_power_ion_density=0.062144272, - expected_alpha_power_electron_density=0.132056578, - expected_charged_particle_power=497.580075, - expected_fusion_power=2483.0442725879434, - ), ], ) def test_set_fusion_powers(setfusionpowersparam): From 4a6d597adf4945760867d4b722a2dd7cbe59b9b3 Mon Sep 17 00:00:00 2001 From: Clair Mould <86794332+clmould@users.noreply.github.com> Date: Fri, 22 May 2026 16:34:36 +0100 Subject: [PATCH 12/13] fix bullet point ordering mistake --- .../heating_and_current_drive/RF/culham_electron_cyclotron.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/source/eng-models/heating_and_current_drive/RF/culham_electron_cyclotron.md b/documentation/source/eng-models/heating_and_current_drive/RF/culham_electron_cyclotron.md index 9f7eb7c0ae..61332bc1d7 100644 --- a/documentation/source/eng-models/heating_and_current_drive/RF/culham_electron_cyclotron.md +++ b/documentation/source/eng-models/heating_and_current_drive/RF/culham_electron_cyclotron.md @@ -47,7 +47,7 @@ $$ \mathtt{ecgam} = 0.25(\mathtt{ecgam1} + \mathtt{ecgam2} +\mathtt{ecgam3} + \mathtt{ecgam4}) $$ -1. Calculate the current drive efficiency by dividing `ecgam` by `(dlocal * data.physics.rmajor)`. +7. Calculate the current drive efficiency by dividing `ecgam` by `(dlocal * data.physics.rmajor)`. $$ \text{Current drive efficiency [A/W]} = \frac{\mathtt{ecgam}}{\mathtt{dlocal} \times R_0} From 354035e95b685319df5ee92a4e6776203bf58d7f Mon Sep 17 00:00:00 2001 From: Clair Mould <86794332+clmould@users.noreply.github.com> Date: Fri, 22 May 2026 17:19:11 +0100 Subject: [PATCH 13/13] removal of leftover physics_variables --- .../fusion_reactions/plasma_reactions.md | 22 +++++++++---------- .../profiles/plasma_density_profile.md | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/documentation/source/physics-models/fusion_reactions/plasma_reactions.md b/documentation/source/physics-models/fusion_reactions/plasma_reactions.md index f192f120dc..735f044401 100644 --- a/documentation/source/physics-models/fusion_reactions/plasma_reactions.md +++ b/documentation/source/physics-models/fusion_reactions/plasma_reactions.md @@ -180,17 +180,17 @@ It updates the instance attributes for the cumulative power densities and reacti This method sets the required physics variables on the `physics` data structure with the current instance's fusion power densities and reaction rates. #### Updates: -- `physics_variables.pden_plasma_alpha_mw`: Updated with `self.alpha_power_density` -- `physics_variables.pden_non_alpha_charged_mw`: Updated with `self.pden_non_alpha_charged_mw` -- `physics_variables.pden_plasma_neutron_mw`: Updated with `self.neutron_power_density` -- `physics_variables.fusden_plasma`: Updated with `self.fusion_rate_density` -- `physics_variables.fusden_plasma_alpha`: Updated with `self.alpha_rate_density` -- `physics_variables.proton_rate_density`: Updated with `self.proton_rate_density` -- `physics_module.sigmav_dt_average`: Updated with `self.sigmav_dt_average` -- `physics_module.dt_power_density_plasma`: Updated with `self.dt_power_density` -- `physics_module.dhe3_power_density`: Updated with `self.dhe3_power_density` -- `physics_module.dd_power_density`: Updated with `self.dd_power_density` -- `physics_functions.f_dd_branching_trit`: Updated with `self.f_dd_branching_trit` +- `pden_plasma_alpha_mw`: Updated with `self.alpha_power_density` +- `pden_non_alpha_charged_mw`: Updated with `self.pden_non_alpha_charged_mw` +- `pden_plasma_neutron_mw`: Updated with `self.neutron_power_density` +- `fusden_plasma`: Updated with `self.fusion_rate_density` +- `fusden_plasma_alpha`: Updated with `self.alpha_rate_density` +- `proton_rate_density`: Updated with `self.proton_rate_density` +- `sigmav_dt_average`: Updated with `self.sigmav_dt_average` +- `dt_power_density_plasma`: Updated with `self.dt_power_density` +- `dhe3_power_density`: Updated with `self.dhe3_power_density` +- `dd_power_density`: Updated with `self.dd_power_density` +- `f_dd_branching_trit`: Updated with `self.f_dd_branching_trit` ----------------------- diff --git a/documentation/source/physics-models/profiles/plasma_density_profile.md b/documentation/source/physics-models/profiles/plasma_density_profile.md index df5525e059..b65a30674c 100644 --- a/documentation/source/physics-models/profiles/plasma_density_profile.md +++ b/documentation/source/physics-models/profiles/plasma_density_profile.md @@ -8,7 +8,7 @@ The density profile class is organised around a central runner function that is 2. The steps between the normalised points is then done by [`calculate_profile_dx()`](./plasma_profiles_abstract_class.md#calculate-the-profile-steps-in-x--calculate_profile_dx) which divides the max x-dimension by the number of points. -3. The core electron and ion temperatures are claculated via [`set_physics_variables()`]() +3. The core electron and ion temperatures are calculated via [`set_physics_variables()`]() ### Calculate core values | `set_physics_variables()`