diff --git a/process/core/init.py b/process/core/init.py index cd1c236e4..afce8204b 100644 --- a/process/core/init.py +++ b/process/core/init.py @@ -22,6 +22,7 @@ ) from process.data_structure.impurity_radiation_variables import N_IMPURITIES from process.data_structure.numerics import FiguresOfMerit, PROCESSRunMode +from process.data_structure.pfcoil_variables import PFConductorModel from process.data_structure.physics_variables import DivertorNumberModels from process.models.pfcoil import PFLocationTypes from process.models.physics.profiles import DensityProfilePedestalType @@ -978,7 +979,7 @@ def check_process(inputs, data): # noqa: ARG001 ) # PF coil resistivity is zero if superconducting - if data.pf_coil.i_pf_conductor == 0: + if data.pf_coil.i_pf_conductor == PFConductorModel.SUPERCONDUCTING: data.pf_coil.rho_pf_coil = 0.0 # If there is no NBI, then hot beam density should be zero diff --git a/process/data_structure/pfcoil_variables.py b/process/data_structure/pfcoil_variables.py index 845b6aa2d..e32f8db8f 100644 --- a/process/data_structure/pfcoil_variables.py +++ b/process/data_structure/pfcoil_variables.py @@ -1,7 +1,19 @@ from dataclasses import dataclass, field +from enum import IntEnum import numpy as np + +class PFConductorModel(IntEnum): + """Enumeration for PF conductor models. + Controlled via `i_pf_conductor` + + """ + + SUPERCONDUCTING = 0 + RESISTIVE = 1 + + N_PF_GROUPS_MAX = 10 """maximum number of groups of PF coils""" @@ -317,7 +329,7 @@ class PFCoilData: """steel case thickness for PF coil i (m)""" rho_pf_coil: float = 2.5e-8 - """PF coil resistivity (if i_pf_conductor=1) (Ohm-m)""" + """PF coil resistivity (if i_pf_conductor=1/RESISTIVE) (Ohm-m)""" rhopfbus: float = 3.93e-8 """Resistivity of CS and PF coil bus bars (irrespective of diff --git a/process/models/costs/costs.py b/process/models/costs/costs.py index 47ca87bd2..f9ca23654 100644 --- a/process/models/costs/costs.py +++ b/process/models/costs/costs.py @@ -6,6 +6,7 @@ from process.core import process_output as po from process.core.exceptions import ProcessValueError from process.core.model import Model +from process.data_structure.pfcoil_variables import PFConductorModel from process.models.tfcoil.base import TFConductorModel logger = logging.getLogger(__name__) @@ -1612,7 +1613,9 @@ def acc2222(self): # each superconducting cable (so is zero for resistive coils) costpfsh = ( - 0.0 if self.data.pf_coil.i_pf_conductor == 1 else self.data.costs.cconshpf + 0.0 + if self.data.pf_coil.i_pf_conductor == PFConductorModel.RESISTIVE + else self.data.costs.cconshpf ) # Non-Central Solenoid coils @@ -1627,7 +1630,7 @@ def acc2222(self): for i in range(npf): # Superconductor ($/m) if self.data.costs.supercond_cost_model == 0: - if self.data.pf_coil.i_pf_conductor == 0: + if self.data.pf_coil.i_pf_conductor == PFConductorModel.SUPERCONDUCTING: costpfsc = ( self.data.costs.ucsc[self.data.pf_coil.i_pf_superconductor - 1] * (1.0e0 - self.data.pf_coil.fcupfsu) @@ -1644,7 +1647,7 @@ def acc2222(self): ) else: costpfsc = 0.0e0 - elif self.data.pf_coil.i_pf_conductor == 0: + elif self.data.pf_coil.i_pf_conductor == PFConductorModel.SUPERCONDUCTING: costpfsc = ( self.data.costs.sc_mat_cost_0[ self.data.pf_coil.i_pf_superconductor - 1 @@ -1658,7 +1661,7 @@ def acc2222(self): costpfsc = 0.0 # Copper ($/m) - if self.data.pf_coil.i_pf_conductor == 0: + if self.data.pf_coil.i_pf_conductor == PFConductorModel.SUPERCONDUCTING: costpfcu = ( self.data.costs.uccu * self.data.pf_coil.fcupfsu @@ -1709,7 +1712,7 @@ def acc2222(self): # Superconductor ($/m) if self.data.costs.supercond_cost_model == 0: # Issue #328 Use CS conductor cross-sectional area (m2) - if self.data.pf_coil.i_pf_conductor == 0: + if self.data.pf_coil.i_pf_conductor == PFConductorModel.SUPERCONDUCTING: costpfsc = ( self.data.costs.ucsc[self.data.pf_coil.i_cs_superconductor - 1] * self.data.pf_coil.a_cs_cable_space @@ -1724,7 +1727,7 @@ def acc2222(self): ) else: costpfsc = 0.0e0 - elif self.data.pf_coil.i_pf_conductor == 0: + elif self.data.pf_coil.i_pf_conductor == PFConductorModel.SUPERCONDUCTING: costpfsc = ( self.data.costs.sc_mat_cost_0[ self.data.pf_coil.i_cs_superconductor - 1 @@ -1739,7 +1742,7 @@ def acc2222(self): # Copper ($/m) - if self.data.pf_coil.i_pf_conductor == 0: + if self.data.pf_coil.i_pf_conductor == PFConductorModel.SUPERCONDUCTING: costpfcu = ( self.data.costs.uccu * self.data.pf_coil.a_cs_cable_space diff --git a/process/models/pfcoil.py b/process/models/pfcoil.py index d738c4670..89c558760 100644 --- a/process/models/pfcoil.py +++ b/process/models/pfcoil.py @@ -20,6 +20,7 @@ NFIXMX, NGC2, NPTSMX, + PFConductorModel, ) from process.models import superconductors from process.models.superconductors import SuperconductorMaterial, SuperconductorModel @@ -864,7 +865,7 @@ def pfcoil(self): # Issue 1871. MDK # Allowable current density (for superconducting coils) for each coil, index i - if self.data.pf_coil.i_pf_conductor == 0: + if self.data.pf_coil.i_pf_conductor == PFConductorModel.SUPERCONDUCTING: bmax = max( abs(self.data.pf_coil.b_pf_coil_peak[i]), abs(self.data.pf_coil.bpf2[i]), @@ -910,7 +911,7 @@ def pfcoil(self): # Resistive coils - if self.data.pf_coil.i_pf_conductor == 1: + if self.data.pf_coil.i_pf_conductor == PFConductorModel.RESISTIVE: # Coil resistance (f_a_pf_coil_void is the void fraction) respf = ( @@ -937,7 +938,7 @@ def pfcoil(self): # Conductor weight (f_a_pf_coil_void is the void fraction) - if self.data.pf_coil.i_pf_conductor == 0: + if self.data.pf_coil.i_pf_conductor == PFConductorModel.SUPERCONDUCTING: self.data.pf_coil.m_pf_coil_conductor[i] = ( volpf * self.data.tfcoil.dcond[ @@ -963,7 +964,7 @@ def pfcoil(self): # Stress ==> cross-sectional area of supporting steel to use - if self.data.pf_coil.i_pf_conductor == 0: + if self.data.pf_coil.i_pf_conductor == PFConductorModel.SUPERCONDUCTING: # Superconducting coil # Updated assumptions: 500 MPa stress limit with all of the force # supported in the conduit (steel) case. @@ -2035,7 +2036,7 @@ def outpf(self): if self.data.build.iohcl == 0: op.ocmmnt(self.outfile, "No central solenoid included") op.oblnkl(self.outfile) - elif self.data.pf_coil.i_pf_conductor == 0: + elif self.data.pf_coil.i_pf_conductor == PFConductorModel.SUPERCONDUCTING: op.ocmmnt(self.outfile, "Superconducting central solenoid") op.ovarin( @@ -2330,7 +2331,7 @@ def outpf(self): op.ocmmnt(self.outfile, "----------------------------") op.oblnkl(self.outfile) - if self.data.pf_coil.i_pf_conductor == 0: + if self.data.pf_coil.i_pf_conductor == PFConductorModel.SUPERCONDUCTING: op.oblnkl(self.outfile) op.ocmmnt(self.outfile, "Superconducting PF coils") @@ -2557,7 +2558,7 @@ def outpf(self): # PF coils for k in range(self.data.pf_coil.nef): - if self.data.pf_coil.i_pf_conductor == 0: + if self.data.pf_coil.i_pf_conductor == PFConductorModel.SUPERCONDUCTING: rows.append([ f"PF {k}", f"{self.data.pf_coil.c_pf_cs_coils_peak_ma[k]:.3e}", @@ -2587,7 +2588,7 @@ def outpf(self): abs(self.data.pf_coil.j_cs_pulse_start), abs(self.data.pf_coil.j_cs_flat_top_end), ) - if self.data.pf_coil.i_pf_conductor == 0: + if self.data.pf_coil.i_pf_conductor == PFConductorModel.SUPERCONDUCTING: # Issue #328 rows.append([ "CS", @@ -3361,7 +3362,7 @@ def ohcalc(self): ) # Stress ==> cross-sectional area of supporting steel to use - if self.data.pf_coil.i_pf_conductor == 0: + if self.data.pf_coil.i_pf_conductor == PFConductorModel.SUPERCONDUCTING: # Superconducting coil # New calculation from M. N. Wilson for hoop stress @@ -3477,7 +3478,7 @@ def ohcalc(self): ) # Weight of conductor in central Solenoid - if self.data.pf_coil.i_pf_conductor == 0: + if self.data.pf_coil.i_pf_conductor == PFConductorModel.SUPERCONDUCTING: self.data.pf_coil.m_pf_coil_conductor[ self.data.pf_coil.n_cs_pf_coils - 1 ] = ( @@ -3500,7 +3501,7 @@ def ohcalc(self): * constants.den_copper ) - if self.data.pf_coil.i_pf_conductor == 0: + if self.data.pf_coil.i_pf_conductor == PFConductorModel.SUPERCONDUCTING: # Allowable coil overall current density at EOF # (superconducting coils only) diff --git a/process/models/power.py b/process/models/power.py index e807ce843..bf8e81ae3 100644 --- a/process/models/power.py +++ b/process/models/power.py @@ -12,7 +12,7 @@ from process.core.exceptions import ProcessValueError from process.core.model import Model from process.data_structure.blanket_variables import BlktModelTypes -from process.data_structure.pfcoil_variables import NGC2 +from process.data_structure.pfcoil_variables import NGC2, PFConductorModel class PumpingPowerModelTypes(IntEnum): @@ -1028,7 +1028,10 @@ def calculate_cryo_loads(self): self.data.tfcoil.cryo_cool_req = 0.0e0 # Superconductors TF/PF cryogenic cooling - if self.data.tfcoil.i_tf_sup == 1 or self.data.pf_coil.i_pf_conductor == 0: + if ( + self.data.tfcoil.i_tf_sup == 1 + or self.data.pf_coil.i_pf_conductor == PFConductorModel.SUPERCONDUCTING + ): # self.data.heat_transport.helpow calculation self.data.heat_transport.helpow = self.cryo( self.data.tfcoil.i_tf_sup, diff --git a/process/models/pulse.py b/process/models/pulse.py index 78ec3cb99..46741b8eb 100644 --- a/process/models/pulse.py +++ b/process/models/pulse.py @@ -5,6 +5,7 @@ from process.core import constants from process.core import process_output as po from process.core.model import Model +from process.data_structure.pfcoil_variables import PFConductorModel logger = logging.getLogger(__name__) @@ -67,7 +68,7 @@ def tohswg(self, output: bool): # Central Solenoid resistance (ohms) - if self.data.pf_coil.i_pf_conductor == 0: + if self.data.pf_coil.i_pf_conductor == PFConductorModel.SUPERCONDUCTING: r = 0.0e0 else: r = ( diff --git a/process/models/structure.py b/process/models/structure.py index 6a3815a47..1489b3db6 100644 --- a/process/models/structure.py +++ b/process/models/structure.py @@ -8,6 +8,7 @@ from process.core import constants from process.core import process_output as po from process.core.model import Model +from process.data_structure.pfcoil_variables import PFConductorModel logger = logging.getLogger(__name__) @@ -163,7 +164,7 @@ def structure( coldmass = 0.0e0 if i_tf_sup == 1: coldmass = coldmass + tfmass + aintmass + dewmass - if i_pf_conductor != 1: + if i_pf_conductor != PFConductorModel.RESISTIVE: coldmass += pfmass # Coil gravity support mass diff --git a/process/models/tfcoil/base.py b/process/models/tfcoil/base.py index 87be5d730..cba4e3950 100644 --- a/process/models/tfcoil/base.py +++ b/process/models/tfcoil/base.py @@ -17,6 +17,7 @@ from process.core.exceptions import ProcessValueError from process.core.model import DataStructure, Model from process.data_structure.build_variables import TFCSRadialConfiguration +from process.data_structure.pfcoil_variables import PFConductorModel from process.data_structure.physics_variables import DivertorNumberModels logger = logging.getLogger(__name__) @@ -2538,7 +2539,7 @@ def stresscl( radtf[0] = dr_bore # Superconducting CS - if i_pf_conductor == 0: + if i_pf_conductor == PFConductorModel.SUPERCONDUCTING: # Getting the turn dimention from scratch # as the TF is called before CS in caller.f90 # -# @@ -3049,7 +3050,7 @@ def stresscl( # -------------------------------- # SC central solenoid coil stress unsmearing (bucked and wedged only) # --- - if i_tf_bucking >= 2 and i_pf_conductor == 0: + if i_tf_bucking >= 2 and i_pf_conductor == PFConductorModel.SUPERCONDUCTING: # Central Solenoid (OH) steel conduit stress unsmearing factors for ii in range(n_radial_array): sig_tf_r[ii] = sig_tf_r[ii] * eyoung_cs_stiffest_leg / eyoung_axial[0] diff --git a/tests/unit/models/test_costs_1990.py b/tests/unit/models/test_costs_1990.py index 10c987c60..dccefbbcf 100644 --- a/tests/unit/models/test_costs_1990.py +++ b/tests/unit/models/test_costs_1990.py @@ -5,6 +5,7 @@ import numpy as np import pytest +from process.data_structure.pfcoil_variables import PFConductorModel from process.models.engineering.pumping import CoolantType @@ -2144,7 +2145,7 @@ class Acc2222Param(NamedTuple): supercond_cost_model=0, j_crit_str_cs=100.0, j_crit_str_pf=200.0, - i_pf_conductor=0, + i_pf_conductor=PFConductorModel.SUPERCONDUCTING, f_a_cs_void=0.29999999999999999, n_cs_pf_coils=7, n_pf_coil_turns=np.array( @@ -2340,7 +2341,7 @@ class Acc2222Param(NamedTuple): supercond_cost_model=0, j_crit_str_cs=100.0, j_crit_str_pf=200.0, - i_pf_conductor=0, + i_pf_conductor=PFConductorModel.SUPERCONDUCTING, f_a_cs_void=0.29999999999999999, n_cs_pf_coils=7, n_pf_coil_turns=np.array( @@ -2536,7 +2537,7 @@ class Acc2222Param(NamedTuple): supercond_cost_model=1, j_crit_str_cs=100.0, j_crit_str_pf=200.0, - i_pf_conductor=0, + i_pf_conductor=PFConductorModel.SUPERCONDUCTING, f_a_cs_void=0.29999999999999999, n_cs_pf_coils=7, n_pf_coil_turns=np.array( diff --git a/tests/unit/models/test_pfcoil.py b/tests/unit/models/test_pfcoil.py index 1bf393f0e..cd1cf121c 100644 --- a/tests/unit/models/test_pfcoil.py +++ b/tests/unit/models/test_pfcoil.py @@ -17,7 +17,10 @@ from numpy.testing import assert_array_almost_equal from process.core import constants -from process.data_structure.pfcoil_variables import N_PF_COILS_IN_GROUP_MAX +from process.data_structure.pfcoil_variables import ( + N_PF_COILS_IN_GROUP_MAX, + PFConductorModel, +) from process.models.pfcoil import ( CSEUDEMOTurnGeometry, CSGeometry, @@ -2483,7 +2486,9 @@ def test_pfcoil(monkeypatch, pfcoil): pfcoil.data.pf_coil, "zref", [3.6, 1.2, 2.5, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0] ) monkeypatch.setattr(pfcoil.data.pf_coil, "m_pf_coil_max", 0.0) - monkeypatch.setattr(pfcoil.data.pf_coil, "i_pf_conductor", 0) + monkeypatch.setattr( + pfcoil.data.pf_coil, "i_pf_conductor", PFConductorModel.SUPERCONDUCTING + ) monkeypatch.setattr(pfcoil.data.pf_coil, "alfapf", 5.0e-10) monkeypatch.setattr(pfcoil.data.pf_coil, "n_pf_cs_plasma_circuits", 8) monkeypatch.setattr(pfcoil.data.pf_coil, "rho_pf_coil", 2.5e-8) @@ -2593,7 +2598,9 @@ def test_ohcalc(monkeypatch, reinitialise_error_module, cs_coil): monkeypatch.setattr(cs_coil.data.pf_coil, "b_cs_peak_pulse_start", 1.4e1) monkeypatch.setattr(cs_coil.data.pf_coil, "j_cs_critical_flat_top_end", 4.070e7) monkeypatch.setattr(cs_coil.data.pf_coil, "temp_cs_superconductor_margin", 1.5) - monkeypatch.setattr(cs_coil.data.pf_coil, "i_pf_conductor", 0) + monkeypatch.setattr( + cs_coil.data.pf_coil, "i_pf_conductor", PFConductorModel.SUPERCONDUCTING + ) monkeypatch.setattr(cs_coil.data.pf_coil, "j_pf_wp_critical", np.full(22, 0.0)) monkeypatch.setattr(cs_coil.data.pf_coil, "rho_pf_coil", 2.8e-8) monkeypatch.setattr(cs_coil.data.pf_coil, "f_a_pf_coil_void", np.full(22, 0.3)) diff --git a/tests/unit/models/test_pulse.py b/tests/unit/models/test_pulse.py index 8902823d4..a8214de23 100644 --- a/tests/unit/models/test_pulse.py +++ b/tests/unit/models/test_pulse.py @@ -3,6 +3,8 @@ import numpy as np import pytest +from process.data_structure.pfcoil_variables import PFConductorModel + @pytest.fixture def pulse(process_models): @@ -59,7 +61,7 @@ class TohswgParam(NamedTuple): t_current_ramp_up_min=0, vpfskv=0, n_pf_cs_plasma_circuits=8, - i_pf_conductor=0, + i_pf_conductor=PFConductorModel.SUPERCONDUCTING, n_cs_pf_coils=7, p_cs_resistive_flat_top=0, ind_pf_cs_plasma_mutual=np.array( @@ -617,7 +619,7 @@ class TohswgParam(NamedTuple): t_current_ramp_up_min=-526.67247746645455, vpfskv=20, n_pf_cs_plasma_circuits=8, - i_pf_conductor=0, + i_pf_conductor=PFConductorModel.SUPERCONDUCTING, n_cs_pf_coils=7, p_cs_resistive_flat_top=0, ind_pf_cs_plasma_mutual=np.array( diff --git a/tests/unit/models/test_structure.py b/tests/unit/models/test_structure.py index 816ee4a62..b8353f6ad 100644 --- a/tests/unit/models/test_structure.py +++ b/tests/unit/models/test_structure.py @@ -2,6 +2,7 @@ import pytest +from process.data_structure.pfcoil_variables import PFConductorModel from process.models.structure import Structure @@ -33,7 +34,7 @@ def test_structure(structure): akappa=1.848, b0=5.3292, i_tf_sup=1, - i_pf_conductor=0, + i_pf_conductor=PFConductorModel.SUPERCONDUCTING, tf_h_width=15.337464674334223, tfhmax=9.0730900215620327, shldmass=2294873.8131476026, diff --git a/tests/unit/models/tfcoil/test_tfcoil.py b/tests/unit/models/tfcoil/test_tfcoil.py index 5df3a9f14..da98774ee 100644 --- a/tests/unit/models/tfcoil/test_tfcoil.py +++ b/tests/unit/models/tfcoil/test_tfcoil.py @@ -11,6 +11,7 @@ import process.models.tfcoil.base as tfcoil_module from process.data_structure.build_variables import TFCSRadialConfiguration +from process.data_structure.pfcoil_variables import PFConductorModel @pytest.fixture @@ -1030,7 +1031,7 @@ class StressclParam(NamedTuple): f_a_tf_turn_cable_copper=0.80884, str_wp=0, n_tf_wp_stress_layers=5, - i_pf_conductor=0, + i_pf_conductor=PFConductorModel.SUPERCONDUCTING, f_a_cs_turn_steel=0.57874999999999999, f_z_cs_tf_internal=0.90000000000000002, j_cs_flat_top_end=20726000, @@ -1147,7 +1148,7 @@ class StressclParam(NamedTuple): f_a_tf_turn_cable_copper=0.80884, str_wp=0.0015619754370069119, n_tf_wp_stress_layers=5, - i_pf_conductor=0, + i_pf_conductor=PFConductorModel.SUPERCONDUCTING, f_a_cs_turn_steel=0.57874999999999999, f_z_cs_tf_internal=0.90000000000000002, j_cs_flat_top_end=20726000,