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..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}) $$ -7. Calculate the current drive efficiency by dividing `ecgam` by `(dlocal * physics_variables.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} 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..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 @@ -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`, `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 `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) diff --git a/documentation/source/physics-models/fusion_reactions/plasma_reactions.md b/documentation/source/physics-models/fusion_reactions/plasma_reactions.md index cb967370ed..735f044401 100644 --- a/documentation/source/physics-models/fusion_reactions/plasma_reactions.md +++ b/documentation/source/physics-models/fusion_reactions/plasma_reactions.md @@ -177,20 +177,20 @@ 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 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/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/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()` 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/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..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.THLOREUS.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/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..6ded110158 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. @@ -8,6 +7,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 +20,1264 @@ 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)""" - - -beta_fast_alpha: float = None -"""fast alpha beta component""" - - -beta_vol_avg_max: float = None -"""Max allowable volume averaged beta""" - - -beta_vol_avg_min: float = None -"""Minimum allowable volume averaged beta""" - - -beta_beam: float = None -"""neutral beam beta component""" - - -beta_poloidal_vol_avg: float = None -"""poloidal beta""" - - -beta_poloidal_eps: float = None -"""Poloidal beta and inverse aspcet ratio product""" - - -beta_toroidal_vol_avg: float = None -"""Plasma volume averaged toroidal beta""" - -beta_thermal_toroidal_profile: list[float] = None -"""toroidal beta profile""" - - -beta_thermal_vol_avg: float = None -"""Plasma volume averaged thermal beta""" - - -beta_thermal_poloidal_vol_avg: float = None -"""Plasma volume averaged poloidal thermal beta""" - - -beta_thermal_toroidal_vol_avg: float = None -"""Plasma volume averaged toloidal thermal beta""" - - -beta_norm_total: float = None -"""normaised total beta""" - - -beta_norm_thermal: float = None -"""normaised thermal beta""" - - -beta_norm_toroidal: float = None -"""normaised toroidal beta""" - - -beta_norm_poloidal: float = None -"""normaised poloidal beta""" - - -e_plasma_beta_thermal: float = None -"""Plasma thermal energy derived from thermal beta""" - - -betbm0: float = None -"""leading coefficient for NB beta fraction""" - - -b_plasma_surface_poloidal_average: float = None -"""Plasma surface average poloidal field (T)""" - - -b_plasma_toroidal_on_axis: float = None -"""Plasma toroidal field on axis (T) (`iteration variable 2`)""" - -b_plasma_inboard_toroidal: float = None -"""Plasma inboard toroidal field (T)""" - -b_plasma_outboard_toroidal: float = None -"""Plasma outboard toroidal field (T)""" - -b_plasma_toroidal_profile: list[float] = None -"""toroidal field profile in plasma (T)""" - - -b_plasma_total: float = None -"""Sum of plasma total toroidal + poloidal field (T)""" - -e_plasma_magnetic_stored: float = None -"""Plasma stored magnetic energy (J)""" - - -burnup: float = None -"""fractional plasma burnup""" - - -burnup_in: float = None -"""fractional plasma burnup user input""" - - -b_plasma_vertical_required: float = None -"""Vertical field needed for plasma equilibrium (T)""" - - -c_beta: float = None -"""Destabalisation parameter for i_beta_norm_max=4 beta limit""" - - -csawth: float = None -"""coeff. for sawteeth effects on burn V-s requirement""" - - -f_vol_plasma: float = None -"""multiplying factor for the plasma volume (normally=1)""" - - -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_max_wesson: float = None -"""Wesson-like coefficient for beta scaling""" - +@dataclass(slots=True) +class PhysicsData: + iscz: int = 0 -beta_norm_max_menard: float = None -"""Menard-like coefficient for beta scaling""" + err242: int = 0 + err243: int = 0 -beta_norm_max_original_scaling: float = None -"""Original scaling coefficient for beta scaling""" + f_p_plasma_separatrix_rad: float = 0.0 + """Separatrix radiation fraction""" + e_plasma_beta: float = 0.0 + """[J]""" -beta_norm_max_tholerus: float = None -"""Tholerus-like coefficient for beta scaling""" + p_plasma_heating_total_mw: float = 0.0 + """[W]""" + t_energy_confinement_beta: float = 0.0 + """[s]""" -beta_norm_max_stambaugh: float = None -"""Stambaugh-like coefficient for beta scaling""" + ptarmw: float = 0.0 + lambdaio: float = 0.0 -nd_plasma_electrons_max: float = None -"""Plasma electron max density limit (/m3)""" + drsep: float = 0.0 + fio: float = 0.0 -nd_plasma_ions_total_vol_avg: float = None -"""Plasma volume averaged total ion density (/m3)""" + fli: float = 0.0 + flo: float = 0.0 -nd_plasma_electron_line: float = None -"""Plasma line averaged electron density (/m3)""" + fui: float = 0.0 + fuo: float = 0.0 -nd_plasma_protons_vol_avg: float = None -"""Plasma volume averaged proton ash density (/m3)""" + plimw: float = 0.0 + plomw: float = 0.0 -ntau: float = None -"""Fusion double product (s/m3)""" + puimw: float = 0.0 + puomw: float = 0.0 -nTtau: float = None -"""Lawson triple product [keV s / m3]""" + rho_star: float = 0.0 + nu_star: float = 0.0 -nd_plasma_impurities_vol_avg: float = None -"""Plasma volume averaged impurity (Z > 2) ion density (/m3)""" + beta_mcdonald: float = 0.0 + itart_r: float = 0.0 -gradient_length_ne: float = None -"""Max. normalised gradient length in el. density (i_plasma_pedestal==0 only)""" + # Var in subroutine plasma_composition which requires re-initialisation on + # each new run: + first_call: int = 1 + m_beam_amu: float = 0.0 + """beam ion mass (amu)""" -gradient_length_te: float = None -"""Max. normalised gradient length in el. temperature (i_plasma_pedestal==0 only)""" + m_fuel_amu: float = 0.0 + """average mass of fuel portion of ions (amu)""" + m_ions_total_amu: float = 0.0 + """average mass of all ions (amu)""" -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""" - - -f_c_plasma_inductive: float = None -"""fraction of plasma current produced inductively""" - - -f_alpha_electron: float = None -"""fraction of alpha energy to electrons""" - - -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.""" - - -f_alpha_ion: float = None -"""fraction of alpha power to ions""" - - -f_plasma_fuel_deuterium: float = None -"""Plasma deuterium fuel fraction""" - - -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) -""" - - -ffwal: float = None -"""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 = 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_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_plasma_fuel_helium3: float = None -"""Plasma Helium-3 fuel fraction""" - + m_plasma_fuel_ions: float = 0.0 + """Mass of the plasma fuel ions (kg)""" -figmer: float = None -"""physics figure of merit (= plasma_current*aspect**sbar, where `sbar=1`)""" + 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)""" -fkzohm: float = None -"""Zohm elongation scaling adjustment factor (`i_plasma_geometry=2, 3`)""" + 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)""" -f_plasma_fuel_tritium: float = None -"""Plasma tritium fuel fraction""" + alphaj: float = 1.0 + """current profile index""" + alphaj_wesson: float = None + """Wesson-like current profile index""" -fusden_total: float = None -"""fusion reaction rate density, from beams and plasma (reactions/m3/sec)""" + alphan: float = 0.25 + """density profile index""" + alphap: float = 0.0 + """pressure profile index""" -fusrat_total: float = None -"""fusion reaction rate, from beams and plasma (reactions/sec)""" + fusden_alpha_total: float = 0.0 + """Alpha particle production rate per unit volume, from plasma and beams [particles/m3/sec]""" -fusrat_plasma_dt_profile: list[float] = None -"""Profile of D-T fusion reaction rate in plasma, (reactions/sec)""" + fusden_plasma_alpha: float = 0.0 + """Alpha particle production rate per unit volume, just from plasma [particles/m3/sec]""" -fusrat_plasma_dd_triton_profile: list[float] = None -"""Profile of D-D fusion reaction rate (tritium branch) in plasma, (reactions/sec)""" + alphat: float = 0.5 + """temperature profile index""" -fusrat_plasma_dd_helion_profile: list[float] = None -"""Profile of D-D fusion reaction rate (helium branch) in plasma, (reactions/sec)""" + aspect: float = 2.907 + """aspect ratio (`iteration variable 1`)""" -fusrat_plasma_dhe3_profile: list[float] = None -"""Profile of D-3He fusion reaction rate in plasma, (reactions/sec)""" + beamfus0: float = 1.0 + """multiplier for beam-background fusion calculation""" -fusden_plasma: float = None -"""fusion reaction rate, just from plasma (reactions/m3/sec)""" + beta_total_vol_avg: float = 0.042 + """Volume averaged total plasma beta (`iteration variable 5`) (calculated if stellarator)""" + beta_fast_alpha: float = 0.0 + """fast alpha beta component""" -f_c_plasma_non_inductive: float = None -"""fraction of the plasma current produced by non-inductive means (`iteration variable 44`)""" + beta_vol_avg_max: float = 0.0 + """Max allowable volume averaged beta""" + beta_vol_avg_min: float = 0.0 + """Minimum allowable volume averaged beta""" -ejima_coeff: float = None -"""Ejima coefficient for resistive startup V-s formula""" + beta_beam: float = 0.0 + """neutral beam beta component""" + beta_poloidal_vol_avg: float = 0.0 + """poloidal beta""" -f_beta_alpha_beam_thermal: float = None -"""ratio of (fast alpha + neutral beam beta) to thermal beta""" + beta_poloidal_eps: float = 0.0 + """Poloidal beta and inverse aspcet ratio product""" + beta_toroidal_vol_avg: float = 0.0 + """Plasma volume averaged toroidal beta""" -hfac: list[float] = None -"""H factors for an ignited plasma for each energy confinement time scaling law""" + beta_thermal_toroidal_profile: list[float] = field(default_factory=list) + """toroidal beta profile""" + beta_thermal_vol_avg: float = 0.0 + """Plasma volume averaged thermal beta""" -hfact: float = None -"""H factor on energy confinement times, radiation corrected (`iteration variable 10`).""" + beta_thermal_poloidal_vol_avg: float = 0.0 + """Plasma volume averaged poloidal thermal beta""" + beta_thermal_toroidal_vol_avg: float = 0.0 + """Plasma volume averaged toloidal thermal beta""" -hstar: float = None -"""H* non-radiation corrected H factor on energy confinement times""" + beta_norm_total: float = 0.0 + """normaised total beta""" + beta_norm_thermal: float = 0.0 + """normaised thermal beta""" -t_plasma_energy_confinement_max: float = None -"""Maximum allowed energy confinement time (s)""" + beta_norm_toroidal: float = 0.0 + """normaised toroidal beta""" + beta_norm_poloidal: float = 0.0 + """normaised poloidal beta""" -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 -""" + e_plasma_beta_thermal: float = 0.0 + """Plasma thermal energy derived from thermal beta""" + betbm0: float = 1.5 + """leading coefficient for NB beta fraction""" -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 -""" + 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`)""" -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 -""" + b_plasma_inboard_toroidal: float = 0.0 + """Plasma inboard toroidal field (T)""" + b_plasma_outboard_toroidal: float = 0.0 + """Plasma outboard toroidal field (T)""" -i_diamagnetic_current: int = None -"""switch for diamagnetic current scaling -- =0 Do not calculate -- =1 Use original TART scaling -- =2 Use SCENE scaling -""" - + b_plasma_toroidal_profile: list[float] = field(default_factory=list) + """toroidal field profile in plasma (T)""" -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 -""" + b_plasma_total: float = 0.0 + """Sum of plasma total toroidal + poloidal field (T)""" + e_plasma_magnetic_stored: float = 0.0 + """Plasma stored magnetic energy (J)""" -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 -""" + burnup: float = 0.0 + """fractional plasma burnup""" + burnup_in: float = 0.0 + """fractional plasma burnup user input""" -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) 2) ion density (/m3)""" + gradient_length_ne: float = None + """Max. normalised gradient length in el. density (i_plasma_pedestal==0 only)""" -kappa_ipb: float = None -"""Separatrix elongation calculated for IPB scalings""" + 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 + """ -nd_plasma_electron_on_axis: float = None -"""central electron density (/m3)""" + eps: float = 0.34399724802 + """inverse aspect ratio""" + f_c_plasma_auxiliary: float = 0.0 + """fraction of plasma current produced by auxiliary current drive""" -nd_plasma_ions_on_axis: float = None -"""central ion density (/m3)""" + f_c_plasma_inductive: float = 0.0 + """fraction of plasma current produced inductively""" + f_alpha_electron: float = 0.0 + """fraction of alpha energy to electrons""" -m_s_limit: float = None -"""margin to vertical stability""" + 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""" -pres_plasma_thermal_on_axis: float = None -"""Plasma central thermal pressure (no fast ions or beam pressure) (Pa)""" + f_plasma_fuel_deuterium: float = 0.5 + """Plasma deuterium fuel fraction""" -pres_plasma_thermal_total_profile: list[float] = None -"""Profile of total pressure in plasma (Pa)""" + 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) + """ -pres_plasma_electron_profile: list[float] = None -"""Profile of electron pressure in plasma (Pa)""" + ffwal: float = 0.92 + """factor to convert plasma surface area to first wall area in neutron wall + load calculation (`i_pflux_fw_neutron=1`) + """ -pres_plasma_ion_total_profile: list[float] = None -"""Profile of ion pressure in plasma (Pa)""" + 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`) + """ -pres_plasma_fuel_profile: list[float] = None -"""Profile of fuel pressure in plasma (Pa)""" + 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`) + """ -j_plasma_on_axis: float = None -"""Central plasma current density (A/m2)""" + f_plasma_fuel_helium3: float = 0.0 + """Plasma Helium-3 fuel fraction""" -j_plasma_bootstrap_sauter_profile: list[float] = None -"""Profile of bootstrap current density in plasma using Sauter et al scaling (A/m2)""" + figmer: float = 0.0 + """physics figure of merit (= plasma_current*aspect**sbar, where `sbar=1`)""" -n_plasma_profile_elements: int = None -"""Number of elements in plasma profile""" + 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""" + itartpf: int = 0 + """switch for Spherical Tokamak PF models: + - =0 use Peng and Strickler (1986) model + - =1 use conventional aspect ratio model + """ + i_pflux_fw_neutron: int = 1 + """switch for neutron wall load calculation: + - =1 use scaled plasma surface area + - =2 use first wall area directly + """ -pden_plasma_alpha_mw: float = None -"""Alpha power per volume just from plasma [MW/m3]""" + plasma_square: float = 0.0 + """plasma squareness used by Sauter plasma shape""" + kappa: float = 1.792 + """plasma separatrix elongation (calculated if `i_plasma_geometry = 1-5, 7 or 9-10`)""" -pden_alpha_total_mw: float = None -"""Alpha power per volume from plasma and beams [MW/m3]""" + kappa95: float = 1.6 + """plasma elongation at 95% surface (calculated if `i_plasma_geometry = 0-3, 6, or 8-10`)""" + kappa_ipb: float = 0.0 + """Separatrix elongation calculated for IPB scalings""" -f_pden_alpha_electron_mw: float = None -"""Alpha power per volume to electrons [MW/m3]""" + nd_plasma_electron_on_axis: float = 0.0 + """central electron density (/m3)""" + nd_plasma_ions_on_axis: float = 0.0 + """central ion density (/m3)""" -p_fw_alpha_mw: float = None -"""alpha power escaping plasma and reaching first wall (MW)""" + m_s_limit: float = 0.3 + """margin to vertical stability""" + pres_plasma_thermal_on_axis: float = 0.0 + """Plasma central thermal pressure (no fast ions or beam pressure) (Pa)""" -f_pden_alpha_ions_mw: float = None -"""alpha power per volume to ions (MW/m3)""" + pres_plasma_thermal_total_profile: list[float] = field(default_factory=list) + """Profile of total pressure in plasma (Pa)""" + pres_plasma_electron_profile: list[float] = field(default_factory=list) + """Profile of electron pressure in plasma (Pa)""" -p_plasma_alpha_mw: float = None -"""Alpha power from only the plasma (MW)""" + pres_plasma_ion_total_profile: list[float] = field(default_factory=list) + """Profile of ion pressure in plasma (Pa)""" + pres_plasma_fuel_profile: list[float] = field(default_factory=list) + """Profile of fuel pressure in plasma (Pa)""" -p_alpha_total_mw: float = None -"""Total alpha power from plasma and beams (MW)""" + j_plasma_on_axis: float = 0.0 + """Central plasma current density (A/m2)""" + j_plasma_bootstrap_sauter_profile: list[float] = field(default_factory=list) + """Profile of bootstrap current density in plasma using Sauter et al scaling (A/m2)""" -p_beam_alpha_mw: float = None -"""alpha power from hot neutral beam ions (MW)""" + n_plasma_profile_elements: int = 501 + """Number of elements in plasma profile""" + pres_plasma_thermal_vol_avg: float = None + """Volume averaged thermal plasma pressure (no fast ions or beam pressure) (Pa)""" -p_beam_neutron_mw: float = None -"""neutron power from hot neutral beam ions (MW)""" + f_dd_branching_trit: float = 0.0 + """branching ratio for DD -> T""" + pden_plasma_alpha_mw: float = 0.0 + """Alpha power per volume just from plasma [MW/m3]""" -p_beam_dt_mw: float = None -"""D-T fusion power from hot neutral beam ions (MW)""" + pden_alpha_total_mw: float = 0.0 + """Alpha power per volume from plasma and beams [MW/m3]""" + f_pden_alpha_electron_mw: float = 0.0 + """Alpha power per volume to electrons [MW/m3]""" -p_non_alpha_charged_mw: float = None -"""non-alpha charged particle fusion power (MW)""" + p_fw_alpha_mw: float = 0.0 + """alpha power escaping plasma and reaching first wall (MW)""" + f_pden_alpha_ions_mw: float = 0.0 + """alpha power per volume to ions (MW/m3)""" -p_charged_particle_mw: float = None -"""Total charged particle fusion power [MW]""" + p_plasma_alpha_mw: float = 0.0 + """Alpha power from only the plasma (MW)""" + p_alpha_total_mw: float = 0.0 + """Total alpha power from plasma and beams (MW)""" -pden_non_alpha_charged_mw: float = None -"""Non-alpha charged particle fusion power per volume [MW/m3]""" + p_beam_alpha_mw: float = 0.0 + """alpha power from hot neutral beam ions (MW)""" + p_beam_neutron_mw: float = 0.0 + """neutron power from hot neutral beam ions (MW)""" -f_temp_plasma_electron_density_vol_avg: float = None -"""Ratio of density weighted plasma electron tempertaurature to volume averaged (Profile Factor)""" + p_beam_dt_mw: float = 0.0 + """D-T fusion power from hot neutral beam ions (MW)""" + p_non_alpha_charged_mw: float = 0.0 + """non-alpha charged particle fusion power (MW)""" -p_plasma_inner_rad_mw: float = None -"""radiation power from inner zone (MW)""" + p_charged_particle_mw: float = 0.0 + """Total charged particle fusion power [MW]""" + pden_non_alpha_charged_mw: float = 0.0 + """Non-alpha charged particle fusion power per volume [MW/m3]""" -pden_plasma_core_rad_mw: float = None -"""total core radiation 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)""" + p_plasma_inner_rad_mw: float = 0.0 + """radiation power from inner zone (MW)""" -p_dd_total_mw: float = None -"""deuterium-deuterium fusion power (MW)""" + pden_plasma_core_rad_mw: float = 0.0 + """total core radiation power per volume (MW/m3)""" + p_dd_total_mw: float = 0.0 + """deuterium-deuterium fusion power (MW)""" -p_dhe3_total_mw: float = None -"""deuterium-helium3 fusion power (MW)""" + p_dhe3_total_mw: float = 0.0 + """deuterium-helium3 fusion power (MW)""" + p_plasma_separatrix_mw: float = 0.0 + """power to conducted to the divertor region (MW)""" -p_plasma_separatrix_mw: float = None -"""power to conducted to the divertor region (MW)""" + p_plasma_separatrix_rmajor_mw: float = 0.0 + """Power to conducted to the divertor region per major radius (MW/m)""" -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 = 0.0 + """EU DEMO divertor protection parameter (MW/T/m)""" -p_div_bt_q_aspect_rmajor_mw: float = None -"""EU DEMO divertor protection parameter (MW/T/m)""" + p_div_lower_separatrix_mw: float = 0.0 + """Separatrix power conducted to the lower divertor region (calculated if `i_single_null = 0`) (MW)""" + p_div_upper_separatrix_mw: float = 0.0 + """Separatrix power conducted to the upper divertor region (calculated if `i_single_null = 0`) (MW)""" -p_div_lower_separatrix_mw: float = None -"""Separatrix power conducted to the lower divertor region (calculated if `i_single_null = 0`) (MW)""" + p_div_separatrix_max_mw: float = 0.0 + """Separatrix power conducted to the divertor with most load (calculated if `i_single_null = 0`) (MW)""" + p_dt_total_mw: float = 0.0 + """Total deuterium-tritium fusion power, from plasma and beams [MW]""" -p_div_upper_separatrix_mw: float = None -"""Separatrix power conducted to the upper divertor region (calculated if `i_single_null = 0`) (MW)""" + p_plasma_dt_mw: float = 0.0 + """Deuterium-tritium fusion power, just from plasma [MW]""" + p_plasma_outer_rad_mw: float = 0.0 + """radiation power from outer zone (MW)""" -p_div_separatrix_max_mw: float = None -"""Separatrix power conducted to the divertor with most load (calculated if `i_single_null = 0`) (MW)""" + pden_plasma_outer_rad_mw: float = 0.0 + """edge radiation power per volume (MW/m3)""" + vs_plasma_internal: float = 0.0 + """internal plasma V-s""" -p_dt_total_mw: float = None -"""Total deuterium-tritium fusion power, from plasma and beams [MW]""" + pflux_fw_rad_mw: float = 0.0 + """Nominal mean radiation load on inside surface of reactor (MW/m2)""" + pden_ion_electron_equilibration_mw: float = 0.0 + """ion/electron equilibration power per volume (MW/m3)""" -p_plasma_dt_mw: float = None -"""Deuterium-tritium fusion power, just from plasma [MW]""" + plasma_current: float = 0.0 + """plasma current (A)""" + c_plasma_peng_analytic: float = 0.0 + """Peng analytic plasma current (A)""" -p_plasma_outer_rad_mw: float = None -"""radiation power from outer zone (MW)""" + c_plasma_peng_double_null: float = 0.0 + """Peng double null divertor plasma current (A)""" + c_plasma_cyclindrical: float = 0.0 + """Cylindrical plasma current (A)""" -pden_plasma_outer_rad_mw: float = None -"""edge radiation power per volume (MW/m3)""" + c_plasma_ipdg89: float = 0.0 + """ITER IPDG89 plasma current (A)""" + c_plasma_todd_empirical_i: float = 0.0 + """Todd empirical plasma current I (A)""" -vs_plasma_internal: float = None -"""internal plasma V-s""" + c_plasma_todd_empirical_ii: float = 0.0 + """Todd empirical plasma current II (A)""" + c_plasma_connor_hastie: float = 0.0 + """Connor-Hastie plasma current (A)""" -pflux_fw_rad_mw: float = None -"""Nominal mean radiation load on inside surface of reactor (MW/m2)""" + c_plasma_sauter: float = 0.0 + """Sauter plasma current (A)""" + c_plasma_fiesta_st: float = 0.0 + """FIESTA ST plasma current (A)""" -pden_ion_electron_equilibration_mw: float = None -"""ion/electron equilibration power per volume (MW/m3)""" + p_plasma_neutron_mw: float = 0.0 + """Neutron fusion power from just the plasma [MW]""" + p_neutron_total_mw: float = 0.0 + """Total neutron fusion power from plasma and beams [MW]""" -plasma_current: float = None -"""plasma current (A)""" + pden_neutron_total_mw: float = 0.0 + """neutron fusion power per volume from beams and plasma (MW/m3)""" -c_plasma_peng_analytic: float = None -"""Peng analytic plasma current (A)""" + pden_plasma_neutron_mw: float = 0.0 + """neutron fusion power per volume just from plasma (MW/m3)""" -c_plasma_peng_double_null: float = None -"""Peng double null divertor plasma current (A)""" + p_plasma_ohmic_mw: float = 0.0 + """ohmic heating power (MW)""" -c_plasma_cyclindrical: float = None -"""Cylindrical plasma current (A)""" + pden_plasma_ohmic_mw: float = 0.0 + """ohmic heating power per volume (MW/m3)""" -c_plasma_ipdg89: float = None -"""ITER IPDG89 plasma current (A)""" + p_plasma_loss_mw: float = 0.0 + """heating power (= transport loss power) (MW) used in confinement time calculation""" -c_plasma_todd_empirical_i: float = None -"""Todd empirical plasma current I (A)""" + p_fusion_total_mw: float = 0.0 + """fusion power (MW)""" -c_plasma_todd_empirical_ii: float = None -"""Todd empirical plasma current II (A)""" -c_plasma_connor_hastie: float = None -"""Connor-Hastie plasma current (A)""" + len_plasma_poloidal: float = 0.0 + """plasma poloidal perimeter (m)""" -c_plasma_sauter: float = None -"""Sauter plasma current (A)""" + p_plasma_rad_mw: float = 0.0 + """total radiation power from inside LCFS (MW)""" -c_plasma_fiesta_st: float = None -"""FIESTA ST plasma current (A)""" + pden_plasma_rad_mw: float = 0.0 + """total radiation power per volume (MW/m3)""" -p_plasma_neutron_mw: float = None -"""Neutron fusion power from just the plasma [MW]""" + pradsolmw: float = 0.0 + """radiation power from SoL (MW)""" + proton_rate_density: float = 0.0 + """Proton production rate [particles/m3/sec]""" -p_neutron_total_mw: float = None -"""Total neutron fusion power from plasma and beams [MW]""" + psolradmw: float = 0.0 + """SOL radiation power (MW) (`stellarator only`)""" + pden_plasma_sync_mw: float = 0.0 + """synchrotron radiation power per volume (MW/m3)""" -pden_neutron_total_mw: float = None -"""neutron fusion power per volume from beams and plasma (MW/m3)""" + p_plasma_sync_mw: float = 0.0 + """Total synchrotron radiation power from plasma (MW)""" + i_l_h_threshold: int = 19 + """switch for L-H mode power threshold scaling to use (see l_h_threshold_powers for list)""" -pden_plasma_neutron_mw: float = None -"""neutron fusion power per volume just from plasma (MW/m3)""" + p_l_h_threshold_mw: float = 0.0 + """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] = 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_plasma_ohmic_mw: float = None -"""ohmic heating power (MW)""" + p_electron_transport_loss_mw: float = 0.0 + """electron transport power (MW)""" + pden_electron_transport_loss_mw: float = 0.0 + """electron transport power per volume (MW/m3)""" -pden_plasma_ohmic_mw: float = None -"""ohmic heating power per volume (MW/m3)""" + p_ion_transport_loss_mw: float = 0.0 + """ion transport power (MW)""" + pscalingmw: float = 0.0 + """Total transport power from scaling law (MW)""" -p_plasma_loss_mw: float = None -"""heating power (= transport loss power) (MW) used in confinement time calculation""" + pden_ion_transport_loss_mw: float = 0.0 + """ion transport power per volume (MW/m3)""" + q0: float = 1.0 + """Safety factor on axis""" -p_fusion_total_mw: float = None -"""fusion power (MW)""" + 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) + """ + molflow_plasma_fuelling_required: float = 0.0 + """plasma fuelling rate (nucleus-pairs/s)""" -len_plasma_poloidal: float = None -"""plasma poloidal perimeter (m)""" + tauratio: float = 1.0 + """tauratio /1.0/ : ratio of He and pellet particle confinement times""" + q95_min: float = 0.0 + """lower limit for edge safety factor""" -p_plasma_rad_mw: float = None -"""total radiation power from inside LCFS (MW)""" + qstar: float = 0.0 + """cylindrical safety factor""" + rad_fraction_sol: float = 0.8 + """SoL radiation fraction""" -pden_plasma_rad_mw: float = None -"""total radiation power per volume (MW/m3)""" + rad_fraction_total: float = 0.0 + """Radiation fraction total = SoL + LCFS radiation / total power deposited in plasma""" + f_nd_alpha_electron: float = 0.1 + """thermal alpha density/electron density (`iteration variable 109`)""" -pradsolmw: float = None -"""radiation power from SoL (MW)""" + f_nd_protium_electrons: float = 0.0 + """Seeded f_nd_protium_electrons density / electron density.""" + ind_plasma_internal_norm: float = 0.9 + """Plasma normalised internal inductance""" -proton_rate_density: float = None -"""Proton production rate [particles/m3/sec]""" + ind_plasma_internal_norm_iter_3: float = 0.0 + """Plasma normalised internal inductance (ITER type 3)""" + ind_plasma_internal_norm_wesson: float = 0.0 + """Wesson-like plasma normalised internal inductance""" -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_menard: float = 0.0 + """Menard-like plasma normalised internal inductance""" + ind_plasma: float = 0.0 + """plasma inductance (H)""" -f_sync_reflect: float = None -"""synchrotron wall reflectivity factor""" + rmajor: float = 8.14 + """plasma major radius (m) (`iteration variable 3`)""" + rminor: float = 0.0 + """plasma minor radius (m)""" -t_electron_energy_confinement: float = None -"""electron energy confinement time (sec)""" + f_nd_beam_electron: float = 0.005 + """hot beam density / n_e (`iteration variable 7`)""" + f_nd_plasma_carbon_electron: float = 0.0 + """n_carbon / n_e""" -tauee_in: float = None -"""Input electron energy confinement time (sec) (`i_confinement_time=48 only`)""" + rndfuel: float = 0.0 + """fuel burnup rate (reactions/second)""" + f_nd_plasma_iron_argon_electron: float = 0.0 + """n_highZ / n_e""" -t_energy_confinement: float = None -"""global thermal energy confinement time (sec)""" + f_nd_plasma_oxygen_electron: float = 0.0 + """n_oxygen / n_e""" + f_res_plasma_neo: float = 0.0 + """neo-classical correction factor to res_plasma""" -t_ion_energy_confinement: float = None -"""ion energy confinement time (sec)""" + res_plasma: float = 0.0 + """plasma resistance (ohm)""" + t_plasma_res_diffusion: float = 0.0 + """plasma current resistive diffusion time (s)""" -t_alpha_confinement: float = None -"""alpha particle confinement time (sec)""" + a_plasma_surface: float = 0.0 + """plasma surface area""" + a_plasma_surface_outboard: float = 0.0 + """outboard plasma surface area""" -f_alpha_energy_confinement: float = None -"""alpha particle to energy confinement time ratio""" + i_single_null: int = 1 + """switch for single null / double null plasma: + - =0 for double null + - =1 for single null (diverted side down) + """ + f_sync_reflect: float = 0.6 + """synchrotron wall reflectivity factor""" -temp_plasma_electron_vol_avg_kev: float = None -"""volume averaged electron temperature (keV) (`iteration variable 4`)""" + t_electron_energy_confinement: float = 0.0 + """electron energy confinement time (sec)""" + tauee_in: float = 0.0 + """Input electron energy confinement time (sec) (`i_confinement_time=48 only`)""" -temp_plasma_electron_on_axis_kev: float = None -"""central electron temperature (keV)""" + t_energy_confinement: float = 0.0 + """global thermal energy confinement time (sec)""" + t_ion_energy_confinement: float = 0.0 + """ion energy confinement time (sec)""" -temp_plasma_electron_density_weighted_kev: float = None -"""density weighted average electron temperature (keV)""" + t_alpha_confinement: float = 0.0 + """alpha particle confinement time (sec)""" + f_alpha_energy_confinement: float = 0.0 + """alpha particle to energy confinement time ratio""" -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`""" + temp_plasma_electron_vol_avg_kev: float = 12.9 + """volume averaged electron temperature (keV) (`iteration variable 4`)""" + temp_plasma_electron_on_axis_kev: float = 0.0 + """central electron temperature (keV)""" -temp_plasma_ion_on_axis_kev: float = None -"""central ion temperature (keV)""" + temp_plasma_electron_density_weighted_kev: float = 0.0 + """density weighted average electron 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_density_weighted_kev: float = None -"""density weighted average ion temperature (keV)""" + temp_plasma_ion_on_axis_kev: float = 0.0 + """central ion temperature (keV)""" + temp_plasma_ion_density_weighted_kev: float = 0.0 + """density weighted average 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`""" + 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 = 0.36 + """plasma separatrix triangularity (calculated if `i_plasma_geometry = 1, 3-5 or 7`)""" -triang: float = None -"""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`)""" + vol_plasma: float = 0.0 + """plasma volume (m3)""" -triang95: float = None -"""plasma triangularity at 95% surface (calculated if `i_plasma_geometry = 0-2, 6, 8 or 9`)""" + vs_plasma_burn_required: float = 0.0 + """V-s needed during flat-top (heat + burn times) (Wb)""" + vs_plasma_ramp_required: float = 0.0 + """V-s needed during ramp-up (Wb)""" -vol_plasma: float = None -"""plasma volume (m3)""" + v_plasma_loop_burn: float = 0.0 + """Plasma loop voltage during flat-top (V)""" + vs_plasma_ind_ramp: float = 0.0 + """Total plasma inductive flux consumption for plasma current ramp-up (Vs)(Wb)""" -vs_plasma_burn_required: float = None -"""V-s needed during flat-top (heat + burn times) (Wb)""" + vs_plasma_res_ramp: float = 0.0 + """Plasma resistive flux consumption for plasma current ramp-up (Vs)(Wb)""" + vs_plasma_total_required: float = 0.0 + """total V-s needed (Wb)""" -vs_plasma_ramp_required: float = None -"""V-s needed during ramp-up (Wb)""" + pflux_fw_neutron_mw: float = 0.0 + """average neutron wall load (MW/m2)""" + pflux_plasma_surface_neutron_avg_mw: float = 0.0 + """Average neutron flux at plasma surface (MW/m2)""" -v_plasma_loop_burn: float = None -"""Plasma loop voltage during flat-top (V)""" + wtgpd: float = 0.0 + """mass of fuel used per day (g)""" + a_plasma_poloidal: float = 0.0 + """plasma poloidal cross-sectional area [m^2]""" -vs_plasma_ind_ramp: float = None -"""Total plasma inductive flux consumption for plasma current ramp-up (Vs)(Wb)""" + n_charge_plasma_effective_vol_avg: float = 0.0 + """Volume averaged plasma effective charge""" + n_charge_plasma_effective_profile: list[float] = field(default_factory=list) + """Profile of plasma effective charge""" -vs_plasma_res_ramp: float = None -"""Plasma resistive flux consumption for plasma current ramp-up (Vs)(Wb)""" + n_charge_plasma_effective_mass_weighted_vol_avg: float = 0.0 + """Plasma mass-weighted volume averaged plasma effective charge""" + len_plasma_debye_electron_profile: list[float] = field(default_factory=list) + """Profile of electron Debye length in plasma (m)""" -vs_plasma_total_required: float = None -"""total V-s needed (Wb)""" + 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)""" + 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_fw_neutron_mw: float = None -"""average neutron wall load (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)""" -pflux_plasma_surface_neutron_avg_mw: float = None -"""Average neutron flux at plasma surface (MW/m2)""" + 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)""" + len_plasma_debye_electron_vol_avg: float = 0.0 + """Volume averaged electron Debye length in plasma (m)""" -wtgpd: float = None -"""mass of fuel used per day (g)""" + vel_plasma_electron_profile: list[float] = field(default_factory=list) + """Profile of electron thermal velocity in plasma (m/s)""" + vel_plasma_deuteron_vol_avg: float = 0.0 + """Volume averaged deuteron thermal velocity in plasma (m/s)""" -a_plasma_poloidal: float = None -"""plasma poloidal cross-sectional area [m^2]""" + vel_plasma_electron_vol_avg: float = 0.0 + """Volume averaged electron thermal velocity in plasma (m/s)""" + vel_plasma_deuteron_profile: list[float] = field(default_factory=list) + """Profile of deuteron thermal velocity in plasma (m/s)""" -n_charge_plasma_effective_vol_avg: float = None -"""Volume averaged plasma effective charge""" + vel_plasma_triton_profile: list[float] = field(default_factory=list) + """Profile of triton thermal velocity in plasma (m/s)""" -n_charge_plasma_effective_profile: list[float] = None -"""Profile of plasma effective charge""" + vel_plasma_triton_vol_avg: float = 0.0 + """Volume averaged triton thermal velocity in plasma (m/s)""" + vel_plasma_alpha_thermal_profile: list[float] = field(default_factory=list) + """Profile of thermal alpha particle 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_vol_avg: float = 0.0 + """Volume averaged 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_birth: float = 0.0 + """Birth velocity of alpha particles 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)""" + plasma_coulomb_log_electron_electron_profile: list[float] = field( + default_factory=list + ) + """Profile of electron-electron Coulomb logarithm in plasma""" -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_vol_avg: float = 0.0 + """Volume averaged 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_deuteron_profile: list[float] = field( + default_factory=list + ) + """Profile of electron-deuteron 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_vol_avg: float = 0.0 + """Volume averaged 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_triton_profile: list[float] = field(default_factory=list) + """Profile of electron-triton 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_vol_avg: float = 0.0 + """Volume averaged 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_deuteron_triton_profile: list[float] = field(default_factory=list) + """Profile of deuteron-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_vol_avg: float = 0.0 + """Volume averaged 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_electron_alpha_thermal_profile: list[float] = field( + default_factory=list + ) + """Profile of electron-alpha 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_vol_avg: float = 0.0 + """Volume averaged electron-alpha Coulomb logarithm in plasma""" -vel_plasma_triton_vol_avg: float = None -"""Volume averaged triton thermal 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_profile: list[float] = None -"""Profile of 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_thermal_vol_avg: float = None -"""Volume averaged thermal alpha particle velocity in plasma (m/s)""" + freq_plasma_electron_profile: list[float] = field(default_factory=list) + """Electron plasma frequency profile (Hz)""" -vel_plasma_alpha_birth: float = None -"""Birth velocity of alpha particles in plasma (m/s)""" + freq_plasma_electron_vol_avg: float = 0.0 + """Volume averaged electron plasma frequency (Hz)""" -plasma_coulomb_log_electron_electron_profile: list[float] = None -"""Profile of 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_electron_vol_avg: float = None -"""Volume averaged electron-electron 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_profile: list[float] = None -"""Profile of 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_deuteron_vol_avg: float = None -"""Volume averaged electron-deuteron 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_profile: list[float] = None -"""Profile of 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_electron_triton_vol_avg: float = None -"""Volume averaged electron-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_profile: list[float] = None -"""Profile of 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_deuteron_triton_vol_avg: float = None -"""Volume averaged deuteron-triton 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_profile: list[float] = None -"""Profile of electron-alpha Coulomb logarithm in plasma""" + freq_plasma_upper_hybrid_vol_avg: float = 0.0 + """Volume averaged upper hybrid frequency in plasma (Hz)""" -plasma_coulomb_log_electron_alpha_thermal_vol_avg: float = None -"""Volume averaged electron-alpha Coulomb logarithm in plasma""" + 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_profile: list[float] = None -"""Profile of 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)""" -t_plasma_electron_alpha_spitzer_slow_vol_avg: float = None -"""Volume averaged electron-alpha Spitzer slowing down time in plasma (s)""" + t_plasma_electron_deuteron_collision_profile: list[float] = field( + default_factory=list + ) + """Profile of electron-deuteron collision time in plasma (s)""" -freq_plasma_electron_profile: list[float] = None -"""Electron plasma frequency profile (Hz)""" + t_plasma_electron_deuteron_collision_vol_avg: float = 0.0 + """Volume averaged electron-deuteron collision time in plasma (s)""" -freq_plasma_electron_vol_avg: float = None -"""Volume averaged electron plasma frequency (Hz)""" + t_plasma_electron_triton_collision_profile: list[float] = field(default_factory=list) + """Profile of electron-triton collision time in plasma (s)""" -freq_plasma_deuteron_profile: list[float] = None -"""Deuteron plasma frequency profile (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_profile: list[float] = None -"""Profile of 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_electron_vol_avg: float = None -"""Volume averaged electron 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_profile: list[float] = None -"""Profile of 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_deuteron_vol_avg: float = None -"""Volume averaged deuteron 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_profile: list[float] = None -"""Profile of 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_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_vol_avg: float = 0.0 + """Volume averaged 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_triton_collision_profile: list[float] = field( + default_factory=list + ) + """Profile of electron-triton 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_vol_avg: float = 0.0 + """Volume averaged 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_alpha_thermal_collision_profile: list[float] = field( + default_factory=list + ) + """Profile of electron-alpha 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_vol_avg: float = 0.0 + """Volume averaged 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)""" + 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_deuteron_collision_vol_avg: float = None -"""Volume averaged electron-deuteron 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_profile: list[float] = None -"""Profile of 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_triton_collision_vol_avg: float = None -"""Volume averaged electron-triton 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_profile: list[float] = None -"""Profile of 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)""" -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_vol_avg: float = 0.0 + """Volume averaged 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_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_electron_collision_vol_avg: float = None -"""Volume averaged electron-electron 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_profile: list[float] = None -"""Profile of 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_deuteron_collision_vol_avg: float = None -"""Volume averaged electron-deuteron 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_profile: list[float] = None -"""Profile of electron-triton collision frequency in plasma (Hz)""" + 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 -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..3420c01e12 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, @@ -82,7 +85,9 @@ ) from process.models.physics.density_limit import PlasmaDensityLimit from process.models.physics.exhaust import PlasmaExhaust -from process.models.physics.impurity_radiation import initialise_imprad +from process.models.physics.impurity_radiation import ( + initialise_imprad, +) from process.models.physics.l_h_transition import PlasmaConfinementTransition from process.models.physics.physics import ( DetailedPhysics, @@ -94,6 +99,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,16 +620,20 @@ 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) 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), ) @@ -631,8 +641,10 @@ 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() @@ -674,7 +686,6 @@ def __init__(self, data: DataStructure): ) self.dcll = DCLL(fw=self.fw) - self.setup_data_structure() @property @@ -745,6 +756,15 @@ def models(self) -> tuple[Model, ...]: self.stellarator, self.plasma_current, self.neoclassics, + self.plasma_inductance, + self.ne_profile, + self.te_profile, + self.plasma_fields, + 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/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..9ccddc2937 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 separate 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 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..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,10 +16,9 @@ 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 + +if TYPE_CHECKING: + from process.models.physics.plasma_profiles import PlasmaProfile logger = logging.getLogger(__name__) @@ -68,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. @@ -86,32 +90,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 +123,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 +145,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 +258,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 +672,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 +1273,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 +1316,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 +1400,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,10 +1441,16 @@ def output(self): ) -class SauterBootstrapCurrent: +class SauterBootstrapCurrent(Model): """Class to calculate the bootstrap current using the Sauter et al formula.""" - def bootstrap_fraction_sauter(self, plasma_profile: float) -> float: + 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: PlasmaProfile) -> float: """Calculate the bootstrap current fraction from the Sauter et al scaling. Parameters @@ -1478,45 +1488,45 @@ 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 # @ 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] @@ -1534,10 +1544,10 @@ 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.n_plasma_profile_elements, + self.data.physics.rmajor, + self.data.physics.b_plasma_toroidal_on_axis, + self.data.physics.triang, ne, ni, tempe, @@ -1550,10 +1560,10 @@ def bootstrap_fraction_sauter(self, plasma_profile: float) -> float: * dlogne_drho + 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.n_plasma_profile_elements, + self.data.physics.rmajor, + self.data.physics.b_plasma_toroidal_on_axis, + self.data.physics.triang, ne, ni, tempe, @@ -1566,10 +1576,10 @@ def bootstrap_fraction_sauter(self, plasma_profile: float) -> float: * dlogte_drho + 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.n_plasma_profile_elements, + self.data.physics.rmajor, + self.data.physics.b_plasma_toroidal_on_axis, + self.data.physics.triang, inverse_q, sqeps, tempi, @@ -1585,14 +1595,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..af0b49527d 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 @@ -786,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 @@ -810,29 +813,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 +858,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. @@ -1303,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. @@ -1336,31 +1345,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 +1379,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 +1388,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 +1405,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 +1418,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 +1496,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 +1686,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 +1696,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 +1742,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 +1757,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 +1805,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 +1826,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 +1850,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 +1866,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 +2290,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 +2392,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 +2955,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..c81e069e50 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 DataStructure +from process.data_structure.physics_variables import PhysicsData from process.models.physics.plasma_profiles import PlasmaProfile logger = logging.getLogger(__name__) @@ -101,7 +102,7 @@ class FusionReactionRate: 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. @@ -113,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 @@ -180,22 +183,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 @@ -203,7 +206,9 @@ 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, ) @@ -219,12 +224,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 ) ) @@ -282,27 +287,29 @@ 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_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 +323,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 ) ) @@ -379,27 +386,31 @@ 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_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 +427,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 ) ) @@ -479,27 +490,31 @@ 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_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 +531,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 +626,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 +664,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 +676,8 @@ def fusion_rate_integral( Parameterised temperature and density profiles. reaction_constants : Bosch-Hale reaction constants. - + physics_data: PhysicsData + physics dataclass Returns ------- @@ -676,8 +694,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 +708,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 +802,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 +823,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 +896,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/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 ef84fdb281..48b8760af0 100644 --- a/process/models/physics/l_h_transition.py +++ b/process/models/physics/l_h_transition.py @@ -5,10 +5,8 @@ from process.core import constants from process.core import process_output as po -from process.data_structure import ( - numerics, - physics_variables, -) +from process.core.model import Model +from process.data_structure import numerics logger = logging.getLogger(__name__) @@ -59,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): @@ -73,21 +71,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 +294,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 +302,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 +321,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 +330,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 +486,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..573ab73acf 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 ) @@ -565,185 +566,189 @@ def run(self): # Calculate fusion power + components - fusion_reactions = reactions.FusionReactionRate(self.plasma_profile) + fusion_reactions = reactions.FusionReactionRate(self.plasma_profile, self.data) 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..79e2027596 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,9 @@ 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.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 +60,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 +89,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 +107,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 +122,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 +204,33 @@ 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 # 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 +243,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 +287,30 @@ def calculate_profile_factors(self): # and
=