From 65f04cd33c342a844ae913c2f6ad3d7bfae70310 Mon Sep 17 00:00:00 2001 From: Clair Mould <86794332+clmould@users.noreply.github.com> Date: Fri, 15 May 2026 16:27:37 +0100 Subject: [PATCH 1/3] convert stellarator vars to dataclass --- process/core/caller.py | 2 +- process/core/init.py | 8 +- process/core/input.py | 48 +-- process/core/model.py | 2 + process/core/output.py | 2 +- process/core/solver/constraints.py | 10 +- process/core/solver/iteration_variables.py | 8 +- .../data_structure/stellarator_variables.py | 279 +++++++----------- process/main.py | 3 + process/models/physics/confinement_time.py | 7 +- process/models/physics/physics.py | 19 +- process/models/physics/plasma_current.py | 16 +- process/models/physics/plasma_geometry.py | 7 +- process/models/stellarator/build.py | 10 +- process/models/stellarator/coils/calculate.py | 95 +++--- process/models/stellarator/coils/forces.py | 50 ++-- process/models/stellarator/coils/output.py | 17 +- process/models/stellarator/denisty_limits.py | 27 +- process/models/stellarator/divertor.py | 41 ++- process/models/stellarator/heating.py | 23 +- process/models/stellarator/initialization.py | 3 +- process/models/stellarator/neoclassics.py | 16 +- process/models/stellarator/stellarator.py | 67 +++-- .../models/stellarator/test_stellarator.py | 39 ++- 24 files changed, 358 insertions(+), 441 deletions(-) diff --git a/process/core/caller.py b/process/core/caller.py index 9d8bb1430b..df87164244 100644 --- a/process/core/caller.py +++ b/process/core/caller.py @@ -269,7 +269,7 @@ def _call_models_once(self, xc: np.ndarray, data: DataStructure): # Perform the various function calls # Stellarator caller - if data_structure.stellarator_variables.istell != 0: + if data.stellarator.istell != 0: self.models.stellarator.run() # TODO Is this return safe? return diff --git a/process/core/init.py b/process/core/init.py index 989d04c198..348267f1b9 100644 --- a/process/core/init.py +++ b/process/core/init.py @@ -27,7 +27,6 @@ ) from process.data_structure.rebco_variables import init_rebco_variables from process.data_structure.scan_variables import init_scan_variables -from process.data_structure.stellarator_variables import init_stellarator_variables from process.data_structure.superconducting_tf_coil_variables import ( init_superconducting_tf_coil_variables, ) @@ -249,7 +248,6 @@ def init_all_module_vars(): init_physics_variables() init_scan_variables() init_superconducting_tf_coil_variables() - init_stellarator_variables() init_tfcoil_variables() constants.init_constants() init_pf_power_variables() @@ -1122,9 +1120,7 @@ def check_process(inputs, data): # noqa: ARG001 # Ensure that blanket material fractions allow non-zero space for steel # CCFE HCPB Model - if data_structure.stellarator_variables.istell == 0 and ( - data.fwbs.i_blanket_type == 1 - ): + if data.stellarator.istell == 0 and (data.fwbs.i_blanket_type == 1): fsum = data.fwbs.breeder_multiplier + data.fwbs.vfcblkt + data.fwbs.vfpblkt if fsum >= 1.0: raise ProcessValidationError( @@ -1244,5 +1240,5 @@ def set_active_constraints(): def set_device_type(data): if data.ife.ife == 1: data_structure.global_variables.icase = "Inertial Fusion model" - elif data_structure.stellarator_variables.istell != 0: + elif data.stellarator.istell != 0: data_structure.global_variables.icase = "Stellarator model" diff --git a/process/core/input.py b/process/core/input.py index 5f299d6c4c..1605ce419d 100644 --- a/process/core/input.py +++ b/process/core/input.py @@ -236,9 +236,7 @@ def __post_init__(self): "pres_blkt_coolant": InputVariable("fwbs", float, range=(100000.0, 100000000.0)), "blpressure_liq": InputVariable("fwbs", float, range=(100000.0, 100000000.0)), "b_cs_limit_max": InputVariable("pf_coil", float, range=(0.01, 100.0)), - "bmn": InputVariable( - data_structure.stellarator_variables, float, range=(0.0001, 0.01) - ), + "bmn": InputVariable("stellarator", float, range=(0.0001, 0.01)), "b_tf_inboard_max": InputVariable("constraints", float, range=(0.1, 50.0)), "f_c_plasma_bootstrap_max": InputVariable( "current_drive", float, range=(-0.999, 0.999) @@ -462,9 +460,7 @@ def __post_init__(self): "f_alpha_energy_confinement_min": InputVariable( "constraints", float, range=(1.0, 100.0) ), - "f_asym": InputVariable( - data_structure.stellarator_variables, float, range=(0.9, 2.0) - ), + "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( @@ -479,9 +475,7 @@ def __post_init__(self): "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( - data_structure.stellarator_variables, float, range=(0.0, 1.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) ), @@ -492,10 +486,8 @@ def __post_init__(self): "f_vforce_inboard": InputVariable( data_structure.tfcoil_variables, float, range=(0.0, 1.0) ), - "f_w": InputVariable(data_structure.stellarator_variables, float, range=(0.1, 1.0)), - "f_st_coil_aspect": InputVariable( - data_structure.stellarator_variables, float, range=(0.1, 10.0) - ), + "f_w": InputVariable("stellarator", float, range=(0.1, 1.0)), + "f_st_coil_aspect": InputVariable("stellarator", float, range=(0.1, 10.0)), "f_z_cryostat": InputVariable("build", float, range=(2.0, 10.0)), "fauxbop": InputVariable("ife", float, range=(0.0, 1.0)), "fblbe": InputVariable("fwbs", float, range=(0.0, 1.0)), @@ -532,9 +524,7 @@ def __post_init__(self): "fjohc0": InputVariable("constraints", float, range=(0.001, 1.0)), "f_ster_div_single": InputVariable("fwbs", float, range=(0.0, 1.0)), "fdiva": InputVariable("divertor", float, range=(0.1, 2.0)), - "fdivwet": InputVariable( - data_structure.stellarator_variables, float, range=(0.01, 1.0) - ), + "fdivwet": InputVariable("stellarator", float, range=(0.01, 1.0)), "feffcd": InputVariable("current_drive", float, range=(0.0, 20.0)), "f_a_fw_outboard_hcd": InputVariable("fwbs", float, range=(0.0, 1.0)), "fhole": InputVariable("fwbs", float, range=(0.0, 1.0)), @@ -543,9 +533,7 @@ def __post_init__(self): "f_h_mode_margin": InputVariable("constraints", float, range=(0.001, 1000000.0)), "f_l_mode_margin": InputVariable("constraints", float, range=(0.001, 1000000.0)), "flirad": InputVariable("ife", float, range=(0.0, 10.0)), - "flpitch": InputVariable( - data_structure.stellarator_variables, float, range=(0.0001, 0.01) - ), + "flpitch": InputVariable("stellarator", float, range=(0.0001, 0.01)), "f_div_flux_expansion": InputVariable("divertor", float, range=(0.0, 10.0)), "fmgdmw": InputVariable("heat_transport", float, range=(0.0, 100.0)), "fndt": InputVariable("buildings", float, range=(0.0, 10.0)), @@ -640,9 +628,7 @@ def __post_init__(self): ), "temp_blkt_coolant_in": InputVariable("fwbs", float, range=(200.0, 600.0)), "inlet_temp_liq": InputVariable("fwbs", float, range=(508.0, 1500.0)), - "iotabar": InputVariable( - data_structure.stellarator_variables, float, range=(0.1, 10.0) - ), + "iotabar": InputVariable("stellarator", float, range=(0.1, 10.0)), "j_tf_bus": InputVariable( data_structure.tfcoil_variables, float, range=(10000.0, 100000000.0) ), @@ -675,7 +661,7 @@ def __post_init__(self): "maintenance_fwbs": InputVariable("costs", float, range=(0.0, 1.0)), "maintenance_gen": InputVariable("costs", float, range=(0.0, 1.0)), "max_gyrotron_frequency": InputVariable( - data_structure.stellarator_variables, + "stellarator", float, range=(1000000000.0, 100000000000000.0), ), @@ -868,9 +854,7 @@ def __post_init__(self): "shdr": InputVariable("ife", float, range=(0.0, 10.0)), "shdzl": InputVariable("ife", float, range=(0.0, 10.0)), "shdzu": InputVariable("ife", float, range=(0.0, 10.0)), - "shear": InputVariable( - data_structure.stellarator_variables, float, range=(0.1, 10.0) - ), + "shear": InputVariable("stellarator", float, range=(0.1, 10.0)), "dz_shld_lower": InputVariable("build", float, range=(0.0, 10.0)), "dz_shld_upper": InputVariable("build", float, range=(0.0, 10.0)), "shmf": InputVariable("buildings", float, range=(0.0, 1.0)), @@ -971,9 +955,7 @@ def __post_init__(self): "temp_plasma_electron_vol_avg_kev": InputVariable( data_structure.physics_variables, float, range=(1.0, 200.0) ), - "te0_ecrh_achievable": InputVariable( - data_structure.stellarator_variables, float, range=(1.0, 1000.0) - ), + "te0_ecrh_achievable": InputVariable("stellarator", float, range=(1.0, 1000.0)), "temp_cp_average": InputVariable( data_structure.tfcoil_variables, float, range=(4.0, 573.15) ), @@ -1287,8 +1269,8 @@ def __post_init__(self): "i_pf_energy_storage_source": InputVariable( data_structure.pf_power_variables, int, range=(1, 3) ), - "istell": InputVariable(data_structure.stellarator_variables, int, range=(0, 6)), - "isthtr": InputVariable(data_structure.stellarator_variables, int, range=(1, 3)), + "istell": InputVariable("stellarator", int, range=(0, 6)), + "isthtr": InputVariable("stellarator", int, range=(1, 3)), "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)), @@ -1299,7 +1281,7 @@ def __post_init__(self): data_structure.physics_variables, int, range=(1, 2) ), "lsa": InputVariable("costs", int, range=(1, 4)), - "m_res": InputVariable(data_structure.stellarator_variables, int, range=(1, 10)), + "m_res": InputVariable("stellarator", int, range=(1, 10)), "n_tf_wp_layers": InputVariable( data_structure.tfcoil_variables, int, range=(1, 100) ), @@ -1313,7 +1295,7 @@ def __post_init__(self): "n_rad_per_layer": InputVariable( data_structure.tfcoil_variables, int, range=(1, 500) ), - "n_res": InputVariable(data_structure.stellarator_variables, int, range=(3, 6)), + "n_res": InputVariable("stellarator", int, range=(3, 6)), "n_tf_graded_layers": InputVariable( data_structure.tfcoil_variables, int, range=(1, 20) ), diff --git a/process/core/model.py b/process/core/model.py index 443926e401..77b480f3d9 100644 --- a/process/core/model.py +++ b/process/core/model.py @@ -21,6 +21,7 @@ from process.data_structure.primary_pumping_variables import PrimaryPumpingData from process.data_structure.pulse_variables import PulseData from process.data_structure.reinke_variables import ReinkeData +from process.data_structure.stellarator_variables import StellaratorData from process.data_structure.structure_variables import StructureData from process.data_structure.times_variables import TimesData from process.data_structure.vacuum_variables import VacuumData @@ -55,6 +56,7 @@ class DataStructure: divertor: DivertorData = initialise_later pf_coil: PFCoilData = initialise_later power: PowerData = initialise_later + stellarator: StellaratorData = initialise_later def __post_init__(self): for f in fields(self): diff --git a/process/core/output.py b/process/core/output.py index 6a2fc187ed..83435cca66 100644 --- a/process/core/output.py +++ b/process/core/output.py @@ -25,7 +25,7 @@ def write(models, data, _outfile): logging_model_handler.clear_logs() # Call stellarator output routine instead if relevant - if data_structure.stellarator_variables.istell != 0: + if data.stellarator.istell != 0: models.stellarator.output() return diff --git a/process/core/solver/constraints.py b/process/core/solver/constraints.py index dd79383fa6..3b3ca07dfe 100644 --- a/process/core/solver/constraints.py +++ b/process/core/solver/constraints.py @@ -737,7 +737,7 @@ def constraint_equation_23(constraint_registration, data): @ConstraintManager.register_constraint(24, "", "<=") -def constraint_equation_24(constraint_registration, _data): +def constraint_equation_24(constraint_registration, data): """Equation for beta upper limit i_beta_component: switch for beta limit scaling (constraint equation 24): @@ -758,7 +758,7 @@ 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 - or data_structure.stellarator_variables.istell != 0 + or data.stellarator.istell != 0 ): value = data_structure.physics_variables.beta_total_vol_avg # Here, the beta limit applies to only the thermal component, not the fast alpha or neutral beam parts @@ -1821,15 +1821,15 @@ def constraint_equation_91(constraint_registration, data): # Achievable ECRH te needs to be larger than needed te for igntion if data_structure.physics_variables.i_plasma_ignited == 0: value = ( - data_structure.stellarator_variables.powerht_constraint + data.stellarator.powerht_constraint + data.current_drive.p_hcd_primary_extra_heat_mw ) else: - value = data_structure.stellarator_variables.powerht_constraint + value = data.stellarator.powerht_constraint return geq( value, - data_structure.stellarator_variables.powerscaling_constraint, + data.stellarator.powerscaling_constraint, constraint_registration, ) diff --git a/process/core/solver/iteration_variables.py b/process/core/solver/iteration_variables.py index 714851471c..17392b4390 100644 --- a/process/core/solver/iteration_variables.py +++ b/process/core/solver/iteration_variables.py @@ -246,9 +246,7 @@ class IterationVariable: "dx_croco_strand_copper", data_structure.rebco_variables, 1.0e-3, 1.0e-1 ), 162: IterationVariable("r_cp_top", "build", 0.0010, 10.0), - 169: IterationVariable( - "te0_ecrh_achievable", data_structure.stellarator_variables, 1.0, 1.0e3 - ), + 169: IterationVariable("te0_ecrh_achievable", "stellarator", 1.0, 1.0e3), 170: IterationVariable("deg_div_field_plate", "divertor", 0.49, 5.01), 171: IterationVariable( "casths_fraction", data_structure.tfcoil_variables, 0.01, 0.99 @@ -261,9 +259,7 @@ class IterationVariable: ), 174: IterationVariable("triang", data_structure.physics_variables, 0.00, 1.00), 175: IterationVariable("kappa", data_structure.physics_variables, 0.00, 10.00), - 176: IterationVariable( - "f_st_coil_aspect", data_structure.stellarator_variables, 0.70, 1.30 - ), + 176: IterationVariable("f_st_coil_aspect", "stellarator", 0.70, 1.30), } diff --git a/process/data_structure/stellarator_variables.py b/process/data_structure/stellarator_variables.py index 310efdbfb4..f7fd3d5740 100644 --- a/process/data_structure/stellarator_variables.py +++ b/process/data_structure/stellarator_variables.py @@ -1,184 +1,119 @@ -# These variables were from stellarator.f90 -f_st_n_coils: float = None -"""Actual number of coils to reference value from stella_config file""" +from dataclasses import dataclass -f_st_rmajor: float = None -"""Actual major radius to reference value from stella_config file""" -f_st_aspect: float = None -"""Actual aspect ratio to reference value from stella_config file""" +@dataclass +class StellaratorData: + f_st_n_coils: float = 0.0 + """Actual number of coils to reference value from stella_config file""" -f_st_coil_aspect: float = None -"""Scaling factor for (stellarator major radius / coil radius ratio)""" + f_st_rmajor: float = 0.0 + """Actual major radius to reference value from stella_config file""" -f_st_b: float = None -"""Actual b_plasma_toroidal_on_axis to reference value from stella_config file """ + f_st_aspect: float = None + """Actual aspect ratio to reference value from stella_config file""" -f_st_i_total: float = None -"""Actual total coil current to reference value from stella_config file""" + f_st_coil_aspect: float = 1.0 + """Scaling factor for (stellarator major radius / coil radius ratio)""" -f_st_rminor: float = None -"""Actual minor radius to reference value from stella_config file""" + f_st_b: float = 0.0 + """Actual b_plasma_toroidal_on_axis to reference value from stella_config file """ -f_coil_shape: float = None -"""Paramtere required for coil scaling -(min_plasma_coil_distance + stella_config_rminor_ref) / stella_config_coil_rminor -""" + f_st_i_total: float = 0.0 + """Actual total coil current to reference value from stella_config file""" -first_call: bool = None + f_st_rminor: float = 0.0 + """Actual minor radius to reference value from stella_config file""" -first_call_stfwbs: bool = None + f_coil_shape: float = 0.0 + """Paramtere required for coil scaling + (min_plasma_coil_distance + stella_config_rminor_ref) / stella_config_coil_rminor + """ -r_coil_minor: float = None -"""Coil minor radius (m)""" + first_call: bool = True -r_coil_major: float = None -"""Coil major radius (m)""" + first_call_stfwbs: bool = True -# These variables were from stellarator_variables.f90 -istell: int = None -"""Switch for stellarator option (set via `device.dat`): - - =0 use tokamak model - - =1 use stellarator model: Helias5 - - =2 use stellarator model: Helias4 - - =3 use stellarator model: Helias3 - - =4 use stellarator model: Wendelstein 7-X with 50 Coils - - =5 use stellarator model: Wendelstein 7-X with 30 Coils - - =6 use stellarator model: Use stella_conf.json file (any modulear stellarator, see documentation) -""" - -bmn: float = None -"""relative radial field perturbation""" - -f_asym: float = None -"""divertor heat load peaking factor""" - -f_rad: float = None -"""radiated power fraction in SOL""" - -f_w: float = None -"""island size fraction factor""" - -fdivwet: float = None -"""wetted fraction of the divertor area""" - -flpitch: float = None -"""field line pitch (rad)""" - -hportamax: float = None -"""maximum available area for horizontal ports (m2)""" - -hportpmax: float = None -"""maximum available poloidal extent for horizontal ports (m)""" - -hporttmax: float = None -"""maximum available toroidal extent for horizontal ports (m)""" - -iotabar: float = None -"""rotational transform (reciprocal of tokamak q) for stellarator confinement time scaling laws""" - -isthtr: int = None -"""Switch for stellarator auxiliary heating method: - - = 1electron cyclotron resonance heating - - = 2lower hybrid heating - - = 3neutral beam injection -""" - -m_res: int = None -"""poloidal resonance number (1)""" - -max_gyrotron_frequency: float = None -"""Maximal available gyrotron frequency (input parameter) (Hz)""" - -n_res: int = None -"""toroidal resonance number (1)""" - -shear: float = None -"""magnetic shear, derivative of iotabar (1)""" - -te0_ecrh_achievable: float = None -"""maximal central electron temperature as achievable by the ECRH, input. (keV)""" - -vportamax: float = None -"""maximum available area for vertical ports (m2)""" - -vportpmax: float = None -"""maximum available poloidal extent for vertical ports (m)""" - -vporttmax: float = None -"""maximum available toroidal extent for vertical ports (m)""" - -powerht_constraint: float = None - -powerscaling_constraint: float = None - - -def init_stellarator_variables(): - global \ - first_call, \ - first_call_stfwbs, \ - f_st_n_coils, \ - f_st_rmajor, \ - f_st_rminor, \ - f_coil_shape, \ - f_st_b, \ - f_st_i_total, \ - r_coil_minor, \ - r_coil_major, \ - istell, \ - bmn, \ - f_asym, \ - f_rad, \ - f_w, \ - f_st_coil_aspect, \ - fdivwet, \ - flpitch, \ - hportamax, \ - hportpmax, \ - hporttmax, \ - iotabar, \ - isthtr, \ - m_res, \ - n_res, \ - shear, \ - vportamax, \ - vportpmax, \ - vporttmax, \ - max_gyrotron_frequency, \ - te0_ecrh_achievable, \ - powerht_constraint, \ - powerscaling_constraint - - first_call = True - first_call_stfwbs = True - f_st_n_coils = 0.0 - f_st_rmajor = 0.0 - f_st_rminor = 0.0 - f_coil_shape = 0.0 - f_st_b = 0.0 - f_st_i_total = 0.0 - f_st_coil_aspect = 1.0 - r_coil_major = 0.0 - r_coil_minor = 0.0 - istell = 0 - bmn = 1e-3 - f_asym = 1.0 - f_rad = 0.85 - f_w = 0.5 - fdivwet = 0.333333333333333 - flpitch = 1e-3 - hportamax = 0.0 - hportpmax = 0.0 - hporttmax = 0.0 - iotabar = 1.0 - isthtr = 1 - m_res = 5 - n_res = 5 - shear = 0.5 - vportamax = 0.0 - vportpmax = 0.0 - vporttmax = 0.0 - max_gyrotron_frequency = 1.0e9 - te0_ecrh_achievable = 1.0e2 - powerht_constraint = 0.0 - powerscaling_constraint = 0.0 + r_coil_minor: float = 0.0 + """Coil minor radius (m)""" + + r_coil_major: float = 0.0 + """Coil major radius (m)""" + + istell: int = 0 + """Switch for stellarator option (set via `device.dat`): + - =0 use tokamak model + - =1 use stellarator model: Helias5 + - =2 use stellarator model: Helias4 + - =3 use stellarator model: Helias3 + - =4 use stellarator model: Wendelstein 7-X with 50 Coils + - =5 use stellarator model: Wendelstein 7-X with 30 Coils + - =6 use stellarator model: Use stella_conf.json file (any modulear stellarator, see documentation) + """ + + bmn: float = 1e-3 + """relative radial field perturbation""" + + f_asym: float = 1.0 + """divertor heat load peaking factor""" + + f_rad: float = 0.85 + """radiated power fraction in SOL""" + + f_w: float = 0.5 + """island size fraction factor""" + + fdivwet: float = 0.333333333333333 + """wetted fraction of the divertor area""" + + flpitch: float = 1e-3 + """field line pitch (rad)""" + + hportamax: float = 0.0 + """maximum available area for horizontal ports (m2)""" + + hportpmax: float = 0.0 + """maximum available poloidal extent for horizontal ports (m)""" + + hporttmax: float = 0.0 + """maximum available toroidal extent for horizontal ports (m)""" + + iotabar: float = 1.0 + """rotational transform (reciprocal of tokamak q) for stellarator confinement time scaling laws""" + + isthtr: int = 1 + """Switch for stellarator auxiliary heating method: + - = 1electron cyclotron resonance heating + - = 2lower hybrid heating + - = 3neutral beam injection + """ + + m_res: int = 5 + """poloidal resonance number (1)""" + + max_gyrotron_frequency: float = 1.0e9 + """Maximal available gyrotron frequency (input parameter) (Hz)""" + + n_res: int = 5 + """toroidal resonance number (1)""" + + shear: float = 0.5 + """magnetic shear, derivative of iotabar (1)""" + + te0_ecrh_achievable: float = 1.0e2 + """maximal central electron temperature as achievable by the ECRH, input. (keV)""" + + vportamax: float = 0.0 + """maximum available area for vertical ports (m2)""" + + vportpmax: float = 0.0 + """maximum available poloidal extent for vertical ports (m)""" + + vporttmax: float = 0.0 + """maximum available toroidal extent for vertical ports (m)""" + + powerht_constraint: float = 0.0 + + powerscaling_constraint: float = 0.0 + + +CREATE_DICTS_FROM_DATACLASS = StellaratorData diff --git a/process/main.py b/process/main.py index 8d13858a37..2257d544e0 100644 --- a/process/main.py +++ b/process/main.py @@ -741,6 +741,9 @@ def models(self) -> tuple[Model, ...]: self.plasma_dia_current, self.plasma_bootstrap_current, self.plasma_exhaust, + self.stellarator, + self.plasma_current, + self.neoclassics, ) def setup_data_structure(self): diff --git a/process/models/physics/confinement_time.py b/process/models/physics/confinement_time.py index e02a511ffa..451b634e1d 100644 --- a/process/models/physics/confinement_time.py +++ b/process/models/physics/confinement_time.py @@ -10,10 +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, - stellarator_variables, -) +from process.data_structure import physics_variables from process.models.physics.plasma_geometry import PlasmaGeom logger = logging.getLogger(__name__) @@ -1395,7 +1392,7 @@ def output_confinement_time_info(self): po.oblnkl(self.outfile) # Plot table of al the H-factor scalings and coparison values - self.output_confinement_comparison(istell=stellarator_variables.istell) + self.output_confinement_comparison(istell=self.data.stellarator.istell) def output_confinement_comparison(self, istell: int): """Routine to calculate ignition margin for different confinement scalings and diff --git a/process/models/physics/physics.py b/process/models/physics/physics.py index 851d6abe59..34ce980ec6 100644 --- a/process/models/physics/physics.py +++ b/process/models/physics/physics.py @@ -21,7 +21,6 @@ impurity_radiation_module, numerics, physics_variables, - stellarator_variables, ) from process.models.physics import impurity_radiation from process.models.physics.plasma_geometry import PlasmaGeom @@ -1725,7 +1724,7 @@ def outplas(self): self.geometry.output() self.current.output() - if stellarator_variables.istell == 0: + if self.data.stellarator.istell == 0: self.fields.output() # Output beta information @@ -1734,7 +1733,7 @@ def outplas(self): self.output_temperature_density_profile_info() po.oblnkl(self.outfile) - if stellarator_variables.istell == 0: + if self.data.stellarator.istell == 0: self.density_limit.output() po.oheadr(self.outfile, "Plasma Reactions :") @@ -2061,7 +2060,7 @@ def outplas(self): "OP ", ) - if stellarator_variables.istell != 0: + if self.data.stellarator.istell != 0: po.ovarre( self.outfile, "SOL radiation power as imposed by f_rad (MW)", @@ -2086,7 +2085,7 @@ def outplas(self): "OP ", ) - if stellarator_variables.istell == 0: + if self.data.stellarator.istell == 0: po.oblnkl(self.outfile) po.ovarre( self.outfile, @@ -2247,12 +2246,12 @@ def outplas(self): self.exhaust.output() - if stellarator_variables.istell == 0: + if self.data.stellarator.istell == 0: self.plasma_transition.output_l_h_threshold_powers() self.confinement.output_confinement_time_info() - if stellarator_variables.istell == 0: + if self.data.stellarator.istell == 0: # Issues 363 Output dimensionless plasma parameters MDK po.osubhd(self.outfile, "Dimensionless plasma parameters") po.ocmmnt(self.outfile, "For definitions see") @@ -2291,7 +2290,7 @@ def outplas(self): po.oblnkl(self.outfile) self.inductance.output_volt_second_information() - if stellarator_variables.istell == 0: + if self.data.stellarator.istell == 0: self.plasma_bootstrap_current.output() self.dia_current.output() @@ -2571,7 +2570,7 @@ def output_temperature_density_profile_info(self) -> None: physics_variables.nd_plasma_electron_line, "OP ", ) - if stellarator_variables.istell == 0: + if self.data.stellarator.istell == 0: po.ovarre( self.outfile, "Greenwald fraction (f_GW)", @@ -3879,7 +3878,7 @@ def output_beta_information(self): ) po.oblnkl(self.outfile) - if stellarator_variables.istell == 0: + if self.data.stellarator.istell == 0: if ( BetaNormMaxModel(physics_variables.i_beta_norm_max) != BetaNormMaxModel.USER_INPUT diff --git a/process/models/physics/plasma_current.py b/process/models/physics/plasma_current.py index 2930290193..5c35b83d53 100644 --- a/process/models/physics/plasma_current.py +++ b/process/models/physics/plasma_current.py @@ -16,10 +16,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, - stellarator_variables, -) +from process.data_structure import physics_variables from process.models.physics.plasma_geometry import PlasmaGeometryModelType logger = logging.getLogger(__name__) @@ -68,7 +65,7 @@ def full_name(self): return self._full_name_ -class PlasmaCurrent: +class PlasmaCurrent(Model): """Class to hold plasma current calculations for plasma processing.""" def __init__(self): @@ -76,11 +73,14 @@ def __init__(self): self.outfile = constants.NOUT self.mfile = constants.MFILE + def run(self): + """This model doesn't need to be run""" + def output(self) -> None: """Output plasma current and safety factor information.""" po.oheadr(self.outfile, "Plasma Current and Safety Factor") - if stellarator_variables.istell == 0: + if self.data.stellarator.istell == 0: po.oblnkl(self.outfile) po.ovarin( self.outfile, @@ -148,7 +148,7 @@ def output(self) -> None: "OP ", ) - if stellarator_variables.istell == 0: + if self.data.stellarator.istell == 0: po.ovarrf( self.outfile, "Safety factor on axis (q₀)", "(q0)", physics_variables.q0 ) @@ -194,7 +194,7 @@ def output(self) -> None: self.outfile, "Rotational transform", "(iotabar)", - stellarator_variables.iotabar, + self.data.stellarator.iotabar, ) def calculate_plasma_current( diff --git a/process/models/physics/plasma_geometry.py b/process/models/physics/plasma_geometry.py index 19a99bd1d0..ac26d9b925 100644 --- a/process/models/physics/plasma_geometry.py +++ b/process/models/physics/plasma_geometry.py @@ -12,7 +12,6 @@ from process.core.model import Model from process.data_structure import ( physics_variables, - stellarator_variables, ) logger = logging.getLogger(__name__) @@ -524,7 +523,7 @@ def output(self): """ po.oheadr(self.outfile, "Plasma Geometry") - if stellarator_variables.istell == 0: + if self.data.stellarator.istell == 0: if self.data.divertor.n_divertors == 0: po.ocmmnt(self.outfile, "Plasma configuration = limiter") elif self.data.divertor.n_divertors == 1: @@ -539,7 +538,7 @@ def output(self): else: po.ocmmnt(self.outfile, "Plasma configuration = stellarator") - if stellarator_variables.istell == 0: + if self.data.stellarator.istell == 0: if physics_variables.itart == 0: physics_variables.itart_r = physics_variables.itart po.ovarin( @@ -607,7 +606,7 @@ def output(self): po.oblnkl(self.outfile) geom_type = PlasmaGeometryModelType(physics_variables.i_plasma_geometry) - if stellarator_variables.istell == 0: + if self.data.stellarator.istell == 0: po.ocmmnt( self.outfile, f"X-Point Elongation set from: {geom_type.kappa_model.description}", diff --git a/process/models/stellarator/build.py b/process/models/stellarator/build.py index 3a8bfd81dc..d49bc5ff1d 100644 --- a/process/models/stellarator/build.py +++ b/process/models/stellarator/build.py @@ -4,9 +4,6 @@ physics_variables, stellarator_configuration, ) -from process.data_structure import ( - stellarator_variables as st, -) def st_build(stellarator, f_output: bool, data: DataStructure): @@ -92,12 +89,15 @@ def st_build(stellarator, f_output: bool, data: DataStructure): # derivative_min_LCFS_coils_dist for how strong the stellarator shape changes wrt to aspect ratio data.build.available_radial_space = ( - st.r_coil_minor * st.f_coil_shape - physics_variables.rminor + data.stellarator.r_coil_minor * data.stellarator.f_coil_shape + - physics_variables.rminor ) +stellarator_configuration.stella_config_derivative_min_lcfs_coils_dist * ( physics_variables.rminor - - st.f_st_rmajor * stellarator_configuration.stella_config_rminor_ref + - data.stellarator.f_st_rmajor + * stellarator_configuration.stella_config_rminor_ref ) + # Radius to inner edge of inboard shield data.build.r_shld_inboard_inner = ( physics_variables.rmajor diff --git a/process/models/stellarator/coils/calculate.py b/process/models/stellarator/coils/calculate.py index 84481e2d3a..b4797438a6 100644 --- a/process/models/stellarator/coils/calculate.py +++ b/process/models/stellarator/coils/calculate.py @@ -6,7 +6,6 @@ from process.data_structure import ( rebco_variables, stellarator_configuration, - stellarator_variables, tfcoil_variables, ) from process.models.stellarator.coils import forces @@ -41,14 +40,14 @@ def st_coil(stellarator, output: bool, data: DataStructure): data structure object to provide model data """ - r_coil_major = stellarator_variables.r_coil_major - r_coil_minor = stellarator_variables.r_coil_minor + r_coil_major = data.stellarator.r_coil_major + r_coil_minor = data.stellarator.r_coil_minor ####################################################################################### calculate_winding_pack_geometry() # Total coil current (MA) - coilcurrent = calculate_current() + coilcurrent = calculate_current(data) awp_rad, a_tf_wp_no_insulation, a_tf_wp_with_insulation, f_a_scu_of_wp = ( winding_pack_total_size(r_coil_major, r_coil_minor, coilcurrent, data) @@ -60,8 +59,8 @@ def st_coil(stellarator, output: bool, data: DataStructure): ####################################################################################### # Port calculations - calculate_vertical_ports() - calculate_horizontal_ports() + calculate_vertical_ports(data) + calculate_horizontal_ports(data) ####################################################################################### # General Coil Geometry values @@ -79,8 +78,8 @@ def st_coil(stellarator, output: bool, data: DataStructure): calculate_coils_summary_variables(coilcurrent, r_coil_major, r_coil_minor, awp_rad) - inductance = calculate_inductnace(r_coil_minor) - calculate_stored_magnetic_energy(r_coil_minor) + inductance = calculate_inductance(r_coil_minor, data) + calculate_stored_magnetic_energy(r_coil_minor, data) # Coil dimensions data.build.z_tf_inside_half = ( @@ -99,9 +98,9 @@ def st_coil(stellarator, output: bool, data: DataStructure): # [m^2] Total surface area of toroidal shells covering coils tfcoil_variables.tfcryoarea = ( stellarator_configuration.stella_config_coilsurface - * stellarator_variables.f_st_rmajor + * data.stellarator.f_st_rmajor * ( - stellarator_variables.r_coil_minor + data.stellarator.r_coil_minor / stellarator_configuration.stella_config_coil_rminor ) * 1.1e0 @@ -111,7 +110,7 @@ def st_coil(stellarator, output: bool, data: DataStructure): # Minimal bending radius: min_bending_radius = ( stellarator_configuration.stella_config_min_bend_radius - * stellarator_variables.f_st_rmajor + * data.stellarator.f_st_rmajor / (1.0 - tfcoil_variables.dr_tf_wp_with_insulation / (2.0 * r_coil_minor)) ) @@ -128,22 +127,22 @@ def st_coil(stellarator, output: bool, data: DataStructure): # ####################################################################################### # Forces scaling # - forces.calculate_max_force_density(a_tf_wp_no_insulation) + forces.calculate_max_force_density(a_tf_wp_no_insulation, data) forces.calculate_maximum_stress() # Units: MN/m - max_force_density_mnm = forces.calculate_max_force_density_mnm() + max_force_density_mnm = forces.calculate_max_force_density_mnm(data) max_lateral_force_density = forces.calculate_max_lateral_force_density( - a_tf_wp_no_insulation + a_tf_wp_no_insulation, data ) max_radial_force_density = forces.calculate_max_radial_force_density( - a_tf_wp_no_insulation + a_tf_wp_no_insulation, data ) # # F = f*V = B*j*V \propto B/B0 * I/I0 * A0/A * A/A0 * len/len0 - centering_force_max_mn = forces.calculate_centering_force_max_mn() - centering_force_min_mn = forces.calculate_centering_force_min_mn() - centering_force_avg_mn = forces.calculate_centering_force_avg_mn() + centering_force_max_mn = forces.calculate_centering_force_max_mn(data) + centering_force_min_mn = forces.calculate_centering_force_min_mn(data) + centering_force_avg_mn = forces.calculate_centering_force_avg_mn(data) # #################################### @@ -289,37 +288,41 @@ def calculate_coils_summary_variables(coilcurrent, r_coil_major, r_coil_minor, a # useful for stellarators -def calculate_inductnace(r_coil_minor): +def calculate_inductance(r_coil_minor, data: DataStructure): """This uses the reference value for the inductance and scales it with a^2/R (toroid inductance scaling) Parameters ---------- r_coil_minor : + data: DataStructure + data structure object """ return ( stellarator_configuration.stella_config_inductance - / stellarator_variables.f_st_rmajor + / data.stellarator.f_st_rmajor * (r_coil_minor / stellarator_configuration.stella_config_coil_rminor) ** 2 - * stellarator_variables.f_st_n_coils**2 + * data.stellarator.f_st_n_coils**2 ) -def calculate_stored_magnetic_energy(r_coil_minor): +def calculate_stored_magnetic_energy(r_coil_minor, data: DataStructure): """[GJ] Total magnetic energy Parameters ---------- r_coil_minor : + data: DataStructure + data structure object """ tfcoil_variables.e_tf_magnetic_stored_total_gj = ( 0.5e0 * ( stellarator_configuration.stella_config_inductance - / stellarator_variables.f_st_rmajor + / data.stellarator.f_st_rmajor * (r_coil_minor / stellarator_configuration.stella_config_coil_rminor) ** 2 - * stellarator_variables.f_st_n_coils**2 + * data.stellarator.f_st_n_coils**2 ) * (tfcoil_variables.c_tf_total / tfcoil_variables.n_tf_coils) ** 2 * 1.0e-9 @@ -353,19 +356,19 @@ def calculate_winding_pack_geometry(): ) ** 2 - tfcoil_variables.a_tf_turn_cable_space_no_void -def calculate_current(): +def calculate_current(data: DataStructure): """Recalculate the coil current from global stellarator configuration and variables: coilcurrent = f_b * stella_config_i0 * f_r / f_n - Update stellarator_variables.f_i + Update data.stellarator.f_i """ coilcurrent = ( - stellarator_variables.f_st_b + data.stellarator.f_st_b * stellarator_configuration.stella_config_i0 - * stellarator_variables.f_st_rmajor - / stellarator_variables.f_st_n_coils + * data.stellarator.f_st_rmajor + / data.stellarator.f_st_n_coils ) - stellarator_variables.f_st_i_total = ( + data.stellarator.f_st_i_total = ( coilcurrent / stellarator_configuration.stella_config_i0 ) return coilcurrent @@ -549,43 +552,37 @@ def calculate_casing(): tfcoil_variables.dx_tf_side_case_min = tfcoil_variables.dr_tf_nose_case -def calculate_vertical_ports(): +def calculate_vertical_ports(data: DataStructure): # Maximal toroidal port size (vertical ports) (m) # The maximal distance is correct but the vertical extension of this port is not clear# # This is simplified for now and can be made more accurate in the future# - stellarator_variables.vporttmax = ( + data.stellarator.vporttmax = ( 0.4e0 * stellarator_configuration.stella_config_max_portsize_width - * stellarator_variables.f_st_rmajor - / stellarator_variables.f_st_n_coils + * data.stellarator.f_st_rmajor + / data.stellarator.f_st_n_coils ) # This is not accurate yet. Needs more insight# # Maximal poloidal port size (vertical ports) (m) - stellarator_variables.vportpmax = ( - 2.0 * stellarator_variables.vporttmax - ) # Simple approximation + data.stellarator.vportpmax = 2.0 * data.stellarator.vporttmax # Simple approximation # Maximal vertical port clearance area (m2) - stellarator_variables.vportamax = ( - stellarator_variables.vporttmax * stellarator_variables.vportpmax - ) + data.stellarator.vportamax = data.stellarator.vporttmax * data.stellarator.vportpmax -def calculate_horizontal_ports(): +def calculate_horizontal_ports(data: DataStructure): # Maximal toroidal port size (horizontal ports) (m) - stellarator_variables.hporttmax = ( + data.stellarator.hporttmax = ( 0.8e0 * stellarator_configuration.stella_config_max_portsize_width - * stellarator_variables.f_st_rmajor - / stellarator_variables.f_st_n_coils + * data.stellarator.f_st_rmajor + / data.stellarator.f_st_n_coils ) # Factor 0.8 to take the variation with height into account # Maximal poloidal port size (horizontal ports) (m) - stellarator_variables.hportpmax = ( - 2.0e0 * stellarator_variables.hporttmax + data.stellarator.hportpmax = ( + 2.0e0 * data.stellarator.hporttmax ) # Simple approximation # Maximal horizontal port clearance area (m2) - stellarator_variables.hportamax = ( - stellarator_variables.hporttmax * stellarator_variables.hportpmax - ) + data.stellarator.hportamax = data.stellarator.hporttmax * data.stellarator.hportpmax diff --git a/process/models/stellarator/coils/forces.py b/process/models/stellarator/coils/forces.py index 60b2162dd3..b308f78731 100644 --- a/process/models/stellarator/coils/forces.py +++ b/process/models/stellarator/coils/forces.py @@ -1,24 +1,26 @@ """Module for coil force calculations in stellarators.""" +from process.core.model import DataStructure from process.data_structure import ( stellarator_configuration, - stellarator_variables, tfcoil_variables, ) -def calculate_max_force_density(a_tf_wp_no_insulation): +def calculate_max_force_density(a_tf_wp_no_insulation, data: DataStructure): """Calculate the maximum force density in the TF coil winding pack from scaling. [MN/m3] Parameters ---------- a_tf_wp_no_insulation : + data: DataStructure + data structure object """ tfcoil_variables.max_force_density = ( stellarator_configuration.stella_config_max_force_density - * stellarator_variables.f_st_i_total - / stellarator_variables.f_st_n_coils + * data.stellarator.f_st_i_total + / data.stellarator.f_st_n_coils * tfcoil_variables.b_tf_inboard_peak_symmetric / stellarator_configuration.stella_config_wp_bmax * stellarator_configuration.stella_config_wp_area @@ -26,12 +28,12 @@ def calculate_max_force_density(a_tf_wp_no_insulation): ) -def calculate_max_force_density_mnm(): +def calculate_max_force_density_mnm(data: DataStructure): """Calculate the maximum force per meter in the TF coil winding pack from scaling. [MN/m]""" return ( stellarator_configuration.stella_config_max_force_density_mnm - * stellarator_variables.f_st_i_total - / stellarator_variables.f_st_n_coils + * data.stellarator.f_st_i_total + / data.stellarator.f_st_n_coils * tfcoil_variables.b_tf_inboard_peak_symmetric / stellarator_configuration.stella_config_wp_bmax ) @@ -46,18 +48,20 @@ def calculate_maximum_stress(): ) -def calculate_max_lateral_force_density(a_tf_wp_no_insulation): +def calculate_max_lateral_force_density(a_tf_wp_no_insulation, data: DataStructure): """Calculate the maximum lateral force density in the TF coil winding pack from scaling. [MN/m3] Parameters ---------- a_tf_wp_no_insulation : + data: DataStructure + data structure object """ return ( stellarator_configuration.stella_config_max_lateral_force_density - * stellarator_variables.f_st_i_total - / stellarator_variables.f_st_n_coils + * data.stellarator.f_st_i_total + / data.stellarator.f_st_n_coils * tfcoil_variables.b_tf_inboard_peak_symmetric / stellarator_configuration.stella_config_wp_bmax * stellarator_configuration.stella_config_wp_area @@ -65,18 +69,20 @@ def calculate_max_lateral_force_density(a_tf_wp_no_insulation): ) -def calculate_max_radial_force_density(a_tf_wp_no_insulation): +def calculate_max_radial_force_density(a_tf_wp_no_insulation, data): """Calculate the maximum radial force density in the TF coil winding pack from scaling. [MN/m3] Parameters ---------- a_tf_wp_no_insulation : + data: DataStructure + data structure object """ return ( stellarator_configuration.stella_config_max_radial_force_density - * stellarator_variables.f_st_i_total - / stellarator_variables.f_st_n_coils + * data.stellarator.f_st_i_total + / data.stellarator.f_st_n_coils * tfcoil_variables.b_tf_inboard_peak_symmetric / stellarator_configuration.stella_config_wp_bmax * stellarator_configuration.stella_config_wp_area @@ -84,12 +90,12 @@ def calculate_max_radial_force_density(a_tf_wp_no_insulation): ) -def calculate_centering_force_max_mn(): +def calculate_centering_force_max_mn(data: DataStructure): """Calculate the maximum centering force in the TF coils from scaling. [MN]""" return ( stellarator_configuration.stella_config_centering_force_max_mn - * stellarator_variables.f_st_i_total - / stellarator_variables.f_st_n_coils + * data.stellarator.f_st_i_total + / data.stellarator.f_st_n_coils * tfcoil_variables.b_tf_inboard_peak_symmetric / stellarator_configuration.stella_config_wp_bmax * stellarator_configuration.stella_config_coillength @@ -98,12 +104,12 @@ def calculate_centering_force_max_mn(): ) -def calculate_centering_force_min_mn(): +def calculate_centering_force_min_mn(data: DataStructure): """Calculate the minimum centering force in the TF coils from scaling. [MN]""" return ( stellarator_configuration.stella_config_centering_force_min_mn - * stellarator_variables.f_st_i_total - / stellarator_variables.f_st_n_coils + * data.stellarator.f_st_i_total + / data.stellarator.f_st_n_coils * tfcoil_variables.b_tf_inboard_peak_symmetric / stellarator_configuration.stella_config_wp_bmax * stellarator_configuration.stella_config_coillength @@ -112,12 +118,12 @@ def calculate_centering_force_min_mn(): ) -def calculate_centering_force_avg_mn(): +def calculate_centering_force_avg_mn(data: DataStructure): """Calculate the average centering force in the TF coils from scaling. [MN]""" return ( stellarator_configuration.stella_config_centering_force_avg_mn - * stellarator_variables.f_st_i_total - / stellarator_variables.f_st_n_coils + * data.stellarator.f_st_i_total + / data.stellarator.f_st_n_coils * tfcoil_variables.b_tf_inboard_peak_symmetric / stellarator_configuration.stella_config_wp_bmax * stellarator_configuration.stella_config_coillength diff --git a/process/models/stellarator/coils/output.py b/process/models/stellarator/coils/output.py index ba40cada64..d2e31248a6 100644 --- a/process/models/stellarator/coils/output.py +++ b/process/models/stellarator/coils/output.py @@ -1,8 +1,5 @@ from process.core import process_output as po -from process.data_structure import ( - stellarator_variables, - tfcoil_variables, -) +from process.data_structure import tfcoil_variables def write( @@ -513,35 +510,35 @@ def write( stellarator.outfile, "Max toroidal size of vertical ports (m)", "(vporttmax)", - stellarator_variables.vporttmax, + data.stellarator.vporttmax, ) po.ovarre( stellarator.outfile, "Max poloidal size of vertical ports (m)", "(vportpmax)", - stellarator_variables.vportpmax, + data.stellarator.vportpmax, ) po.ovarre( stellarator.outfile, "Max area of vertical ports (m2)", "(vportamax)", - stellarator_variables.vportamax, + data.stellarator.vportamax, ) po.ovarre( stellarator.outfile, "Max toroidal size of horizontal ports (m)", "(hporttmax)", - stellarator_variables.hporttmax, + data.stellarator.hporttmax, ) po.ovarre( stellarator.outfile, "Max poloidal size of horizontal ports (m)", "(hportpmax)", - stellarator_variables.hportpmax, + data.stellarator.hportpmax, ) po.ovarre( stellarator.outfile, "Max area of horizontal ports (m2)", "(hportamax)", - stellarator_variables.hportamax, + data.stellarator.hportamax, ) diff --git a/process/models/stellarator/denisty_limits.py b/process/models/stellarator/denisty_limits.py index 52ac9cf82f..7f4e8b1c19 100644 --- a/process/models/stellarator/denisty_limits.py +++ b/process/models/stellarator/denisty_limits.py @@ -5,15 +5,12 @@ from process.core import process_output as po from process.core.exceptions import ProcessValueError -from process.data_structure import ( - physics_variables, - stellarator_variables, -) +from process.data_structure import physics_variables logger = logging.getLogger(__name__) -def st_denisty_limits(stellarator, f_output): +def st_denisty_limits(stellarator, f_output, data): """Routine to reiterate the physics loop This routine reiterates some physics modules. @@ -24,6 +21,8 @@ def st_denisty_limits(stellarator, f_output): f_output : + data: DataStructure + data structure object """ # Set the required value for icc=5 @@ -37,7 +36,7 @@ def st_denisty_limits(stellarator, f_output): # Calculates the ECRH parameters ne0_max_ECRH, bt_ecrh = st_d_limit_ecrh( - stellarator_variables.max_gyrotron_frequency, + data.stellarator.max_gyrotron_frequency, physics_variables.b_plasma_toroidal_on_axis, ) @@ -45,11 +44,7 @@ def st_denisty_limits(stellarator, f_output): bt_ecrh = min(physics_variables.b_plasma_toroidal_on_axis, bt_ecrh) if f_output: - output( - stellarator, - bt_ecrh, - ne0_max_ECRH, - ) + output(stellarator, bt_ecrh, ne0_max_ECRH, data) def st_sudo_density_limit(b_plasma_toroidal_on_axis, powht, rmajor, rminor): @@ -218,14 +213,14 @@ def power_at_ignition_point(stellarator, gyro_frequency_max, te0_available): return powerht_out, pscalingmw_out -def output(stellarator, bt_ecrh, ne0_max_ECRH): +def output(stellarator, bt_ecrh, ne0_max_ECRH, data): po.oheadr(stellarator.outfile, "ECRH Ignition at lower values. Information:") po.ovarre( stellarator.outfile, "Maximal available gyrotron freq (input)", "(max_gyro_frequency)", - stellarator_variables.max_gyrotron_frequency, + data.stellarator.max_gyrotron_frequency, ) po.ovarre( @@ -259,13 +254,13 @@ def output(stellarator, bt_ecrh, ne0_max_ECRH): stellarator.outfile, "Maximum reachable ECRH temperature (pseudo) (KEV)", "(te0_ecrh_achievable)", - stellarator_variables.te0_ecrh_achievable, + data.stellarator.te0_ecrh_achievable, ) powerht_local, pscalingmw_local = power_at_ignition_point( stellarator, - stellarator_variables.max_gyrotron_frequency, - stellarator_variables.te0_ecrh_achievable, + data.stellarator.max_gyrotron_frequency, + data.stellarator.te0_ecrh_achievable, ) po.ovarre( stellarator.outfile, diff --git a/process/models/stellarator/divertor.py b/process/models/stellarator/divertor.py index b84002145f..ded0770c94 100644 --- a/process/models/stellarator/divertor.py +++ b/process/models/stellarator/divertor.py @@ -5,7 +5,6 @@ from process.core.model import DataStructure from process.data_structure import ( physics_variables, - stellarator_variables, ) @@ -27,7 +26,7 @@ def st_div(stellarator, f_output: bool, data: DataStructure): ---------- Stellarator Divertor Model for the Systems Code PROCESS, F. Warmer, 21/06/2013 """ - Theta = stellarator_variables.flpitch # ~bmn [rad] field line pitch + Theta = data.stellarator.flpitch # ~bmn [rad] field line pitch r = physics_variables.rmajor p_div = physics_variables.p_plasma_separatrix_mw alpha = data.divertor.anginc @@ -45,18 +44,16 @@ def st_div(stellarator, f_output: bool, data: DataStructure): # Island size (m) w_r = 4.0e0 * np.sqrt( - stellarator_variables.bmn - * r - / (stellarator_variables.shear * stellarator_variables.n_res) + data.stellarator.bmn * r / (data.stellarator.shear * data.stellarator.n_res) ) # Perpendicular (to plate) distance from X-point to divertor plate (m) - Delta = stellarator_variables.f_w * w_r + Delta = data.stellarator.f_w * w_r # Length 'along' plasma (m) - l_p = 2 * np.pi * r * (stellarator_variables.m_res) / stellarator_variables.n_res + l_p = 2 * np.pi * r * (data.stellarator.m_res) / data.stellarator.n_res # Connection length from X-point to divertor plate (m) @@ -80,20 +77,20 @@ def st_div(stellarator, f_output: bool, data: DataStructure): # Total length of divertor plates (m) - l_t = 2.0e0 * stellarator_variables.n_res * l_d + l_t = 2.0e0 * data.stellarator.n_res * l_d # Wetted area (m2) a_eff = l_t * l_q - # Divertor plate width (m): assume total area is wetted area/stellarator_variables.fdivwet + # Divertor plate width (m): assume total area is wetted area/data.stellarator.fdivwet - darea = a_eff / stellarator_variables.fdivwet + darea = a_eff / data.stellarator.fdivwet l_w = darea / l_t # Divertor heat load (MW/m2) - q_div = stellarator_variables.f_asym * (p_div / a_eff) + q_div = data.stellarator.f_asym * (p_div / a_eff) # Transfer to global variables @@ -132,6 +129,8 @@ def output(stellarator, a_eff, l_d, l_w, f_x, l_q, w_r, Delta, data: DataStructu Island width (m). Delta : Perpendicular distance from X-point to plate (m). + data: DataStructure + data structure object """ po.oheadr(stellarator.outfile, "Divertor") @@ -164,56 +163,56 @@ def output(stellarator, a_eff, l_d, l_w, f_x, l_q, w_r, Delta, data: DataStructu stellarator.outfile, "Radiated power fraction in SOL", "(f_rad)", - stellarator_variables.f_rad, + data.stellarator.f_rad, ) po.ovarre( stellarator.outfile, "Heat load peaking factor", "(f_asym)", - stellarator_variables.f_asym, + data.stellarator.f_asym, ) po.ovarin( stellarator.outfile, "Poloidal resonance number", "(m_res)", - stellarator_variables.m_res, + data.stellarator.m_res, ) po.ovarin( stellarator.outfile, "Toroidal resonance number", "(n_res)", - stellarator_variables.n_res, + data.stellarator.n_res, ) po.ovarre( stellarator.outfile, "Relative radial field perturbation", "(bmn)", - stellarator_variables.bmn, + data.stellarator.bmn, ) po.ovarre( stellarator.outfile, "Field line pitch (rad)", "(flpitch)", - stellarator_variables.flpitch, + data.stellarator.flpitch, ) po.ovarre( stellarator.outfile, "Island size fraction factor", "(f_w)", - stellarator_variables.f_w, + data.stellarator.f_w, ) po.ovarre( stellarator.outfile, - "Magnetic stellarator_variables.shear (/m)", + "Magnetic data.stellarator.shear (/m)", "(shear)", - stellarator_variables.shear, + data.stellarator.shear, ) po.ovarre(stellarator.outfile, "Divertor wetted area (m2)", "(A_eff)", a_eff) po.ovarre( stellarator.outfile, "Wetted area fraction of total plate area", "(fdivwet)", - stellarator_variables.fdivwet, + data.stellarator.fdivwet, ) po.ovarre(stellarator.outfile, "Divertor plate length (m)", "(L_d)", l_d) po.ovarre(stellarator.outfile, "Divertor plate width (m)", "(L_w)", l_w) diff --git a/process/models/stellarator/heating.py b/process/models/stellarator/heating.py index c19a9b0eb2..9bbf3d8780 100644 --- a/process/models/stellarator/heating.py +++ b/process/models/stellarator/heating.py @@ -3,10 +3,7 @@ from process.core import process_output as po from process.core.exceptions import ProcessValueError from process.core.model import DataStructure -from process.data_structure import ( - physics_variables, - stellarator_variables, -) +from process.data_structure import physics_variables logger = logging.getLogger(__name__) @@ -29,7 +26,7 @@ def st_heat(stellarator, f_output: bool, data: DataStructure): """ f_p_beam_injected_ions = None - if stellarator_variables.isthtr == 1: + if data.stellarator.isthtr == 1: data.current_drive.p_hcd_ecrh_injected_total_mw = ( data.current_drive.p_hcd_primary_extra_heat_mw ) @@ -45,7 +42,7 @@ def st_heat(stellarator, f_output: bool, data: DataStructure): + data.current_drive.p_hcd_injected_electrons_mw ) / data.current_drive.eta_hcd_primary_injector_wall_plug - elif stellarator_variables.isthtr == 2: + elif data.stellarator.isthtr == 2: data.current_drive.p_hcd_lowhyb_injected_total_mw = ( data.current_drive.p_hcd_primary_extra_heat_mw ) @@ -61,7 +58,7 @@ def st_heat(stellarator, f_output: bool, data: DataStructure): + data.current_drive.p_hcd_injected_electrons_mw ) / data.current_drive.eta_hcd_primary_injector_wall_plug - elif stellarator_variables.isthtr == 3: + elif data.stellarator.isthtr == 3: ( _effnbss, f_p_beam_injected_ions, @@ -90,10 +87,10 @@ def st_heat(stellarator, f_output: bool, data: DataStructure): + data.current_drive.p_hcd_injected_electrons_mw ) / data.current_drive.eta_hcd_primary_injector_wall_plug else: - logger.error(f"isthtr {stellarator_variables.isthtr}") - logger.error(f"isthtr type {type(stellarator_variables.isthtr)}") + logger.error(f"isthtr {data.stellarator.isthtr}") + logger.error(f"isthtr type {type(data.stellarator.isthtr)}") raise ProcessValueError( - "Illegal value for isthtr", isthtr=stellarator_variables.isthtr + "Illegal value for isthtr", isthtr=data.stellarator.isthtr ) # Total injected power @@ -139,11 +136,11 @@ def st_heat(stellarator, f_output: bool, data: DataStructure): def output(stellarator, data: DataStructure, f_p_beam_injected_ions=None): po.oheadr(stellarator.outfile, "Auxiliary Heating System") - if stellarator_variables.isthtr == 1: + if data.stellarator.isthtr == 1: po.ocmmnt(stellarator.outfile, "Electron Cyclotron Resonance Heating") - elif stellarator_variables.isthtr == 2: + elif data.stellarator.isthtr == 2: po.ocmmnt(stellarator.outfile, "Lower Hybrid Heating") - elif stellarator_variables.isthtr == 3: + elif data.stellarator.isthtr == 3: po.ocmmnt(stellarator.outfile, "Neutral Beam Injection Heating") if physics_variables.i_plasma_ignited == 1: diff --git a/process/models/stellarator/initialization.py b/process/models/stellarator/initialization.py index 79d7b7887e..15801a286f 100644 --- a/process/models/stellarator/initialization.py +++ b/process/models/stellarator/initialization.py @@ -2,7 +2,6 @@ from process.data_structure import ( numerics, physics_variables, - stellarator_variables, ) @@ -13,7 +12,7 @@ def st_init(data: DataStructure): Many of these may override the values set in routine """ - if stellarator_variables.istell == 0: + if data.stellarator.istell == 0: return numerics.boundu[0] = 40.0 # allow higher aspect ratio diff --git a/process/models/stellarator/neoclassics.py b/process/models/stellarator/neoclassics.py index ceab08c950..ab80137dd2 100644 --- a/process/models/stellarator/neoclassics.py +++ b/process/models/stellarator/neoclassics.py @@ -3,23 +3,29 @@ import numpy as np from process.core import constants +from process.core.model import Model from process.data_structure import ( impurity_radiation_module, neoclassics_variables, physics_variables, stellarator_configuration, - stellarator_variables, ) from process.models.stellarator.stellarator import KEV logger = logging.getLogger(__name__) -class Neoclassics: +class Neoclassics(Model): @property def no_roots(self): return neoclassics_variables.roots.shape[0] + def output(self): + """This model doesn't have any output""" + + def run(self): + """This model doesn't need to be run""" + def init_neoclassics(self, r_effin, eps_effin, iotain): """Constructor of the neoclassics object from the effective radius, epsilon effective and iota only. @@ -282,7 +288,7 @@ def calc_neoclassics(self): self.init_neoclassics( 0.6, stellarator_configuration.stella_config_epseff, - stellarator_variables.iotabar, + self.data.stellarator.iotabar, ) q_PROCESS = ( @@ -781,7 +787,7 @@ def neoclassics_calc_q_flux(self): def st_calc_eff_chi(self): volscaling = ( physics_variables.vol_plasma - * stellarator_variables.f_st_rmajor + * self.data.stellarator.f_st_rmajor * ( impurity_radiation_module.radius_plasma_core_norm * physics_variables.rminor @@ -791,7 +797,7 @@ def st_calc_eff_chi(self): ) surfacescaling = ( physics_variables.a_plasma_surface - * stellarator_variables.f_st_rmajor + * self.data.stellarator.f_st_rmajor * ( impurity_radiation_module.radius_plasma_core_norm * physics_variables.rminor diff --git a/process/models/stellarator/stellarator.py b/process/models/stellarator/stellarator.py index 38f3e8f632..66509d9b3e 100644 --- a/process/models/stellarator/stellarator.py +++ b/process/models/stellarator/stellarator.py @@ -18,7 +18,6 @@ numerics, physics_variables, stellarator_configuration, - stellarator_variables, tfcoil_variables, ) from process.models.physics.physics import Physics, rether @@ -133,7 +132,7 @@ def run(self, output: bool = False): self.physics.outplas() st_heat(self, True, self.data) self.st_phys(True) - st_denisty_limits(self, True) + st_denisty_limits(self, True, self.data) # Change in density limit can result in changed dene? # A second call of st_phys is used to make sure it is consitent. @@ -159,7 +158,7 @@ def run(self, output: bool = False): self.st_new_config() self.st_geom() self.st_phys(False) - st_denisty_limits(self, False) + st_denisty_limits(self, False, self.data) st_coil(self, False, self.data) st_build(self, False, self.data) self.st_strc(False) @@ -182,14 +181,14 @@ def run(self, output: bool = False): # This call is comparably time consuming.. # If the respective constraint equation is not called, do not set the values ( - stellarator_variables.powerht_constraint, - stellarator_variables.powerscaling_constraint, + self.data.stellarator.powerht_constraint, + self.data.stellarator.powerscaling_constraint, ) = power_at_ignition_point( - stellarator_variables.max_gyrotron_frequency, - stellarator_variables.te0_ecrh_achievable, + self.data.stellarator.max_gyrotron_frequency, + self.data.stellarator.te0_ecrh_achievable, ) - stellarator_variables.first_call = False + self.data.stellarator.first_call = False def st_new_config(self): """ @@ -202,15 +201,15 @@ def st_new_config(self): To clarify the coils scaling factor: Coil aspect ratio factor can be described with the reversed equation (so if we would know r_coil_minor) - stellarator_variables.f_coil_aspect = ( - (physics_variables.rmajor / stellarator_variables.r_coil_minor) / + self.data.stellarator.f_coil_aspect = ( + (physics_variables.rmajor / self.data.stellarator.r_coil_minor) / (stellarator_configuration.stella_config_rmajor_ref / stellarator_configuration.stella_config_coil_rminor) ) """ load_stellarator_config( - stellarator_variables.istell, + self.data.stellarator.istell, Path(f"{global_variables.output_prefix}stella_conf.json"), ) @@ -228,41 +227,41 @@ def st_new_config(self): * stellarator_configuration.stella_config_symmetry ) # This overwrites tfcoil_variables.n_tf_coils in input file. - stellarator_variables.f_st_rmajor = ( + self.data.stellarator.f_st_rmajor = ( physics_variables.rmajor / stellarator_configuration.stella_config_rmajor_ref ) # Size scaling factor with respect to the reference calculation - stellarator_variables.f_st_rminor = ( + self.data.stellarator.f_st_rminor = ( physics_variables.rminor / stellarator_configuration.stella_config_rminor_ref ) # Size scaling factor with respect to the reference calculation - stellarator_variables.f_st_aspect = ( + self.data.stellarator.f_st_aspect = ( physics_variables.aspect / stellarator_configuration.stella_config_aspect_ref ) - stellarator_variables.f_st_n_coils = tfcoil_variables.n_tf_coils / ( + self.data.stellarator.f_st_n_coils = tfcoil_variables.n_tf_coils / ( stellarator_configuration.stella_config_coilspermodule * stellarator_configuration.stella_config_symmetry ) # Coil number factor - stellarator_variables.f_st_b = ( + self.data.stellarator.f_st_b = ( physics_variables.b_plasma_toroidal_on_axis / stellarator_configuration.stella_config_bt_ref ) # B-field scaling factor # Coil aspect ratio factor to the reference calculation (we use it to scale the coil minor radius) - stellarator_variables.f_coil_aspect = stellarator_variables.f_st_coil_aspect + self.data.stellarator.f_coil_aspect = self.data.stellarator.f_st_coil_aspect # Coil major radius, scaled with respect to the reference calculation - stellarator_variables.r_coil_major = ( + self.data.stellarator.r_coil_major = ( stellarator_configuration.stella_config_coil_rmajor - * stellarator_variables.f_st_rmajor + * self.data.stellarator.f_st_rmajor ) # Coil minor radius, scaled with respect to the reference calculation - stellarator_variables.r_coil_minor = ( + self.data.stellarator.r_coil_minor = ( stellarator_configuration.stella_config_coil_rminor - * stellarator_variables.f_st_rmajor - / stellarator_variables.f_coil_aspect + * self.data.stellarator.f_st_rmajor + / self.data.stellarator.f_coil_aspect ) - stellarator_variables.f_coil_shape = ( + self.data.stellarator.f_coil_shape = ( stellarator_configuration.stella_config_min_plasma_coil_distance + stellarator_configuration.stella_config_rminor_ref ) / stellarator_configuration.stella_config_coil_rminor @@ -286,15 +285,15 @@ def st_geom(self): """ physics_variables.vol_plasma = ( - stellarator_variables.f_st_rmajor - * stellarator_variables.f_st_rminor**2 + self.data.stellarator.f_st_rmajor + * self.data.stellarator.f_st_rminor**2 * stellarator_configuration.stella_config_vol_plasma ) # Plasma surface scaled from effective parameter: physics_variables.a_plasma_surface = ( - stellarator_variables.f_st_rmajor - * stellarator_variables.f_st_rminor + self.data.stellarator.f_st_rmajor + * self.data.stellarator.f_st_rminor * stellarator_configuration.stella_config_plasma_surface ) @@ -349,9 +348,9 @@ def st_strc(self, output): intercoil_surface = ( stellarator_configuration.stella_config_coilsurface - * stellarator_variables.f_st_rmajor + * self.data.stellarator.f_st_rmajor * ( - stellarator_variables.r_coil_minor + self.data.stellarator.r_coil_minor / stellarator_configuration.stella_config_coil_rminor ) - tfcoil_variables.dx_tf_inboard_out_toroidal @@ -1993,7 +1992,7 @@ def st_phys(self, output): physics_variables.rminor * physics_variables.b_plasma_toroidal_on_axis / physics_variables.rmajor - * stellarator_variables.iotabar + * self.data.stellarator.iotabar ) # Perform auxiliary power calculations @@ -2206,10 +2205,10 @@ def st_phys(self, output): # is not taken care of by the rad module. We restrict the radiation power here by the heating power: physics_variables.p_plasma_rad_mw = max(0.0e0, physics_variables.p_plasma_rad_mw) - # Power to divertor, = (1-stellarator_variables.f_rad)*Psol + # Power to divertor, = (1-self.data.stellarator.f_rad)*Psol # The SOL radiation needs to be smaller than the physics_variables.p_plasma_rad_mw - physics_variables.psolradmw = stellarator_variables.f_rad * powht + physics_variables.psolradmw = self.data.stellarator.f_rad * powht physics_variables.p_plasma_separatrix_mw = powht - physics_variables.psolradmw # Add SOL Radiation to total @@ -2267,7 +2266,7 @@ def st_phys(self, output): # Calculate transport losses and energy confinement time using the # chosen scaling law - # N.B. stellarator_variables.iotabar replaces tokamak physics_variables.q95 in argument list + # N.B. self.data.stellarator.iotabar replaces tokamak physics_variables.q95 in argument list ( physics_variables.pden_electron_transport_loss_mw, @@ -2298,7 +2297,7 @@ def st_phys(self, output): physics_variables.rminor, physics_variables.temp_plasma_electron_density_weighted_kev, physics_variables.temp_plasma_ion_density_weighted_kev, - stellarator_variables.iotabar, + self.data.stellarator.iotabar, physics_variables.qstar, physics_variables.vol_plasma, physics_variables.n_charge_plasma_effective_vol_avg, diff --git a/tests/unit/models/stellarator/test_stellarator.py b/tests/unit/models/stellarator/test_stellarator.py index c6e9af3006..3748536b6f 100644 --- a/tests/unit/models/stellarator/test_stellarator.py +++ b/tests/unit/models/stellarator/test_stellarator.py @@ -7,7 +7,6 @@ impurity_radiation_module, physics_variables, stellarator_configuration, - stellarator_variables, tfcoil_variables, ) from process.models.stellarator.build import st_build @@ -160,9 +159,13 @@ def test_stgeom(stgeomparam, monkeypatch, stellarator): stgeomparam.stella_config_plasma_surface, ) - monkeypatch.setattr(stellarator_variables, "f_st_rmajor", stgeomparam.f_st_rmajor) + monkeypatch.setattr( + stellarator.data.stellarator, "f_st_rmajor", stgeomparam.f_st_rmajor + ) - monkeypatch.setattr(stellarator_variables, "f_st_rminor", stgeomparam.f_st_rminor) + monkeypatch.setattr( + stellarator.data.stellarator, "f_st_rminor", stgeomparam.f_st_rminor + ) stellarator.st_geom() @@ -652,7 +655,7 @@ def test_stbild(stbildparam, monkeypatch, stellarator): ) monkeypatch.setattr( - stellarator_variables, + stellarator.data.stellarator, "r_coil_minor", ( stbildparam.stella_config_min_plasma_coil_distance @@ -661,13 +664,19 @@ def test_stbild(stbildparam, monkeypatch, stellarator): * stbildparam.f_st_rminor, ) - monkeypatch.setattr(stellarator_variables, "f_st_rmajor", stbildparam.f_st_rmajor) + monkeypatch.setattr( + stellarator.data.stellarator, "f_st_rmajor", stbildparam.f_st_rmajor + ) - monkeypatch.setattr(stellarator_variables, "f_st_aspect", stbildparam.f_st_aspect) + monkeypatch.setattr( + stellarator.data.stellarator, "f_st_aspect", stbildparam.f_st_aspect + ) - monkeypatch.setattr(stellarator_variables, "f_st_rminor", stbildparam.f_st_rminor) + monkeypatch.setattr( + stellarator.data.stellarator, "f_st_rminor", stbildparam.f_st_rminor + ) - monkeypatch.setattr(stellarator_variables, "f_coil_shape", 1.0) + monkeypatch.setattr(stellarator.data.stellarator, "f_coil_shape", 1.0) st_build(stellarator, False, stellarator.data) @@ -891,7 +900,7 @@ def test_ststrc(ststrcparam, monkeypatch, stellarator): ) monkeypatch.setattr( - stellarator_variables, + stellarator.data.stellarator, "r_coil_minor", ststrcparam.f_st_rmajor, ) @@ -908,11 +917,15 @@ def test_ststrc(ststrcparam, monkeypatch, stellarator): 1, ) - monkeypatch.setattr(stellarator_variables, "f_st_n_coils", ststrcparam.f_st_n_coils) + monkeypatch.setattr( + stellarator.data.stellarator, "f_st_n_coils", ststrcparam.f_st_n_coils + ) - monkeypatch.setattr(stellarator_variables, "f_st_rmajor", ststrcparam.f_st_rmajor) + monkeypatch.setattr( + stellarator.data.stellarator, "f_st_rmajor", ststrcparam.f_st_rmajor + ) - monkeypatch.setattr(stellarator_variables, "f_st_b", ststrcparam.f_st_b) + monkeypatch.setattr(stellarator.data.stellarator, "f_st_b", ststrcparam.f_st_b) stellarator.st_strc(False) @@ -2109,7 +2122,7 @@ def test_st_calc_eff_chi(stcalceffchiparam, monkeypatch, stellarator): ) monkeypatch.setattr( - stellarator_variables, "f_st_rmajor", stcalceffchiparam.f_st_rmajor + stellarator.data.stellarator, "f_st_rmajor", stcalceffchiparam.f_st_rmajor ) output = stellarator.neoclassics.st_calc_eff_chi() From ce1834334ed8e1511591705f21d668a7f8868879 Mon Sep 17 00:00:00 2001 From: Clair Mould <86794332+clmould@users.noreply.github.com> Date: Fri, 15 May 2026 17:03:24 +0100 Subject: [PATCH 2/3] stellarator config dataclass --- process/core/model.py | 2 + .../stellarator_configuration.py | 173 ++++++++---------- process/models/stellarator/build.py | 10 +- process/models/stellarator/coils/calculate.py | 50 ++--- process/models/stellarator/coils/coils.py | 15 +- process/models/stellarator/coils/forces.py | 45 +++-- process/models/stellarator/neoclassics.py | 11 +- process/models/stellarator/preset_config.py | 8 +- process/models/stellarator/stellarator.py | 49 ++--- .../models/stellarator/test_stellarator.py | 26 +-- 10 files changed, 185 insertions(+), 204 deletions(-) diff --git a/process/core/model.py b/process/core/model.py index 77b480f3d9..1f7b03db92 100644 --- a/process/core/model.py +++ b/process/core/model.py @@ -21,6 +21,7 @@ from process.data_structure.primary_pumping_variables import PrimaryPumpingData from process.data_structure.pulse_variables import PulseData from process.data_structure.reinke_variables import ReinkeData +from process.data_structure.stellarator_configuration import StellaratorConfigData from process.data_structure.stellarator_variables import StellaratorData from process.data_structure.structure_variables import StructureData from process.data_structure.times_variables import TimesData @@ -57,6 +58,7 @@ class DataStructure: pf_coil: PFCoilData = initialise_later power: PowerData = initialise_later stellarator: StellaratorData = initialise_later + stellarator_config: StellaratorConfigData = initialise_later def __post_init__(self): for f in fields(self): diff --git a/process/data_structure/stellarator_configuration.py b/process/data_structure/stellarator_configuration.py index bb32a35c57..bf81a0f4be 100644 --- a/process/data_structure/stellarator_configuration.py +++ b/process/data_structure/stellarator_configuration.py @@ -1,137 +1,112 @@ -stella_config_name: str = None -"""Name of the configuration""" +from dataclasses import dataclass -stella_config_symmetry: int = None -"""Number of coils [1]""" +@dataclass +class StellaratorConfigData: + stella_config_name: str = None + """Name of the configuration""" -stella_config_coilspermodule: int = None -"""Coils per module [1]""" + stella_config_symmetry: int = None + """Number of coils [1]""" + stella_config_coilspermodule: int = None + """Coils per module [1]""" -stella_config_rmajor_ref: float = None -"""Reference Point for major radius where all the other variables are determined [m]""" + stella_config_rmajor_ref: float = None + """Reference Point for major radius where all the other variables are determined [m]""" + stella_config_rminor_ref: float = None + """Reference Point for minor radius where all the other variables are determined [m]""" -stella_config_rminor_ref: float = None -"""Reference Point for minor radius where all the other variables are determined [m]""" + stella_config_coil_rmajor: float = None + """Reference Point for coil major radius [m]""" + stella_config_coil_rminor: float = None + """Reference Point for coil minor radius [m]""" -stella_config_coil_rmajor: float = None -"""Reference Point for coil major radius [m]""" + stella_config_aspect_ref: float = None + """Reference Point for aspect ratio where all the other variables are determined [1]""" + stella_config_bt_ref: float = None + """Reference Point for toroidal b where all the other variables are determined [T]""" -stella_config_coil_rminor: float = None -"""Reference Point for coil minor radius [m]""" + stella_config_wp_area: float = None + """Winding pack area at the reference point [m^2]""" + stella_config_wp_bmax: float = None + """The maximal magnetic field in the winding pack at the reference size of the winding pack [T]""" -stella_config_aspect_ref: float = None -"""Reference Point for aspect ratio where all the other variables are determined [1]""" + stella_config_i0: float = None + """Coil current needed for b0 at the reference point [MA]""" + stella_config_a1: float = None + """Magnetic field fit parameter a1 (for the maximal field on the coils) [1]""" -stella_config_bt_ref: float = None -"""Reference Point for toroidal b where all the other variables are determined [T]""" + stella_config_a2: float = None + """Magnetic field fit parameter a2 [1]""" + stella_config_dmin: float = None + """Minimal intercoil distance at the reference point [m]""" -stella_config_wp_area: float = None -"""Winding pack area at the reference point [m^2]""" + stella_config_inductance: float = None + """inductance at the reference point [H]""" + stella_config_coilsurface: float = None + """Coil surface at the reference point [m2]""" -stella_config_wp_bmax: float = None -"""The maximal magnetic field in the winding pack at the reference size of the winding pack [T]""" + stella_config_coillength: float = None + """Total coil length at the reference point [m]""" + stella_config_max_portsize_width: float = None + """Port size in toroidal direction at the reference point [m]""" -stella_config_i0: float = None -"""Coil current needed for b0 at the reference point [MA]""" + stella_config_maximal_coil_height: float = None + """The maximal coil height at reference point. [m]""" + stella_config_min_plasma_coil_distance: float = None + """The minimal distance between coil and plasma at the reference point [m]""" -stella_config_a1: float = None -"""Magnetic field fit parameter a1 (for the maximal field on the coils) [1]""" + stella_config_derivative_min_lcfs_coils_dist: float = None + """The derivative of min_plasma_coil_distance wrt to the minor plasma radius at the reference point [1]""" + stella_config_vol_plasma: float = None + """The plasma volume at the reference point. Scales as a*R^2. [m^3]""" -stella_config_a2: float = None -"""Magnetic field fit parameter a2 [1]""" + stella_config_plasma_surface: float = None + """The plasma surface a the reference point. [m^2]""" + stella_config_wp_ratio: float = None + """Ratio radial to toroidal length of the winding pack. (a1 and a2 should be calculated using this value) [1]""" -stella_config_dmin: float = None -"""Minimal intercoil distance at the reference point [m]""" + stella_config_max_force_density: float = None + """Maximal toroidal and radially averaged force density at reference point in a WP cross section [MN/m^3]""" + stella_config_max_force_density_mnm: float = None + """Maximal integrated force density at reference point in a WP cross section [MN/m]""" -stella_config_inductance: float = None -"""inductance at the reference point [H]""" + stella_config_min_bend_radius: float = None + """Minimal bending radius at reference point [m]""" + stella_config_epseff: float = None + """Maximal epsilon effective in the core region [1]""" -stella_config_coilsurface: float = None -"""Coil surface at the reference point [m2]""" + stella_config_max_lateral_force_density: float = None + """Maximal lateral force density of the coil set [MN/m]""" + stella_config_max_radial_force_density: float = None + """Maximal radial force density of the coil set [MN/m]""" -stella_config_coillength: float = None -"""Total coil length at the reference point [m]""" + stella_config_centering_force_max_mn: float = None + """Maximal centering force of a coil in the coil set [MN]""" + stella_config_centering_force_min_mn: float = None + """Minimal centering force of a coil in the coil set (negative means pointing outwards) [MN]""" -stella_config_max_portsize_width: float = None -"""Port size in toroidal direction at the reference point [m]""" + stella_config_centering_force_avg_mn: float = None + """Average centering force the coils in the coil set [MN/coil]""" + stella_config_neutron_peakfactor: float = None + """The neutron peaking factor determined through inhomogeneities on the stellarator wall (qmax/qavg) [1]""" -stella_config_maximal_coil_height: float = None -"""The maximal coil height at reference point. [m]""" - -stella_config_min_plasma_coil_distance: float = None -"""The minimal distance between coil and plasma at the reference point [m]""" - - -stella_config_derivative_min_lcfs_coils_dist: float = None -"""The derivative of min_plasma_coil_distance wrt to the minor plasma radius at the reference point [1]""" - - -stella_config_vol_plasma: float = None -"""The plasma volume at the reference point. Scales as a*R^2. [m^3]""" - - -stella_config_plasma_surface: float = None -"""The plasma surface a the reference point. [m^2]""" - - -stella_config_wp_ratio: float = None -"""Ratio radial to toroidal length of the winding pack. (a1 and a2 should be calculated using this value) [1]""" - - -stella_config_max_force_density: float = None -"""Maximal toroidal and radially averaged force density at reference point in a WP cross section [MN/m^3]""" - - -stella_config_max_force_density_mnm: float = None -"""Maximal integrated force density at reference point in a WP cross section [MN/m]""" - - -stella_config_min_bend_radius: float = None -"""Minimal bending radius at reference point [m]""" - - -stella_config_epseff: float = None -"""Maximal epsilon effective in the core region [1]""" - - -stella_config_max_lateral_force_density: float = None -"""Maximal lateral force density of the coil set [MN/m]""" - - -stella_config_max_radial_force_density: float = None -"""Maximal radial force density of the coil set [MN/m]""" - - -stella_config_centering_force_max_mn: float = None -"""Maximal centering force of a coil in the coil set [MN]""" - - -stella_config_centering_force_min_mn: float = None -"""Minimal centering force of a coil in the coil set (negative means pointing outwards) [MN]""" - - -stella_config_centering_force_avg_mn: float = None -"""Average centering force the coils in the coil set [MN/coil]""" - - -stella_config_neutron_peakfactor: float = None -"""The neutron peaking factor determined through inhomogeneities on the stellarator wall (qmax/qavg) [1]""" +CREATE_DICTS_FROM_DATACLASS = StellaratorConfigData diff --git a/process/models/stellarator/build.py b/process/models/stellarator/build.py index d49bc5ff1d..64c6087cac 100644 --- a/process/models/stellarator/build.py +++ b/process/models/stellarator/build.py @@ -1,9 +1,6 @@ from process.core import process_output as po from process.core.model import DataStructure -from process.data_structure import ( - physics_variables, - stellarator_configuration, -) +from process.data_structure import physics_variables def st_build(stellarator, f_output: bool, data: DataStructure): @@ -92,10 +89,9 @@ def st_build(stellarator, f_output: bool, data: DataStructure): data.stellarator.r_coil_minor * data.stellarator.f_coil_shape - physics_variables.rminor ) - +stellarator_configuration.stella_config_derivative_min_lcfs_coils_dist * ( + +data.stellarator_config.stella_config_derivative_min_lcfs_coils_dist * ( physics_variables.rminor - - data.stellarator.f_st_rmajor - * stellarator_configuration.stella_config_rminor_ref + - data.stellarator.f_st_rmajor * data.stellarator_config.stella_config_rminor_ref ) # Radius to inner edge of inboard shield diff --git a/process/models/stellarator/coils/calculate.py b/process/models/stellarator/coils/calculate.py index b4797438a6..4c99264caf 100644 --- a/process/models/stellarator/coils/calculate.py +++ b/process/models/stellarator/coils/calculate.py @@ -5,7 +5,6 @@ from process.core.model import DataStructure from process.data_structure import ( rebco_variables, - stellarator_configuration, tfcoil_variables, ) from process.models.stellarator.coils import forces @@ -74,7 +73,7 @@ def st_coil(stellarator, output: bool, data: DataStructure): calculate_plasma_facing_coil_area() - coil_coil_gap, _ = calculate_coil_coil_toroidal_gap(r_coil_major, r_coil_minor) + coil_coil_gap, _ = calculate_coil_coil_toroidal_gap(r_coil_major, r_coil_minor, data) calculate_coils_summary_variables(coilcurrent, r_coil_major, r_coil_minor, awp_rad) @@ -84,24 +83,24 @@ def st_coil(stellarator, output: bool, data: DataStructure): # Coil dimensions data.build.z_tf_inside_half = ( 0.5e0 - * stellarator_configuration.stella_config_maximal_coil_height - * (r_coil_minor / stellarator_configuration.stella_config_coil_rminor) + * data.stellarator_config.stella_config_maximal_coil_height + * (r_coil_minor / data.stellarator_config.stella_config_coil_rminor) ) # [m] maximum half-height of coil # [m] estimated average length of a coil tfcoil_variables.len_tf_coil = ( - stellarator_configuration.stella_config_coillength - * (r_coil_minor / stellarator_configuration.stella_config_coil_rminor) + data.stellarator_config.stella_config_coillength + * (r_coil_minor / data.stellarator_config.stella_config_coil_rminor) / tfcoil_variables.n_tf_coils ) # [m^2] Total surface area of toroidal shells covering coils tfcoil_variables.tfcryoarea = ( - stellarator_configuration.stella_config_coilsurface + data.stellarator_config.stella_config_coilsurface * data.stellarator.f_st_rmajor * ( data.stellarator.r_coil_minor - / stellarator_configuration.stella_config_coil_rminor + / data.stellarator_config.stella_config_coil_rminor ) * 1.1e0 ) @@ -109,7 +108,7 @@ def st_coil(stellarator, output: bool, data: DataStructure): # Minimal bending radius: min_bending_radius = ( - stellarator_configuration.stella_config_min_bend_radius + data.stellarator_config.stella_config_min_bend_radius * data.stellarator.f_st_rmajor / (1.0 - tfcoil_variables.dr_tf_wp_with_insulation / (2.0 * r_coil_minor)) ) @@ -229,7 +228,7 @@ def calculate_plasma_facing_coil_area(): tfcoil_variables.tfsao = tfcoil_variables.tfsai -def calculate_coil_coil_toroidal_gap(r_coil_major, r_coil_minor): +def calculate_coil_coil_toroidal_gap(r_coil_major, r_coil_minor, data: DataStructure): """[m] Minimal distance in toroidal direction between two stellarator coils Consistency with coil width is checked in constraint equation 82 @@ -239,14 +238,17 @@ def calculate_coil_coil_toroidal_gap(r_coil_major, r_coil_minor): r_coil_minor : + data: DataStructure + data structure object + """ # [m] Toroidal gap between two coil filaments tfcoil_variables.toroidalgap = ( - stellarator_configuration.stella_config_dmin + data.stellarator_config.stella_config_dmin * (r_coil_major - r_coil_minor) / ( - stellarator_configuration.stella_config_coil_rmajor - - stellarator_configuration.stella_config_coil_rminor + data.stellarator_config.stella_config_coil_rmajor + - data.stellarator_config.stella_config_coil_rminor ) ) # Left-Over coil gap between two coils (m) @@ -299,9 +301,9 @@ def calculate_inductance(r_coil_minor, data: DataStructure): data structure object """ return ( - stellarator_configuration.stella_config_inductance + data.stellarator_config.stella_config_inductance / data.stellarator.f_st_rmajor - * (r_coil_minor / stellarator_configuration.stella_config_coil_rminor) ** 2 + * (r_coil_minor / data.stellarator_config.stella_config_coil_rminor) ** 2 * data.stellarator.f_st_n_coils**2 ) @@ -319,9 +321,9 @@ def calculate_stored_magnetic_energy(r_coil_minor, data: DataStructure): tfcoil_variables.e_tf_magnetic_stored_total_gj = ( 0.5e0 * ( - stellarator_configuration.stella_config_inductance + data.stellarator_config.stella_config_inductance / data.stellarator.f_st_rmajor - * (r_coil_minor / stellarator_configuration.stella_config_coil_rminor) ** 2 + * (r_coil_minor / data.stellarator_config.stella_config_coil_rminor) ** 2 * data.stellarator.f_st_n_coils**2 ) * (tfcoil_variables.c_tf_total / tfcoil_variables.n_tf_coils) ** 2 @@ -364,12 +366,12 @@ def calculate_current(data: DataStructure): """ coilcurrent = ( data.stellarator.f_st_b - * stellarator_configuration.stella_config_i0 + * data.stellarator_config.stella_config_i0 * data.stellarator.f_st_rmajor / data.stellarator.f_st_n_coils ) data.stellarator.f_st_i_total = ( - coilcurrent / stellarator_configuration.stella_config_i0 + coilcurrent / data.stellarator_config.stella_config_i0 ) return coilcurrent @@ -404,6 +406,7 @@ def winding_pack_total_size( tfcoil_variables.n_tf_coils, r_coil_major, r_coil_minor, + data, ) # Two margins can be applied for jcrit: direct or by temperature margin. # Temperature margin is implemented in the jcrit_vector definition, @@ -439,7 +442,7 @@ def winding_pack_total_size( rhs[:] = coilcurrent / ( wp_width_r**2 - / stellarator_configuration.stella_config_wp_ratio + / data.stellarator_config.stella_config_wp_ratio * fraction_area_superconductor_of_wp ) # f_a_scu_of_wp should be the fraction of the sc that is in the winding pack. @@ -464,11 +467,12 @@ def winding_pack_total_size( tfcoil_variables.n_tf_coils, r_coil_major, r_coil_minor, + data, ) # Winding pack toroidal, radial cross-sections (m) awp_tor = ( - wp_width_r_min / stellarator_configuration.stella_config_wp_ratio + wp_width_r_min / data.stellarator_config.stella_config_wp_ratio ) # Toroidal dimension awp_rad = wp_width_r_min # Radial dimension @@ -558,7 +562,7 @@ def calculate_vertical_ports(data: DataStructure): # This is simplified for now and can be made more accurate in the future# data.stellarator.vporttmax = ( 0.4e0 - * stellarator_configuration.stella_config_max_portsize_width + * data.stellarator_config.stella_config_max_portsize_width * data.stellarator.f_st_rmajor / data.stellarator.f_st_n_coils ) # This is not accurate yet. Needs more insight# @@ -574,7 +578,7 @@ def calculate_horizontal_ports(data: DataStructure): # Maximal toroidal port size (horizontal ports) (m) data.stellarator.hporttmax = ( 0.8e0 - * stellarator_configuration.stella_config_max_portsize_width + * data.stellarator_config.stella_config_max_portsize_width * data.stellarator.f_st_rmajor / data.stellarator.f_st_n_coils ) # Factor 0.8 to take the variation with height into account diff --git a/process/models/stellarator/coils/coils.py b/process/models/stellarator/coils/coils.py index 1fe177c6a4..efb400ea0a 100644 --- a/process/models/stellarator/coils/coils.py +++ b/process/models/stellarator/coils/coils.py @@ -3,9 +3,7 @@ import numpy as np from process.core.exceptions import ProcessValueError -from process.data_structure import ( - stellarator_configuration, -) +from process.core.model import DataStructure from process.models import superconductors logger = logging.getLogger(__name__) @@ -255,7 +253,9 @@ def intersect(x1, y1, x2, y2, xin): return x -def bmax_from_awp(wp_width_radial, current, n_tf_coils, r_coil_major, r_coil_minor): +def bmax_from_awp( + wp_width_radial, current, n_tf_coils, r_coil_major, r_coil_minor, data: DataStructure +): """Returns a fitted function for bmax for stellarators Returns a fitted function for bmax in dependence @@ -274,7 +274,8 @@ def bmax_from_awp(wp_width_radial, current, n_tf_coils, r_coil_major, r_coil_min r_coil_minor : - + data: DataStructure + data structure object """ return ( 2e-1 # this is mu x 1e6, to use current in MA @@ -282,7 +283,7 @@ def bmax_from_awp(wp_width_radial, current, n_tf_coils, r_coil_major, r_coil_min * n_tf_coils / (r_coil_major - r_coil_minor) * ( - stellarator_configuration.stella_config_a1 - + stellarator_configuration.stella_config_a2 * r_coil_major / wp_width_radial + data.stellarator_config.stella_config_a1 + + data.stellarator_config.stella_config_a2 * r_coil_major / wp_width_radial ) ) diff --git a/process/models/stellarator/coils/forces.py b/process/models/stellarator/coils/forces.py index b308f78731..9ed801c0d4 100644 --- a/process/models/stellarator/coils/forces.py +++ b/process/models/stellarator/coils/forces.py @@ -1,10 +1,7 @@ """Module for coil force calculations in stellarators.""" from process.core.model import DataStructure -from process.data_structure import ( - stellarator_configuration, - tfcoil_variables, -) +from process.data_structure import tfcoil_variables def calculate_max_force_density(a_tf_wp_no_insulation, data: DataStructure): @@ -18,12 +15,12 @@ def calculate_max_force_density(a_tf_wp_no_insulation, data: DataStructure): data structure object """ tfcoil_variables.max_force_density = ( - stellarator_configuration.stella_config_max_force_density + data.stellarator_config.stella_config_max_force_density * data.stellarator.f_st_i_total / data.stellarator.f_st_n_coils * tfcoil_variables.b_tf_inboard_peak_symmetric - / stellarator_configuration.stella_config_wp_bmax - * stellarator_configuration.stella_config_wp_area + / data.stellarator_config.stella_config_wp_bmax + * data.stellarator_config.stella_config_wp_area / a_tf_wp_no_insulation ) @@ -31,11 +28,11 @@ def calculate_max_force_density(a_tf_wp_no_insulation, data: DataStructure): def calculate_max_force_density_mnm(data: DataStructure): """Calculate the maximum force per meter in the TF coil winding pack from scaling. [MN/m]""" return ( - stellarator_configuration.stella_config_max_force_density_mnm + data.stellarator_config.stella_config_max_force_density_mnm * data.stellarator.f_st_i_total / data.stellarator.f_st_n_coils * tfcoil_variables.b_tf_inboard_peak_symmetric - / stellarator_configuration.stella_config_wp_bmax + / data.stellarator_config.stella_config_wp_bmax ) @@ -59,12 +56,12 @@ def calculate_max_lateral_force_density(a_tf_wp_no_insulation, data: DataStructu data structure object """ return ( - stellarator_configuration.stella_config_max_lateral_force_density + data.stellarator_config.stella_config_max_lateral_force_density * data.stellarator.f_st_i_total / data.stellarator.f_st_n_coils * tfcoil_variables.b_tf_inboard_peak_symmetric - / stellarator_configuration.stella_config_wp_bmax - * stellarator_configuration.stella_config_wp_area + / data.stellarator_config.stella_config_wp_bmax + * data.stellarator_config.stella_config_wp_area / a_tf_wp_no_insulation ) @@ -80,12 +77,12 @@ def calculate_max_radial_force_density(a_tf_wp_no_insulation, data): data structure object """ return ( - stellarator_configuration.stella_config_max_radial_force_density + data.stellarator_config.stella_config_max_radial_force_density * data.stellarator.f_st_i_total / data.stellarator.f_st_n_coils * tfcoil_variables.b_tf_inboard_peak_symmetric - / stellarator_configuration.stella_config_wp_bmax - * stellarator_configuration.stella_config_wp_area + / data.stellarator_config.stella_config_wp_bmax + * data.stellarator_config.stella_config_wp_area / a_tf_wp_no_insulation ) @@ -93,12 +90,12 @@ def calculate_max_radial_force_density(a_tf_wp_no_insulation, data): def calculate_centering_force_max_mn(data: DataStructure): """Calculate the maximum centering force in the TF coils from scaling. [MN]""" return ( - stellarator_configuration.stella_config_centering_force_max_mn + data.stellarator_config.stella_config_centering_force_max_mn * data.stellarator.f_st_i_total / data.stellarator.f_st_n_coils * tfcoil_variables.b_tf_inboard_peak_symmetric - / stellarator_configuration.stella_config_wp_bmax - * stellarator_configuration.stella_config_coillength + / data.stellarator_config.stella_config_wp_bmax + * data.stellarator_config.stella_config_coillength / tfcoil_variables.n_tf_coils / tfcoil_variables.len_tf_coil ) @@ -107,12 +104,12 @@ def calculate_centering_force_max_mn(data: DataStructure): def calculate_centering_force_min_mn(data: DataStructure): """Calculate the minimum centering force in the TF coils from scaling. [MN]""" return ( - stellarator_configuration.stella_config_centering_force_min_mn + data.stellarator_config.stella_config_centering_force_min_mn * data.stellarator.f_st_i_total / data.stellarator.f_st_n_coils * tfcoil_variables.b_tf_inboard_peak_symmetric - / stellarator_configuration.stella_config_wp_bmax - * stellarator_configuration.stella_config_coillength + / data.stellarator_config.stella_config_wp_bmax + * data.stellarator_config.stella_config_coillength / tfcoil_variables.n_tf_coils / tfcoil_variables.len_tf_coil ) @@ -121,12 +118,12 @@ def calculate_centering_force_min_mn(data: DataStructure): def calculate_centering_force_avg_mn(data: DataStructure): """Calculate the average centering force in the TF coils from scaling. [MN]""" return ( - stellarator_configuration.stella_config_centering_force_avg_mn + data.stellarator_config.stella_config_centering_force_avg_mn * data.stellarator.f_st_i_total / data.stellarator.f_st_n_coils * tfcoil_variables.b_tf_inboard_peak_symmetric - / stellarator_configuration.stella_config_wp_bmax - * stellarator_configuration.stella_config_coillength + / data.stellarator_config.stella_config_wp_bmax + * data.stellarator_config.stella_config_coillength / tfcoil_variables.n_tf_coils / tfcoil_variables.len_tf_coil ) diff --git a/process/models/stellarator/neoclassics.py b/process/models/stellarator/neoclassics.py index ab80137dd2..99644fd72c 100644 --- a/process/models/stellarator/neoclassics.py +++ b/process/models/stellarator/neoclassics.py @@ -8,7 +8,6 @@ impurity_radiation_module, neoclassics_variables, physics_variables, - stellarator_configuration, ) from process.models.stellarator.stellarator import KEV @@ -281,13 +280,13 @@ def init_profile_values_from_PROCESS(self, rho): return dens, temp, dr_dens, dr_temp def calc_neoclassics(self): - if stellarator_configuration.stella_config_epseff < 0: + if self.data.stellarator_config.stella_config_epseff < 0: logger.error( - f"epseff value lower than 0: {stellarator_configuration.stella_config_epseff}" + f"epseff value lower than 0: {self.data.stellarator_config.stella_config_epseff}" ) self.init_neoclassics( 0.6, - stellarator_configuration.stella_config_epseff, + self.data.stellarator_config.stella_config_epseff, self.data.stellarator.iotabar, ) @@ -791,7 +790,7 @@ def st_calc_eff_chi(self): * ( impurity_radiation_module.radius_plasma_core_norm * physics_variables.rminor - / stellarator_configuration.stella_config_rminor_ref + / self.data.stellarator_config.stella_config_rminor_ref ) ** 2 ) @@ -801,7 +800,7 @@ def st_calc_eff_chi(self): * ( impurity_radiation_module.radius_plasma_core_norm * physics_variables.rminor - / stellarator_configuration.stella_config_rminor_ref + / self.data.stellarator_config.stella_config_rminor_ref ) ) diff --git a/process/models/stellarator/preset_config.py b/process/models/stellarator/preset_config.py index 242996e2f3..88ee842965 100644 --- a/process/models/stellarator/preset_config.py +++ b/process/models/stellarator/preset_config.py @@ -2,7 +2,7 @@ from pathlib import Path from process.core.exceptions import ProcessValueError -from process.data_structure import stellarator_configuration +from process.core.model import DataStructure HELIAS5B = { "name": "Helias 5b", @@ -209,7 +209,7 @@ } -def load_stellarator_config(istell: int, config_file: Path | None): +def load_stellarator_config(istell: int, config_file: Path | None, data: DataStructure): """Load the appropriate Stellarator machine configuration Parameters @@ -223,6 +223,8 @@ def load_stellarator_config(istell: int, config_file: Path | None): istell = 6: Init from json config_file: + data: DataStructure + data structure object """ match istell: @@ -247,7 +249,7 @@ def load_stellarator_config(istell: int, config_file: Path | None): for variable_name, variable_value in machine_config.items(): setattr( - stellarator_configuration, + data.stellarator_config, f"stella_config_{variable_name.lower()}", variable_value, ) diff --git a/process/models/stellarator/stellarator.py b/process/models/stellarator/stellarator.py index 66509d9b3e..d2dd447170 100644 --- a/process/models/stellarator/stellarator.py +++ b/process/models/stellarator/stellarator.py @@ -17,7 +17,6 @@ global_variables, numerics, physics_variables, - stellarator_configuration, tfcoil_variables, ) from process.models.physics.physics import Physics, rether @@ -203,47 +202,53 @@ def st_new_config(self): Coil aspect ratio factor can be described with the reversed equation (so if we would know r_coil_minor) self.data.stellarator.f_coil_aspect = ( (physics_variables.rmajor / self.data.stellarator.r_coil_minor) / - (stellarator_configuration.stella_config_rmajor_ref / - stellarator_configuration.stella_config_coil_rminor) + (self.data.stellarator_config.stella_config_rmajor_ref / + self.data.stellarator_config.stella_config_coil_rminor) ) """ load_stellarator_config( self.data.stellarator.istell, Path(f"{global_variables.output_prefix}stella_conf.json"), + self.data, ) # If physics_variables.aspect ratio is not in numerics.ixc set it to default value # Or when you call it the first time if 1 not in numerics.ixc: - physics_variables.aspect = stellarator_configuration.stella_config_aspect_ref + physics_variables.aspect = ( + self.data.stellarator_config.stella_config_aspect_ref + ) # Set the physics_variables.rminor radius as result here. physics_variables.rminor = physics_variables.rmajor / physics_variables.aspect physics_variables.eps = 1.0e0 / physics_variables.aspect tfcoil_variables.n_tf_coils = ( - stellarator_configuration.stella_config_coilspermodule - * stellarator_configuration.stella_config_symmetry + self.data.stellarator_config.stella_config_coilspermodule + * self.data.stellarator_config.stella_config_symmetry ) # This overwrites tfcoil_variables.n_tf_coils in input file. self.data.stellarator.f_st_rmajor = ( - physics_variables.rmajor / stellarator_configuration.stella_config_rmajor_ref + physics_variables.rmajor + / self.data.stellarator_config.stella_config_rmajor_ref ) # Size scaling factor with respect to the reference calculation self.data.stellarator.f_st_rminor = ( - physics_variables.rminor / stellarator_configuration.stella_config_rminor_ref + physics_variables.rminor + / self.data.stellarator_config.stella_config_rminor_ref ) # Size scaling factor with respect to the reference calculation self.data.stellarator.f_st_aspect = ( - physics_variables.aspect / stellarator_configuration.stella_config_aspect_ref + physics_variables.aspect + / self.data.stellarator_config.stella_config_aspect_ref ) self.data.stellarator.f_st_n_coils = tfcoil_variables.n_tf_coils / ( - stellarator_configuration.stella_config_coilspermodule - * stellarator_configuration.stella_config_symmetry + self.data.stellarator_config.stella_config_coilspermodule + * self.data.stellarator_config.stella_config_symmetry ) # Coil number factor self.data.stellarator.f_st_b = ( physics_variables.b_plasma_toroidal_on_axis - / stellarator_configuration.stella_config_bt_ref + / self.data.stellarator_config.stella_config_bt_ref ) # B-field scaling factor # Coil aspect ratio factor to the reference calculation (we use it to scale the coil minor radius) @@ -251,20 +256,20 @@ def st_new_config(self): # Coil major radius, scaled with respect to the reference calculation self.data.stellarator.r_coil_major = ( - stellarator_configuration.stella_config_coil_rmajor + self.data.stellarator_config.stella_config_coil_rmajor * self.data.stellarator.f_st_rmajor ) # Coil minor radius, scaled with respect to the reference calculation self.data.stellarator.r_coil_minor = ( - stellarator_configuration.stella_config_coil_rminor + self.data.stellarator_config.stella_config_coil_rminor * self.data.stellarator.f_st_rmajor / self.data.stellarator.f_coil_aspect ) self.data.stellarator.f_coil_shape = ( - stellarator_configuration.stella_config_min_plasma_coil_distance - + stellarator_configuration.stella_config_rminor_ref - ) / stellarator_configuration.stella_config_coil_rminor + self.data.stellarator_config.stella_config_min_plasma_coil_distance + + self.data.stellarator_config.stella_config_rminor_ref + ) / self.data.stellarator_config.stella_config_coil_rminor def st_geom(self): """ @@ -287,14 +292,14 @@ def st_geom(self): physics_variables.vol_plasma = ( self.data.stellarator.f_st_rmajor * self.data.stellarator.f_st_rminor**2 - * stellarator_configuration.stella_config_vol_plasma + * self.data.stellarator_config.stella_config_vol_plasma ) # Plasma surface scaled from effective parameter: physics_variables.a_plasma_surface = ( self.data.stellarator.f_st_rmajor * self.data.stellarator.f_st_rminor - * stellarator_configuration.stella_config_plasma_surface + * self.data.stellarator_config.stella_config_plasma_surface ) # Plasma cross section area. Approximated @@ -347,11 +352,11 @@ def st_strc(self, output): # Calculate the intercoil bolted plates structure from the coil surface intercoil_surface = ( - stellarator_configuration.stella_config_coilsurface + self.data.stellarator_config.stella_config_coilsurface * self.data.stellarator.f_st_rmajor * ( self.data.stellarator.r_coil_minor - / stellarator_configuration.stella_config_coil_rminor + / self.data.stellarator_config.stella_config_coil_rminor ) - tfcoil_variables.dx_tf_inboard_out_toroidal * tfcoil_variables.len_tf_coil @@ -584,7 +589,7 @@ def st_fwbs(self, output: bool): # The peaking factor, obtained as precalculated parameter self.data.fwbs.wallpf = ( - stellarator_configuration.stella_config_neutron_peakfactor + self.data.stellarator_config.stella_config_neutron_peakfactor ) # Blanket neutronics calculations diff --git a/tests/unit/models/stellarator/test_stellarator.py b/tests/unit/models/stellarator/test_stellarator.py index 3748536b6f..15e45bebac 100644 --- a/tests/unit/models/stellarator/test_stellarator.py +++ b/tests/unit/models/stellarator/test_stellarator.py @@ -6,7 +6,6 @@ from process.data_structure import ( impurity_radiation_module, physics_variables, - stellarator_configuration, tfcoil_variables, ) from process.models.stellarator.build import st_build @@ -148,13 +147,13 @@ def test_stgeom(stgeomparam, monkeypatch, stellarator): ) monkeypatch.setattr( - stellarator_configuration, + stellarator.data.stellarator_config, "stella_config_vol_plasma", stgeomparam.stella_config_vol_plasma, ) monkeypatch.setattr( - stellarator_configuration, + stellarator.data.stellarator_config, "stella_config_plasma_surface", stgeomparam.stella_config_plasma_surface, ) @@ -637,19 +636,19 @@ def test_stbild(stbildparam, monkeypatch, stellarator): ) monkeypatch.setattr( - stellarator_configuration, + stellarator.data.stellarator_config, "stella_config_derivative_min_lcfs_coils_dist", stbildparam.stella_config_derivative_min_lcfs_coils_dist, ) monkeypatch.setattr( - stellarator_configuration, + stellarator.data.stellarator_config, "stella_config_rminor_ref", stbildparam.stella_config_rminor_ref, ) monkeypatch.setattr( - stellarator_configuration, + stellarator.data.stellarator_config, "stella_config_min_plasma_coil_distance", stbildparam.stella_config_min_plasma_coil_distance, ) @@ -882,19 +881,19 @@ def test_ststrc(ststrcparam, monkeypatch, stellarator): ) monkeypatch.setattr( - stellarator_configuration, + stellarator.data.stellarator_config, "stella_config_coilsurface", ststrcparam.stella_config_coilsurface, ) monkeypatch.setattr( - stellarator_configuration, + stellarator.data.stellarator_config, "stella_config_coillength", ststrcparam.stella_config_coillength, ) monkeypatch.setattr( - stellarator_configuration, + stellarator.data.stellarator_config, "stella_config_coil_rminor", 1.0, ) @@ -960,9 +959,9 @@ def test_j_max_protect_am2(): ) == pytest.approx(54919989.379449144) -def test_bmax_from_awp(monkeypatch): - monkeypatch.setattr(stellarator_configuration, "stella_config_a1", 0.688) - monkeypatch.setattr(stellarator_configuration, "stella_config_a2", 0.025) +def test_bmax_from_awp(stellarator, monkeypatch): + monkeypatch.setattr(stellarator.data.stellarator_config, "stella_config_a1", 0.688) + monkeypatch.setattr(stellarator.data.stellarator_config, "stella_config_a2", 0.025) assert bmax_from_awp( wp_width_radial=0.11792792792792792, @@ -970,6 +969,7 @@ def test_bmax_from_awp(monkeypatch): n_tf_coils=50, r_coil_major=22.237837837837837, r_coil_minor=4.7171171171171169, + data=stellarator.data, ) == pytest.approx(39.193416982177489) @@ -2116,7 +2116,7 @@ def test_st_calc_eff_chi(stcalceffchiparam, monkeypatch, stellarator): ) monkeypatch.setattr( - stellarator_configuration, + stellarator.data.stellarator_config, "stella_config_rminor_ref", stcalceffchiparam.stella_config_rminor_ref, ) From 8fc98467ef8589ed9a455888d665c263f8418f58 Mon Sep 17 00:00:00 2001 From: Clair Mould <86794332+clmould@users.noreply.github.com> Date: Tue, 19 May 2026 16:14:05 +0100 Subject: [PATCH 3/3] review comment chances --- .../stellarator_configuration.py | 70 +++++++++---------- .../data_structure/stellarator_variables.py | 2 +- 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/process/data_structure/stellarator_configuration.py b/process/data_structure/stellarator_configuration.py index bf81a0f4be..70a0857a41 100644 --- a/process/data_structure/stellarator_configuration.py +++ b/process/data_structure/stellarator_configuration.py @@ -3,109 +3,109 @@ @dataclass class StellaratorConfigData: - stella_config_name: str = None + stella_config_name: str = "" """Name of the configuration""" - stella_config_symmetry: int = None + stella_config_symmetry: int = 0 """Number of coils [1]""" - stella_config_coilspermodule: int = None + stella_config_coilspermodule: int = 0 """Coils per module [1]""" - stella_config_rmajor_ref: float = None + stella_config_rmajor_ref: float = 0.0 """Reference Point for major radius where all the other variables are determined [m]""" - stella_config_rminor_ref: float = None + stella_config_rminor_ref: float = 0.0 """Reference Point for minor radius where all the other variables are determined [m]""" - stella_config_coil_rmajor: float = None + stella_config_coil_rmajor: float = 0.0 """Reference Point for coil major radius [m]""" - stella_config_coil_rminor: float = None + stella_config_coil_rminor: float = 0.0 """Reference Point for coil minor radius [m]""" - stella_config_aspect_ref: float = None + stella_config_aspect_ref: float = 0.0 """Reference Point for aspect ratio where all the other variables are determined [1]""" - stella_config_bt_ref: float = None + stella_config_bt_ref: float = 0.0 """Reference Point for toroidal b where all the other variables are determined [T]""" - stella_config_wp_area: float = None + stella_config_wp_area: float = 0.0 """Winding pack area at the reference point [m^2]""" - stella_config_wp_bmax: float = None + stella_config_wp_bmax: float = 0.0 """The maximal magnetic field in the winding pack at the reference size of the winding pack [T]""" - stella_config_i0: float = None + stella_config_i0: float = 0.0 """Coil current needed for b0 at the reference point [MA]""" - stella_config_a1: float = None + stella_config_a1: float = 0.0 """Magnetic field fit parameter a1 (for the maximal field on the coils) [1]""" - stella_config_a2: float = None + stella_config_a2: float = 0.0 """Magnetic field fit parameter a2 [1]""" - stella_config_dmin: float = None + stella_config_dmin: float = 0.0 """Minimal intercoil distance at the reference point [m]""" - stella_config_inductance: float = None + stella_config_inductance: float = 0.0 """inductance at the reference point [H]""" - stella_config_coilsurface: float = None + stella_config_coilsurface: float = 0.0 """Coil surface at the reference point [m2]""" - stella_config_coillength: float = None + stella_config_coillength: float = 0.0 """Total coil length at the reference point [m]""" - stella_config_max_portsize_width: float = None + stella_config_max_portsize_width: float = 0.0 """Port size in toroidal direction at the reference point [m]""" - stella_config_maximal_coil_height: float = None + stella_config_maximal_coil_height: float = 0.0 """The maximal coil height at reference point. [m]""" - stella_config_min_plasma_coil_distance: float = None + stella_config_min_plasma_coil_distance: float = 0.0 """The minimal distance between coil and plasma at the reference point [m]""" - stella_config_derivative_min_lcfs_coils_dist: float = None + stella_config_derivative_min_lcfs_coils_dist: float = 0.0 """The derivative of min_plasma_coil_distance wrt to the minor plasma radius at the reference point [1]""" - stella_config_vol_plasma: float = None + stella_config_vol_plasma: float = 0.0 """The plasma volume at the reference point. Scales as a*R^2. [m^3]""" - stella_config_plasma_surface: float = None + stella_config_plasma_surface: float = 0.0 """The plasma surface a the reference point. [m^2]""" - stella_config_wp_ratio: float = None + stella_config_wp_ratio: float = 0.0 """Ratio radial to toroidal length of the winding pack. (a1 and a2 should be calculated using this value) [1]""" - stella_config_max_force_density: float = None + stella_config_max_force_density: float = 0.0 """Maximal toroidal and radially averaged force density at reference point in a WP cross section [MN/m^3]""" - stella_config_max_force_density_mnm: float = None + stella_config_max_force_density_mnm: float = 0.0 """Maximal integrated force density at reference point in a WP cross section [MN/m]""" - stella_config_min_bend_radius: float = None + stella_config_min_bend_radius: float = 0.0 """Minimal bending radius at reference point [m]""" - stella_config_epseff: float = None + stella_config_epseff: float = 0.0 """Maximal epsilon effective in the core region [1]""" - stella_config_max_lateral_force_density: float = None + stella_config_max_lateral_force_density: float = 0.0 """Maximal lateral force density of the coil set [MN/m]""" - stella_config_max_radial_force_density: float = None + stella_config_max_radial_force_density: float = 0.0 """Maximal radial force density of the coil set [MN/m]""" - stella_config_centering_force_max_mn: float = None + stella_config_centering_force_max_mn: float = 0.0 """Maximal centering force of a coil in the coil set [MN]""" - stella_config_centering_force_min_mn: float = None + stella_config_centering_force_min_mn: float = 0.0 """Minimal centering force of a coil in the coil set (negative means pointing outwards) [MN]""" - stella_config_centering_force_avg_mn: float = None + stella_config_centering_force_avg_mn: float = 0.0 """Average centering force the coils in the coil set [MN/coil]""" - stella_config_neutron_peakfactor: float = None + stella_config_neutron_peakfactor: float = 0.0 """The neutron peaking factor determined through inhomogeneities on the stellarator wall (qmax/qavg) [1]""" diff --git a/process/data_structure/stellarator_variables.py b/process/data_structure/stellarator_variables.py index f7fd3d5740..d74b18adb9 100644 --- a/process/data_structure/stellarator_variables.py +++ b/process/data_structure/stellarator_variables.py @@ -9,7 +9,7 @@ class StellaratorData: f_st_rmajor: float = 0.0 """Actual major radius to reference value from stella_config file""" - f_st_aspect: float = None + f_st_aspect: float = 0.0 """Actual aspect ratio to reference value from stella_config file""" f_st_coil_aspect: float = 1.0