From 0ebee1ed1b9c5f95b8d1eb2a3c5b8cce65aeaa75 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Mon, 27 Jul 2026 10:23:45 +0100 Subject: [PATCH 01/21] Refactor SuperconductorModel to include critical field and temperature parameters for improved flexibility --- process/models/superconductors.py | 43 ++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/process/models/superconductors.py b/process/models/superconductors.py index 2590fd9b4c..cc459328a9 100644 --- a/process/models/superconductors.py +++ b/process/models/superconductors.py @@ -76,49 +76,72 @@ class SuperconductorModel(IntEnum): ITER_NB3SN = ( 1, SuperconductorMaterial.NB3SN, + 32.97e0, # [T] + 16.06e0, # [K] SuperconductorShape.CABLE, "ITER Nb₃Sn critical surface model", ) - BI2212 = (2, SuperconductorMaterial.BI2212, SuperconductorShape.CABLE, "Bi-2212") + BI2212 = ( + 2, + SuperconductorMaterial.BI2212, + None, + None, + SuperconductorShape.CABLE, + "Bi-2212", + ) OLD_LUBELL_NBTI = ( 3, SuperconductorMaterial.NBTI, + 15.0e0, # [T] + 9.3e0, # [K] SuperconductorShape.CABLE, "Old Lubell NbTi", ) USER_DEFINED_NB3SN = ( 4, SuperconductorMaterial.NB3SN, + None, + None, SuperconductorShape.CABLE, "User-defined ITER Nb₃Sn", ) WST_NB3SN = ( 5, SuperconductorMaterial.NB3SN, + 32.97e0, # [T] + 16.06e0, # [K] SuperconductorShape.CABLE, "Western Superconducting Nb₃Sn", ) CROCO_REBCO = ( 6, SuperconductorMaterial.REBCO, + None, + None, SuperconductorShape.TAPE, "CROCO REBCO", ) DURHAM_NBTI = ( 7, SuperconductorMaterial.NBTI, + None, + None, SuperconductorShape.CABLE, "Durham Ginzburg-Landau NbTi", ) DURHAM_REBCO = ( 8, SuperconductorMaterial.REBCO, + 430.0e0, # [T] + 185.0e0, # [K] SuperconductorShape.TAPE, "Durham Ginzburg-Landau REBCO", ) HAZELTON_ZHAI_REBCO = ( 9, SuperconductorMaterial.REBCO, + 138.0e0, # [T] + 92.0e0, # [K] SuperconductorShape.TAPE, "Hazelton-Zhai REBCO", ) @@ -127,6 +150,8 @@ def __new__( cls, value: int, material: SuperconductorMaterial, + b_crit_zero_temp_strain: float, + temp_crit_zero_field_strain: float, shape: SuperconductorShape, full_name: str, ): @@ -134,6 +159,8 @@ def __new__( obj = int.__new__(cls, value) obj._value_ = value obj._material_ = material + obj._b_crit_zero_temp_strain = b_crit_zero_temp_strain + obj._temp_crit_zero_field_strain = temp_crit_zero_field_strain obj._shape_ = shape obj._full_name_ = full_name return obj @@ -153,6 +180,20 @@ def sc_shape(self): """The superconductor shape associated with this model.""" return self._shape_ + @DynamicClassAttribute + def b_crit_zero_field_strain(self): + """The upper critical field [T] for the superconductor at zero temperature and + strain (ε = 0). + """ + return self._b_crit_zero_temp_strain + + @DynamicClassAttribute + def temp_crit_zero_field_strain(self): + """The critical temperature [K] for the superconductor at zero field and strain + (ε = 0). + """ + return self._temp_crit_zero_field_strain + @DynamicClassAttribute def sc_type(self): """The superconductor type (LTS or HTS) associated with this model.""" From f4bff95c1322b2782c72a450df2c8f1650934d73 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Mon, 27 Jul 2026 10:26:59 +0100 Subject: [PATCH 02/21] Replace hardcoded bc20m and tc0m values with dynamic properties from SuperconductorModel --- process/models/tfcoil/superconducting.py | 96 ++++++++++++++++++++++-- 1 file changed, 90 insertions(+), 6 deletions(-) diff --git a/process/models/tfcoil/superconducting.py b/process/models/tfcoil/superconducting.py index 56162e2469..8e39d8c043 100644 --- a/process/models/tfcoil/superconducting.py +++ b/process/models/tfcoil/superconducting.py @@ -2909,8 +2909,8 @@ def tf_cable_in_conduit_superconductor_properties( # ITER Nb3Sn critical surface parameterization if i_tf_superconductor == SuperconductorModel.ITER_NB3SN: # Peak field and temperature at zero strain - bc20m = 32.97e0 # [T] - tc0m = 16.06e0 # [K] + bc20m = SuperconductorModel.ITER_NB3SN.b_crit_zero_field_strain # [T] + tc0m = SuperconductorModel.ITER_NB3SN.temp_crit_zero_field_strain # [K] # If strain limit achieved, throw a warning and use the lower strain if abs(strain) > 0.5e-2: @@ -2980,8 +2980,8 @@ def tf_cable_in_conduit_superconductor_properties( # NbTi data elif i_tf_superconductor == SuperconductorModel.OLD_LUBELL_NBTI: - bc20m = 15.0e0 # [T] - tc0m = 9.3e0 # [K] + bc20m = SuperconductorModel.OLD_LUBELL_NBTI.b_crit_zero_field_strain # [T] + tc0m = SuperconductorModel.OLD_LUBELL_NBTI.temp_crit_zero_field_strain # [K] c0 = 1.0e10 # [A/m²] j_superconductor_critical, _ = superconductors.jcrit_nbti( @@ -3046,8 +3046,8 @@ def tf_cable_in_conduit_superconductor_properties( # WST Nb3Sn parameterisation elif i_tf_superconductor == SuperconductorModel.WST_NB3SN: - bc20m = 32.97e0 # [T] - tc0m = 16.06e0 # [K] + bc20m = SuperconductorModel.WST_NB3SN.b_crit_zero_field_strain # [T] + tc0m = SuperconductorModel.WST_NB3SN.temp_crit_zero_field_strain # [K] # If strain limit achieved, throw a warning and use the lower strain if abs(strain) > 0.5e-2: @@ -3113,6 +3113,90 @@ def tf_cable_in_conduit_superconductor_properties( # ================================================================= + # Durham Ginzburg-Landau critical surface model for REBCO + elif i_tf_superconductor == SuperconductorModel.DURHAM_REBCO: + bc20m = SuperconductorModel.DURHAM_REBCO.b_crit_zero_field_strain # [T] + tc0m = SuperconductorModel.DURHAM_REBCO.temp_crit_zero_field_strain # [K] + + # If strain limit achieved, throw a warning and use the lower strain + if abs(strain) > 0.7e-2: + logger.error( + f"TF strain={strain} was outside the region of applicability. " + f"Used lower strain." + ) + strain = np.sign(strain) * 0.7e-2 + + j_superconductor_critical, _, _ = superconductors.gl_rebco( + temp_conductor=temp_tf_coolant_peak_field, + b_conductor=b_tf_inboard_peak, + strain=strain, + b_c20max=bc20m, + t_c0=tc0m, + ) + # Scale for the copper area fraction of the cable + j_cables_critical = j_superconductor_critical * ( + 1.0e0 - f_a_tf_turn_cable_copper + ) + + # Critical current in turn all turn cables + c_turn_cables_critical = j_cables_critical * a_tf_turn_cable_space_effective + + # Strand critical current calulation for costing in $ / kAm + # Already includes buffer and support layers so no need to include + # f_a_tf_turn_cable_copper here + data.tfcoil.j_crit_str_tf = j_superconductor_critical + + # REBCO measurements from 2 T to 14 T, extrapolating outside this + if (b_tf_inboard_peak) >= 14.0: + logger.error( + "Field on superconductor > 14 T (outside of interpolation range)" + ) + + # ================================================================= + + # Hazelton experimental data + Zhai conceptual model for REBCO + elif i_tf_superconductor == SuperconductorModel.HAZELTON_ZHAI_REBCO: + bc20m = ( + SuperconductorModel.HAZELTON_ZHAI_REBCO.b_crit_zero_field_strain + ) # [T] + tc0m = ( + SuperconductorModel.HAZELTON_ZHAI_REBCO.temp_crit_zero_field_strain + ) # [K] + + # If strain limit achieved, throw a warning and use the lower strain + if abs(strain) > 0.7e-2: + logger.error( + f"TF strain={strain} was outside the region of applicability. " + f"Used lower strain." + ) + strain = np.sign(strain) * 0.7e-2 + + # 'high current density' as per parameterisation described in Wolf, + # and based on Hazelton experimental data and Zhai conceptual model; + # see subroutine for full references + j_superconductor_critical, _, _ = superconductors.hijc_rebco( + temp_conductor=temp_tf_coolant_peak_field, + b_conductor=b_tf_inboard_peak, + b_c20max=bc20m, + t_c0=tc0m, + dr_hts_tape=data.superconducting_tfcoil.dr_tf_hts_tape, + dx_hts_tape_rebco=data.superconducting_tfcoil.dx_tf_hts_tape_rebco, + dx_hts_tape_total=data.superconducting_tfcoil.dx_tf_hts_tape_total, + ) + # Scale for the copper area fraction of the cable + j_cables_critical = j_superconductor_critical * ( + 1.0e0 - f_a_tf_turn_cable_copper + ) + + # Critical current in turn all turn cables + c_turn_cables_critical = j_cables_critical * a_tf_turn_cable_space_effective + + # Strand critical current calulation for costing in $ / kAm + # = superconducting filaments jc * (1 -strand copper fraction) + data.tfcoil.j_crit_str_tf = j_superconductor_critical * ( + 1.0e0 - f_a_tf_turn_cable_copper + ) + else: raise ProcessValueError( "Illegal value for i_tf_sc_mat", i_tf_superconductor=i_tf_superconductor From 8cff8db15bd18503adcb0150a4e6cd4a676987fb Mon Sep 17 00:00:00 2001 From: mn3981 Date: Mon, 27 Jul 2026 10:28:19 +0100 Subject: [PATCH 03/21] Replace hardcoded bc20m and tc0m values with dynamic properties from SuperconductorModel --- process/models/pfcoil.py | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/process/models/pfcoil.py b/process/models/pfcoil.py index 2343d3fde3..67449a0ddb 100644 --- a/process/models/pfcoil.py +++ b/process/models/pfcoil.py @@ -4733,8 +4733,12 @@ def j_crit_cable_frac(j_crit_sc, fcu, fhe): # Find critical current density in superconducting strand, jcritstr if isumat == SuperconductorModel.ITER_NB3SN: # ITER Nb3Sn critical surface parameterization - bc20m = 32.97e0 # [T] critical field at 0 K and 0 strain - tc0m = 16.06e0 # [K] critical temperature at 0 T and 0 strain + bc20m = ( + SuperconductorModel.ITER_NB3SN.b_crit_zero_field_strain + ) # [T] critical field at 0 K and 0 strain + tc0m = ( + SuperconductorModel.ITER_NB3SN.temp_crit_zero_field_strain + ) # [K] critical temperature at 0 T and 0 strain # j_crit_sc returned by superconductors.itersc is # the critical current density in the superconductor @@ -4772,8 +4776,12 @@ def j_crit_cable_frac(j_crit_sc, fcu, fhe): elif isumat == SuperconductorModel.OLD_LUBELL_NBTI: # NbTi data - bc20m = 15.0e0 # [T] critical field at 0 K and 0 strain - tc0m = 9.3e0 # [K] critical temperature at 0 T and 0 strain + bc20m = ( + SuperconductorModel.OLD_LUBELL_NBTI.b_crit_zero_field_strain + ) # [T] critical field at 0 K and 0 strain + tc0m = ( + SuperconductorModel.OLD_LUBELL_NBTI.temp_crit_zero_field_strain + ) # [K] critical temperature at 0 T and 0 strain c0 = 1.0e10 # # [A/m²] j_crit_sc, _ = superconductors.jcrit_nbti( temp_conductor=temp_pf_peak_field, @@ -4799,8 +4807,12 @@ def j_crit_cable_frac(j_crit_sc, fcu, fhe): elif isumat == SuperconductorModel.WST_NB3SN: # WST Nb3Sn parameterisation - bc20m = 32.97e0 # [T] critical field at 0 K and 0 strain - tc0m = 16.06e0 # [K] critical temperature at 0 T and 0 strain + bc20m = ( + SuperconductorModel.WST_NB3SN.b_crit_zero_field_strain + ) # [T] critical field at 0 K and 0 strain + tc0m = ( + SuperconductorModel.WST_NB3SN.temp_crit_zero_field_strain + ) # [K] critical temperature at 0 T and 0 strain # j_crit_sc returned by superconductors.itersc is the critical current density # in the superconductor - not the whole strand, which contains copper @@ -4836,8 +4848,12 @@ def j_crit_cable_frac(j_crit_sc, fcu, fhe): elif isumat == SuperconductorModel.DURHAM_REBCO: # Durham Ginzburg-Landau critical surface model for REBCO - bc20m = 429e0 # [T] critical field at 0 K and 0 strain - tc0m = 185e0 # [K] critical temperature at 0 T and 0 strain + bc20m = ( + SuperconductorModel.DURHAM_REBCO.b_crit_zero_field_strain + ) # [T] critical field at 0 K and 0 strain + tc0m = ( + SuperconductorModel.DURHAM_REBCO.temp_crit_zero_field_strain + ) # [K] critical temperature at 0 T and 0 strain j_crit_sc, _, _ = superconductors.gl_rebco( temp_conductor=temp_pf_peak_field, b_conductor=b_pf_peak, @@ -4850,8 +4866,12 @@ def j_crit_cable_frac(j_crit_sc, fcu, fhe): elif isumat == SuperconductorModel.HAZELTON_ZHAI_REBCO: # Hazelton experimental data + Zhai conceptual model for REBCO - bc20m = 138 # [T] critical field at 0 K and 0 strain - tc0m = 92 # [K] critical temperature at 0 T and 0 strain + bc20m = ( + SuperconductorModel.HAZELTON_ZHAI_REBCO.b_crit_zero_field_strain + ) # [T] critical field at 0 K and 0 strain + tc0m = ( + SuperconductorModel.HAZELTON_ZHAI_REBCO.temp_crit_zero_field_strain + ) # [K] critical temperature at 0 T and 0 strain j_crit_sc, _, _ = superconductors.hijc_rebco( temp_conductor=temp_pf_peak_field, b_conductor=b_pf_peak, From 6de7dcfb941fe92695c45cc2681f1c2de2ad9286 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Mon, 27 Jul 2026 10:32:54 +0100 Subject: [PATCH 04/21] Update Durham NbTi parameters to use defined properties for critical field and temperature --- process/models/superconductors.py | 4 ++-- process/models/tfcoil/superconducting.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/process/models/superconductors.py b/process/models/superconductors.py index cc459328a9..01b161b17e 100644 --- a/process/models/superconductors.py +++ b/process/models/superconductors.py @@ -124,8 +124,8 @@ class SuperconductorModel(IntEnum): DURHAM_NBTI = ( 7, SuperconductorMaterial.NBTI, - None, - None, + 14.86e0, # [T] + 9.2e0, # [K] SuperconductorShape.CABLE, "Durham Ginzburg-Landau NbTi", ) diff --git a/process/models/tfcoil/superconducting.py b/process/models/tfcoil/superconducting.py index 8e39d8c043..eeee294d77 100644 --- a/process/models/tfcoil/superconducting.py +++ b/process/models/tfcoil/superconducting.py @@ -3087,8 +3087,8 @@ def tf_cable_in_conduit_superconductor_properties( # Durham Ginzburg-Landau Nb-Ti parameterisation elif i_tf_superconductor == SuperconductorModel.DURHAM_NBTI: - bc20m = data.tfcoil.b_crit_upper_nbti # [T] - tc0m = data.tfcoil.t_crit_nbti # [K] + bc20m = SuperconductorModel.DURHAM_NBTI.b_crit_zero_field_strain # [T] + tc0m = SuperconductorModel.DURHAM_NBTI.temp_crit_zero_field_strain # [K] j_superconductor_critical, _, _ = superconductors.gl_nbti( temp_conductor=temp_tf_coolant_peak_field, From ce6b90615cbe64e1f188078d7f2b93b70a9da10c Mon Sep 17 00:00:00 2001 From: mn3981 Date: Mon, 27 Jul 2026 10:36:55 +0100 Subject: [PATCH 05/21] Remove hardcoded bc20m and tc0m values from PFCoil and CSCoil models, replacing them with dynamic properties from SuperconductorModel --- process/models/pfcoil.py | 20 ++++++-------------- tests/unit/models/test_pfcoil.py | 6 ------ 2 files changed, 6 insertions(+), 20 deletions(-) diff --git a/process/models/pfcoil.py b/process/models/pfcoil.py index 67449a0ddb..2e058118d9 100644 --- a/process/models/pfcoil.py +++ b/process/models/pfcoil.py @@ -886,8 +886,6 @@ def pfcoil(self): temp_pf_peak_field=self.data.tfcoil.tftmp, bcritsc=self.data.tfcoil.bcritsc, tcritsc=self.data.tfcoil.tcritsc, - b_crit_upper_nbti=self.data.tfcoil.b_crit_upper_nbti, - t_crit_nbti=self.data.tfcoil.t_crit_nbti, dr_hts_tape=self.data.superconducting_tfcoil.dr_tf_hts_tape, dx_hts_tape_rebco=self.data.superconducting_tfcoil.dx_tf_hts_tape_rebco, dx_hts_tape_total=self.data.superconducting_tfcoil.dx_tf_hts_tape_total, @@ -3610,8 +3608,6 @@ def ohcalc(self): temp_pf_peak_field=self.data.pf_coil.temp_cs_superconductor_operating, bcritsc=self.data.tfcoil.bcritsc, tcritsc=self.data.tfcoil.tcritsc, - b_crit_upper_nbti=self.data.tfcoil.b_crit_upper_nbti, - t_crit_nbti=self.data.tfcoil.t_crit_nbti, dr_hts_tape=self.data.superconducting_tfcoil.dr_tf_hts_tape, dx_hts_tape_rebco=self.data.superconducting_tfcoil.dx_tf_hts_tape_rebco, dx_hts_tape_total=self.data.superconducting_tfcoil.dx_tf_hts_tape_total, @@ -3660,8 +3656,6 @@ def ohcalc(self): temp_pf_peak_field=self.data.pf_coil.temp_cs_superconductor_operating, bcritsc=self.data.tfcoil.bcritsc, tcritsc=self.data.tfcoil.tcritsc, - b_crit_upper_nbti=self.data.tfcoil.b_crit_upper_nbti, - t_crit_nbti=self.data.tfcoil.t_crit_nbti, dr_hts_tape=self.data.superconducting_tfcoil.dr_tf_hts_tape, dx_hts_tape_rebco=self.data.superconducting_tfcoil.dx_tf_hts_tape_rebco, dx_hts_tape_total=self.data.superconducting_tfcoil.dx_tf_hts_tape_total, @@ -4649,8 +4643,6 @@ def superconpf( temp_pf_peak_field: float, bcritsc: float, tcritsc: float, - b_crit_upper_nbti: float, - t_crit_nbti: float, dr_hts_tape: float, dx_hts_tape_rebco: float, dx_hts_tape_total: float, @@ -4698,10 +4690,6 @@ def superconpf( Critical field at zero temperature and strain [T] (isumat=4 only) tcritsc : float Critical temperature at zero field and strain [K] (isumat=4 only) - b_crit_upper_nbti: float - upper critical field of GL_nbti [T] - t_crit_nbti: float - critical temperature of GL_nbti [K] dr_hts_tape: float Mean width of tape [m] dx_hts_tape_rebco: float @@ -4835,8 +4823,12 @@ def j_crit_cable_frac(j_crit_sc, fcu, fhe): elif isumat == SuperconductorModel.DURHAM_NBTI: # Durham Ginzburg-Landau critical surface model for Nb-Ti - bc20m = b_crit_upper_nbti # [T] critical field at 0 K and 0 strain - tc0m = t_crit_nbti # [K] critical temperature at 0 T and 0 strain + bc20m = ( + SuperconductorModel.DURHAM_NBTI.b_crit_zero_field_strain + ) # [T] critical field at 0 K and 0 strain + tc0m = ( + SuperconductorModel.DURHAM_NBTI.temp_crit_zero_field_strain + ) # [K] critical temperature at 0 T and 0 strain j_crit_sc, _, _ = superconductors.gl_nbti( temp_conductor=temp_pf_peak_field, b_conductor=b_pf_peak, diff --git a/tests/unit/models/test_pfcoil.py b/tests/unit/models/test_pfcoil.py index dc096cb36d..7d011fd227 100644 --- a/tests/unit/models/test_pfcoil.py +++ b/tests/unit/models/test_pfcoil.py @@ -3805,8 +3805,6 @@ def test_peakb(monkeypatch, pfcoil): class SuperconPFParam(NamedTuple): - b_crit_upper_nbti: Any = None - t_crit_nbti: Any = None bmax: Any = None fhe: Any = None fcu: Any = None @@ -3836,8 +3834,6 @@ class SuperconPFParam(NamedTuple): thelium=4.75, bcritsc=24, tcritsc=16, - b_crit_upper_nbti=14.86, - t_crit_nbti=9.04, dr_tf_hts_tape=4.0e-3, dx_tf_hts_tape_rebco=1.0e-6, dx_tf_hts_tape_total=6.5e-5, @@ -3873,8 +3869,6 @@ def test_superconpf(superconpfparam): superconpfparam.thelium, superconpfparam.bcritsc, superconpfparam.tcritsc, - superconpfparam.b_crit_upper_nbti, - superconpfparam.t_crit_nbti, superconpfparam.dr_tf_hts_tape, superconpfparam.dx_tf_hts_tape_rebco, superconpfparam.dx_tf_hts_tape_total, From a9a2b8b2c46eaf13acd2bc2d79cc762c3136aeaf Mon Sep 17 00:00:00 2001 From: mn3981 Date: Mon, 27 Jul 2026 10:43:59 +0100 Subject: [PATCH 06/21] Remove hardcoded b_crit_upper_nbti and t_crit_nbti values, replacing them with dynamic properties from SuperconductorModel --- process/core/input.py | 2 -- process/data_structure/tfcoil_variables.py | 6 ------ process/models/stellarator/coils/calculate.py | 2 -- process/models/stellarator/coils/coils.py | 7 +++---- tests/unit/models/test_pfcoil.py | 12 ------------ tests/unit/models/tfcoil/test_sctfcoil.py | 16 ---------------- 6 files changed, 3 insertions(+), 42 deletions(-) diff --git a/process/core/input.py b/process/core/input.py index bf30712004..2a7b4c6df3 100644 --- a/process/core/input.py +++ b/process/core/input.py @@ -216,7 +216,6 @@ def bounds(self) -> tuple[NumberType | None, NumberType | None]: "auxcool_w": InputVariable("buildings", float, range=(10.0, 1000.0)), "p_hcd_injected_min_mw": InputVariable("constraints", float, range=(0.01, 100.0)), "f_t_plant_available_min": InputVariable("costs", float, range=(0.0, 1.0)), - "b_crit_upper_nbti": InputVariable("tfcoil", float, range=(0.0, 30.0)), "p_plant_electric_base": InputVariable( "heat_transport", float, range=(1000000.0, 10000000000.0) ), @@ -781,7 +780,6 @@ def bounds(self) -> tuple[NumberType | None, NumberType | None]: "dx_tf_turn_cable_space_general": InputVariable("tfcoil", float, range=(0.0, 0.1)), "t_crack_radial": InputVariable("cs_fatigue", float, range=(1e-05, 1.0)), "t_crack_vertical": InputVariable("cs_fatigue", float, range=(1e-05, 1.0)), - "t_crit_nbti": InputVariable("tfcoil", float, range=(0.0, 15.0)), "t_plant_pulse_plasma_current_ramp_up": InputVariable( "times", float, range=(0.0, 10000.0) ), diff --git a/process/data_structure/tfcoil_variables.py b/process/data_structure/tfcoil_variables.py index 985bb09b79..1e9bdb5a55 100644 --- a/process/data_structure/tfcoil_variables.py +++ b/process/data_structure/tfcoil_variables.py @@ -184,12 +184,6 @@ class TFData: e_tf_coil_magnetic_stored: float = 0.0 """Stored magnetic energy in a single TF coil (J)""" - b_crit_upper_nbti: float = 14.86 - """upper critical field of GL_nbti""" - - t_crit_nbti: float = 9.04 - """critical temperature of GL_nbti""" - max_force_density: float = 0.0 """Maximal (WP averaged) force density in TF coils at 1 point. (MN/m3)""" diff --git a/process/models/stellarator/coils/calculate.py b/process/models/stellarator/coils/calculate.py index cefdf71da7..bb273f81c3 100644 --- a/process/models/stellarator/coils/calculate.py +++ b/process/models/stellarator/coils/calculate.py @@ -419,11 +419,9 @@ def winding_pack_total_size( b_max_k[k], data.tfcoil.tftmp + data.tfcoil.tmargmin, data.tfcoil.i_tf_sc_mat, - data.tfcoil.b_crit_upper_nbti, data.tfcoil.bcritsc, data.tfcoil.f_a_tf_turn_cable_copper, data.tfcoil.fhts, - data.tfcoil.t_crit_nbti, data.tfcoil.tcritsc, data.tfcoil.f_a_tf_turn_cable_space_extra_void, data.tfcoil.j_tf_wp, diff --git a/process/models/stellarator/coils/coils.py b/process/models/stellarator/coils/coils.py index e5e7394a95..795288f01d 100644 --- a/process/models/stellarator/coils/coils.py +++ b/process/models/stellarator/coils/coils.py @@ -7,6 +7,7 @@ from process.core.exceptions import ProcessValueError from process.core.model import DataStructure from process.models import superconductors +from process.models.superconductors import SuperconductorModel logger = logging.getLogger(__name__) @@ -23,11 +24,9 @@ def jcrit_from_material( b_max, t_helium, i_tf_sc_mat, - b_crit_upper_nbti, b_crit_sc, f_a_tf_turn_cable_copper, f_hts, - t_crit_nbti, t_crit_sc, f_a_tf_turn_cable_space_extra_void, j_wp, @@ -138,8 +137,8 @@ def jcrit_from_material( j_crit_cable = j_crit_cable_from_fraction(j_crit_sc, f_tf_conductor_copper, f_he) elif i_tf_sc_mat == 7: # Durham Ginzburg-Landau Nb-Ti parameterisation - bc20m = b_crit_upper_nbti - tc0m = t_crit_nbti + bc20m = SuperconductorModel.DURHAM_NBTI.b_crit_zero_field_strain + tc0m = SuperconductorModel.DURHAM_NBTI.temp_crit_zero_field_strain j_crit_sc, _bcrit, _tcrit = superconductors.gl_nbti( t_helium, b_max, strain, bc20m, tc0m ) diff --git a/tests/unit/models/test_pfcoil.py b/tests/unit/models/test_pfcoil.py index 7d011fd227..a7b8c4fe64 100644 --- a/tests/unit/models/test_pfcoil.py +++ b/tests/unit/models/test_pfcoil.py @@ -2478,8 +2478,6 @@ class PFCoilParam(NamedTuple): tcritsc: Any = None str_pf_con_res: Any = None bcritsc: Any = None - b_crit_upper_nbti: Any = None - t_crit_nbti: Any = None first_call: Any = None r_tf_outboard_out: Any = None t_plant_pulse_coil_precharge: Any = None @@ -2553,8 +2551,6 @@ class PFCoilParam(NamedTuple): tcritsc=1.6e1, str_pf_con_res=-5.0e-3, bcritsc=2.4e1, - b_crit_upper_nbti=1.486e1, - t_crit_nbti=9.04, first_call=True, r_tf_outboard_out=10.0, t_plant_pulse_coil_precharge=5.0e2, @@ -2661,8 +2657,6 @@ def test_pfcoil(monkeypatch, pfcoil, pfcoilparam): "tcritsc", "str_pf_con_res", "bcritsc", - "b_crit_upper_nbti", - "t_crit_nbti", ]: monkeypatch.setattr(pfcoil.data.tfcoil, field, getattr(pfcoilparam, field)) @@ -2727,14 +2721,12 @@ class OhCalcParam(NamedTuple): str_cs_con_res: Any = None fhts: Any = None bcritsc: Any = None - t_crit_nbti: Any = None c_pf_cs_coil_pulse_start_ma: Any = None c_pf_cs_coil_flat_top_ma: Any = None c_pf_cs_coil_pulse_end_ma: Any = None rmajor: Any = None plasma_current: Any = None poisson_steel: Any = None - b_crit_upper_nbti: Any = None exp_b_pf_coil_peak: Any = None exp_j_cs_critical_flat_top_end: Any = None @@ -2780,14 +2772,12 @@ class OhCalcParam(NamedTuple): str_cs_con_res=-5.000e-3, fhts=0.5, bcritsc=2.4e1, - t_crit_nbti=9.04, c_pf_cs_coil_pulse_start_ma=np.full(22, 0.0), c_pf_cs_coil_flat_top_ma=np.full(22, 0.0), c_pf_cs_coil_pulse_end_ma=np.full(22, -175.84911993600002), rmajor=8.938, plasma_current=1.8254e7, poisson_steel=3.0e-1, - b_crit_upper_nbti=9.04, exp_b_pf_coil_peak=13.073958753751993, exp_j_cs_critical_flat_top_end=54101481.7685945, ) @@ -2854,9 +2844,7 @@ def test_ohcalc(monkeypatch, reinitialise_error_module, cs_coil, ohcalcparam): "str_cs_con_res", "fhts", "bcritsc", - "t_crit_nbti", "poisson_steel", - "b_crit_upper_nbti", ]: monkeypatch.setattr(cs_coil.data.tfcoil, field, getattr(ohcalcparam, field)) diff --git a/tests/unit/models/tfcoil/test_sctfcoil.py b/tests/unit/models/tfcoil/test_sctfcoil.py index 71fbafe4a9..0880dbf5ed 100644 --- a/tests/unit/models/tfcoil/test_sctfcoil.py +++ b/tests/unit/models/tfcoil/test_sctfcoil.py @@ -161,14 +161,10 @@ class SuperconParam(NamedTuple): a_tf_turn_cable_space_effective: Any = None - b_crit_upper_nbti: Any = None - i_str_wp: Any = None str_wp: Any = None - t_crit_nbti: Any = None - tf_fit_t: Any = None tf_fit_z: Any = None @@ -249,11 +245,9 @@ class SuperconParam(NamedTuple): c_tf_turn=74026.751437500003, b_tf_inboard_peak_with_ripple=12.48976756562082, str_tf_con_res=-0.0050000000000000001, - b_crit_upper_nbti=14.859999999999999, i_str_wp=1, f_a_tf_turn_cable_space_cooling=0.3, str_wp=0.0015619754370069119, - t_crit_nbti=9.0399999999999991, tf_fit_t=0.80807838916035957, tf_fit_z=0.3149613642807837, f_b_tf_inboard_peak_ripple_symmetric=1.0658869305062604, @@ -299,11 +293,9 @@ class SuperconParam(NamedTuple): c_tf_turn=74026.751437500003, b_tf_inboard_peak_with_ripple=12.48976756562082, str_tf_con_res=-0.0050000000000000001, - b_crit_upper_nbti=14.859999999999999, i_str_wp=1, f_a_tf_turn_cable_space_cooling=0.3, str_wp=0.0015619754370069119, - t_crit_nbti=9.0399999999999991, tf_fit_t=0.80807838916035957, tf_fit_z=0.3149613642807837, f_b_tf_inboard_peak_ripple_symmetric=1.0658869305062604, @@ -400,18 +392,10 @@ def test_supercon(superconparam, monkeypatch, cicc_sctfcoil): cicc_sctfcoil.data.tfcoil, "str_tf_con_res", superconparam.str_tf_con_res ) - monkeypatch.setattr( - cicc_sctfcoil.data.tfcoil, "b_crit_upper_nbti", superconparam.b_crit_upper_nbti - ) - monkeypatch.setattr(cicc_sctfcoil.data.tfcoil, "i_str_wp", superconparam.i_str_wp) monkeypatch.setattr(cicc_sctfcoil.data.tfcoil, "str_wp", superconparam.str_wp) - monkeypatch.setattr( - cicc_sctfcoil.data.tfcoil, "t_crit_nbti", superconparam.t_crit_nbti - ) - monkeypatch.setattr( cicc_sctfcoil.data.superconducting_tfcoil, "tf_fit_t", superconparam.tf_fit_t ) From af1c782a4dd89dbc857ca1ded97aef57840a4cc6 Mon Sep 17 00:00:00 2001 From: Christopher Ashe <91618944+chris-ashe@users.noreply.github.com> Date: Tue, 28 Jul 2026 14:39:24 +0100 Subject: [PATCH 07/21] Update process/models/superconductors.py Co-authored-by: clmould <86794332+clmould@users.noreply.github.com> --- process/models/superconductors.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/process/models/superconductors.py b/process/models/superconductors.py index 01b161b17e..87057bd19a 100644 --- a/process/models/superconductors.py +++ b/process/models/superconductors.py @@ -150,8 +150,8 @@ def __new__( cls, value: int, material: SuperconductorMaterial, - b_crit_zero_temp_strain: float, - temp_crit_zero_field_strain: float, + b_crit_zero_temp_strain: float | None, + temp_crit_zero_field_strain: float | None, shape: SuperconductorShape, full_name: str, ): From 5c9f7d9e2ad29d31b576e3e75e3924e268116059 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Tue, 28 Jul 2026 14:45:48 +0100 Subject: [PATCH 08/21] Requested changes --- process/models/stellarator/coils/coils.py | 40 ++++++++++++++--------- process/models/superconductors.py | 6 ++-- 2 files changed, 27 insertions(+), 19 deletions(-) diff --git a/process/models/stellarator/coils/coils.py b/process/models/stellarator/coils/coils.py index 795288f01d..06e63ba194 100644 --- a/process/models/stellarator/coils/coils.py +++ b/process/models/stellarator/coils/coils.py @@ -48,9 +48,11 @@ def jcrit_from_material( ) # of a cable conductor. - if i_tf_sc_mat == 1: # ITER Nb3Sn critical surface parameterization - bc20m = 32.97 # these are values taken from sctfcoil.f90 - tc0m = 16.06 + if ( + i_tf_sc_mat == SuperconductorModel.ITER_NB3SN + ): # ITER Nb3Sn critical surface parameterization + bc20m = SuperconductorModel.ITER_NB3SN.b_crit_zero_field_strain + tc0m = SuperconductorModel.ITER_NB3SN.temp_crit_zero_field_strain # j_crit_sc returned by itersc is the critical current density in the # superconductor - not the whole strand, which contains copper @@ -69,7 +71,7 @@ def jcrit_from_material( j_crit_sc = max(1.0e-9, j_crit_sc) j_crit_cable = max(1.0e-9, j_crit_cable) - elif i_tf_sc_mat == 2: + elif i_tf_sc_mat == SuperconductorModel.BI2212: # Bi-2212 high temperature superconductor parameterization # Current density in a strand of Bi-2212 conductor # N.B. jcrit returned by bi2212 is the critical current density @@ -87,9 +89,9 @@ def jcrit_from_material( ) # bi2212 outputs j_crit_cable j_crit_sc = j_crit_cable / (1 - f_tf_conductor_copper) _tcrit = t_helium + tmarg - elif i_tf_sc_mat == 3: # NbTi data - bc20m = 15.0 - tc0m = 9.3 + elif i_tf_sc_mat == SuperconductorModel.OLD_LUBELL_NBTI: # NbTi data + bc20m = SuperconductorModel.OLD_LUBELL_NBTI.b_crit_zero_field_strain + tc0m = SuperconductorModel.OLD_LUBELL_NBTI.temp_crit_zero_field_strain c0 = 1.0 if b_max > bc20m: @@ -108,16 +110,18 @@ def jcrit_from_material( # This is needed right now. Can we change it later? j_crit_sc = max(1.0e-9, j_crit_sc) j_crit_cable = max(1.0e-9, j_crit_cable) - elif i_tf_sc_mat == 4: # As (1), but user-defined parameters + elif ( + i_tf_sc_mat == SuperconductorModel.USER_DEFINED_NB3SN + ): # As (1), but user-defined parameters bc20m = b_crit_sc tc0m = t_crit_sc j_crit_sc, _bcrit, _tcrit = superconductors.itersc( t_helium, b_max, strain, bc20m, tc0m ) j_crit_cable = j_crit_cable_from_fraction(j_crit_sc, f_tf_conductor_copper, f_he) - elif i_tf_sc_mat == 5: # WST Nb3Sn parameterisation - bc20m = 32.97 - tc0m = 16.06 + elif i_tf_sc_mat == SuperconductorModel.WST_NB3SN: # WST Nb3Sn parameterisation + bc20m = SuperconductorModel.WST_NB3SN.b_crit_zero_field_strain + tc0m = SuperconductorModel.WST_NB3SN.temp_crit_zero_field_strain # j_crit_sc returned by itersc is the critical current density in the # superconductor - not the whole strand, which contains copper @@ -131,12 +135,16 @@ def jcrit_from_material( ) j_crit_cable = j_crit_cable_from_fraction(j_crit_sc, f_tf_conductor_copper, f_he) - elif i_tf_sc_mat == 6: # ! "REBCO" 2nd generation HTS superconductor in CroCo strand + elif ( + i_tf_sc_mat == SuperconductorModel.CROCO_REBCO + ): # ! "REBCO" 2nd generation HTS superconductor in CrCo strand j_crit_sc, _validity, _, _ = superconductors.jcrit_rebco(t_helium, b_max, 0) j_crit_sc = max(1.0e-9, j_crit_sc) j_crit_cable = j_crit_cable_from_fraction(j_crit_sc, f_tf_conductor_copper, f_he) - elif i_tf_sc_mat == 7: # Durham Ginzburg-Landau Nb-Ti parameterisation + elif ( + i_tf_sc_mat == SuperconductorModel.DURHAM_NBTI + ): # Durham Ginzburg-Landau Nb-Ti parameterisation bc20m = SuperconductorModel.DURHAM_NBTI.b_crit_zero_field_strain tc0m = SuperconductorModel.DURHAM_NBTI.temp_crit_zero_field_strain j_crit_sc, _bcrit, _tcrit = superconductors.gl_nbti( @@ -144,9 +152,9 @@ def jcrit_from_material( ) j_crit_cable = j_crit_cable_from_fraction(j_crit_sc, f_tf_conductor_copper, f_he) - elif i_tf_sc_mat == 8: - bc20m = 429 - tc0m = 185 + elif i_tf_sc_mat == SuperconductorModel.DURHAM_REBCO: + bc20m = SuperconductorModel.DURHAM_REBCO.b_crit_zero_field_strain + tc0m = SuperconductorModel.DURHAM_REBCO.temp_crit_zero_field_strain j_crit_sc, _bcrit, _tcrit = superconductors.gl_rebco( t_helium, b_max, strain, bc20m, tc0m ) diff --git a/process/models/superconductors.py b/process/models/superconductors.py index 87057bd19a..55dc5adb6b 100644 --- a/process/models/superconductors.py +++ b/process/models/superconductors.py @@ -84,7 +84,7 @@ class SuperconductorModel(IntEnum): BI2212 = ( 2, SuperconductorMaterial.BI2212, - None, + None, # Model is fitted to experimental data, so no critical B or T is defined None, SuperconductorShape.CABLE, "Bi-2212", @@ -100,8 +100,8 @@ class SuperconductorModel(IntEnum): USER_DEFINED_NB3SN = ( 4, SuperconductorMaterial.NB3SN, - None, - None, + None, # User input via `bcritsc` + None, # User input via `tcritsc` SuperconductorShape.CABLE, "User-defined ITER Nb₃Sn", ) From a879dc4cebf523048b209ed183ea18fb82d249de Mon Sep 17 00:00:00 2001 From: mn3981 Date: Tue, 11 Aug 2026 13:26:19 +0100 Subject: [PATCH 09/21] Refactor CROCOSuperconductingTFCoil to use dynamic critical field and temperature values for REBCO --- process/models/tfcoil/superconducting.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/process/models/tfcoil/superconducting.py b/process/models/tfcoil/superconducting.py index eeee294d77..1663cf43f5 100644 --- a/process/models/tfcoil/superconducting.py +++ b/process/models/tfcoil/superconducting.py @@ -4541,8 +4541,8 @@ def tf_croco_superconductor_properties( # Durham Ginzburg-Landau critical surface model for REBCO elif i_tf_superconductor == SuperconductorModel.DURHAM_REBCO: - bc20m = 430 # [T] - tc0m = 185 # [K] + bc20m = SuperconductorModel.DURHAM_REBCO.b_crit_zero_field_strain # [T] + tc0m = SuperconductorModel.DURHAM_REBCO.temp_crit_zero_field_strain # [K] # If strain limit achieved, throw a warning and use the lower strain if abs(strain) > 0.7e-2: @@ -4564,8 +4564,12 @@ def tf_croco_superconductor_properties( # Hazelton experimental data + Zhai conceptual model for REBCO elif i_tf_superconductor == SuperconductorModel.HAZELTON_ZHAI_REBCO: - bc20m = 138 # [T] - tc0m = 92 # [K] + bc20m = ( + SuperconductorModel.HAZELTON_ZHAI_REBCO.b_crit_zero_field_strain + ) # [T] + tc0m = ( + SuperconductorModel.HAZELTON_ZHAI_REBCO.temp_crit_zero_field_strain + ) # [K] # If strain limit achieved, throw a warning and use the lower strain if abs(strain) > 0.7e-2: From 72b889a46caccf84f6d59720161f5c5c8e999e25 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Tue, 11 Aug 2026 13:59:05 +0100 Subject: [PATCH 10/21] Refactor REBCO superconductor model to use dynamic critical field and temperature values --- process/models/pfcoil.py | 13 ++++++-- process/models/stellarator/coils/coils.py | 6 +++- process/models/superconductors.py | 38 +++++++++++++---------- process/models/tfcoil/superconducting.py | 7 ++++- tests/unit/models/test_superconductors.py | 2 +- 5 files changed, 44 insertions(+), 22 deletions(-) diff --git a/process/models/pfcoil.py b/process/models/pfcoil.py index 2e058118d9..a36ddb6881 100644 --- a/process/models/pfcoil.py +++ b/process/models/pfcoil.py @@ -4815,9 +4815,18 @@ def j_crit_cable_frac(j_crit_sc, fcu, fhe): j_crit_cable = j_crit_cable_frac(j_crit_sc, fcu, fhe) elif isumat == SuperconductorModel.CROCO_REBCO: - # "REBCO" 2nd generation HTS superconductor in CroCo strand + # "REBCO" 2nd generation HTS superconductor in CrCo strand + b_c20m = ( + SuperconductorModel.CROCO_REBCO.b_crit_zero_field_strain + ) # [T] critical field at 0 K and 0 strain + t_c0m = ( + SuperconductorModel.CROCO_REBCO.temp_crit_zero_field_strain + ) # [K] critical temperature at 0 T and 0 strain j_crit_sc, _, _, _ = superconductors.jcrit_rebco( - temp_conductor=temp_pf_peak_field, b_conductor=b_pf_peak + temp_conductor=temp_pf_peak_field, + b_conductor=b_pf_peak, + b_c20_max=b_c20m, + temp_c0_max=t_c0m, ) j_crit_cable = j_crit_cable_frac(j_crit_sc, fcu, fhe) diff --git a/process/models/stellarator/coils/coils.py b/process/models/stellarator/coils/coils.py index 06e63ba194..6757033b98 100644 --- a/process/models/stellarator/coils/coils.py +++ b/process/models/stellarator/coils/coils.py @@ -138,7 +138,11 @@ def jcrit_from_material( elif ( i_tf_sc_mat == SuperconductorModel.CROCO_REBCO ): # ! "REBCO" 2nd generation HTS superconductor in CrCo strand - j_crit_sc, _validity, _, _ = superconductors.jcrit_rebco(t_helium, b_max, 0) + b_c20m = SuperconductorModel.CROCO_REBCO.b_crit_zero_field_strain + t_c0m = SuperconductorModel.CROCO_REBCO.temp_crit_zero_field_strain + j_crit_sc, _validity, _, _ = superconductors.jcrit_rebco( + t_helium, b_max, b_c20m, t_c0m + ) j_crit_sc = max(1.0e-9, j_crit_sc) j_crit_cable = j_crit_cable_from_fraction(j_crit_sc, f_tf_conductor_copper, f_he) diff --git a/process/models/superconductors.py b/process/models/superconductors.py index 55dc5adb6b..d9685ca4cf 100644 --- a/process/models/superconductors.py +++ b/process/models/superconductors.py @@ -85,7 +85,7 @@ class SuperconductorModel(IntEnum): 2, SuperconductorMaterial.BI2212, None, # Model is fitted to experimental data, so no critical B or T is defined - None, + None, # Model is fitted to experimental data, so no critical B or T is defined SuperconductorShape.CABLE, "Bi-2212", ) @@ -116,8 +116,8 @@ class SuperconductorModel(IntEnum): CROCO_REBCO = ( 6, SuperconductorMaterial.REBCO, - None, - None, + 132.5e0, # [T] + 90.0e0, # [K] SuperconductorShape.TAPE, "CROCO REBCO", ) @@ -206,7 +206,7 @@ def full_name(self): def jcrit_rebco( - temp_conductor: float, b_conductor: float + temp_conductor: float, b_conductor: float, temp_c0_max: float, b_c20_max: float ) -> tuple[float, bool, float, float]: """Calculate the critical current density for a "REBCO" 2nd generation HTS superconductor. @@ -214,9 +214,13 @@ def jcrit_rebco( Parameters ---------- temp_conductor : float - Superconductor temperature in Kelvin (K). + Superconductor temperature in Kelvin [K]. b_conductor : float - Magnetic field at the superconductor in Tesla (T). + Magnetic field at the superconductor in Tesla [T]. + temp_c0_max : float + Critical temperature [K] at zero field and strain. + b_c20_max : float + Upper critical field [T] for the superconductor at zero temperature and strain. Returns ------- @@ -242,11 +246,6 @@ def jcrit_rebco( - For temp_conductor ≥ 65 K: 0.0 T ≤ b_conductor ≤ 11.5 T """ - # Critical temperature (K) at zero field and strain. - temp_c0max = 90.0 - # Upper critical field (T) for the superconductor at zero temperature and strain. - b_c20max = 132.5 - C = 1.82962e8 # scaling constant p = 0.5875 q = 1.7 @@ -274,12 +273,12 @@ def jcrit_rebco( b_conductor, ) - if temp_conductor < temp_c0max: + if temp_conductor < temp_c0_max: # Normal case - birr = b_c20max * (1 - temp_conductor / temp_c0max) ** alpha + birr = b_c20_max * (1 - temp_conductor / temp_c0_max) ** alpha else: # If temp is greater than critical temp, ensure result is real but negative. - birr = b_c20max * (1 - temp_conductor / temp_c0max) + birr = b_c20_max * (1 - temp_conductor / temp_c0_max) if b_conductor < birr: # Normal case @@ -289,10 +288,10 @@ def jcrit_rebco( # Field is too high # Ensure result is real but negative, and varies with temperature. # tcb = critical temperature at field b - tcb = temp_c0max * (1 - (b_conductor / b_c20max) ** oneoveralpha) + tcb = temp_c0_max * (1 - (b_conductor / b_c20_max) ** oneoveralpha) j_critical = -(temp_conductor - tcb) - return j_critical, validity, b_c20max, temp_c0max + return j_critical, validity, b_c20_max, temp_c0_max def current_sharing_rebco(bfield, j): @@ -312,7 +311,12 @@ def current_sharing_rebco(bfield, j): """ def deltaj_rebco(temperature): - jcritical, _, _, _ = jcrit_rebco(temperature, bfield) + jcritical, _, _, _ = jcrit_rebco( + temperature, + bfield, + SuperconductorModel.CROCO_REBCO.temp_crit_zero_field_strain, + SuperconductorModel.CROCO_REBCO.b_crit_zero_field_strain, + ) return jcritical - j # No additional arguments are required for deltaj_rebco since it only has one diff --git a/process/models/tfcoil/superconducting.py b/process/models/tfcoil/superconducting.py index 1663cf43f5..3ea0da50b0 100644 --- a/process/models/tfcoil/superconducting.py +++ b/process/models/tfcoil/superconducting.py @@ -4532,9 +4532,14 @@ def tf_croco_superconductor_properties( # ================================================================= if i_tf_superconductor == SuperconductorModel.CROCO_REBCO: + b_c20_max = SuperconductorModel.CROCO_REBCO.b_crit_zero_field_strain # [T] + t_c0 = SuperconductorModel.CROCO_REBCO.temp_crit_zero_field_strain # [K] # Find critical current density in superconducting cable, j_crit_cable j_superconductor_critical, _, bc20m, tc0m = superconductors.jcrit_rebco( - temp_conductor=temp_tf_peak, b_conductor=b_tf_inboard_peak + temp_conductor=temp_tf_peak, + b_conductor=b_tf_inboard_peak, + temp_c0_max=t_c0, + b_c20_max=b_c20_max, ) # ================================================================= diff --git a/tests/unit/models/test_superconductors.py b/tests/unit/models/test_superconductors.py index f6626623e4..0172ef6e11 100644 --- a/tests/unit/models/test_superconductors.py +++ b/tests/unit/models/test_superconductors.py @@ -143,7 +143,7 @@ def test_jcrit_nbti(jcritnbtiparam): def test_jcrit_rebco(): - jcrit_rebco, validity, _, _ = superconductors.jcrit_rebco(4.75, 7.0) + jcrit_rebco, validity, _, _ = superconductors.jcrit_rebco(4.75, 7.0, 90.0, 132.5) assert jcrit_rebco == pytest.approx(55870234414.171684) assert validity From 049a3c2d9f317e1c8ade5e339d4ffbb4e1e08017 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Wed, 12 Aug 2026 15:44:49 +0100 Subject: [PATCH 11/21] Refactor tests to replace hardcoded bc20max and tc0max values with dynamic values from SuperconductorModel --- tests/unit/models/test_superconductors.py | 25 ++++---- tests/unit/models/tfcoil/test_sctfcoil.py | 73 +++++++++++++++++++++-- 2 files changed, 82 insertions(+), 16 deletions(-) diff --git a/tests/unit/models/test_superconductors.py b/tests/unit/models/test_superconductors.py index 0172ef6e11..393ec37e98 100644 --- a/tests/unit/models/test_superconductors.py +++ b/tests/unit/models/test_superconductors.py @@ -3,7 +3,7 @@ import pytest from process.models import superconductors -from process.models.superconductors import CroCoCableGeometry +from process.models.superconductors import CroCoCableGeometry, SuperconductorModel class IterscParam(NamedTuple): @@ -31,8 +31,8 @@ class IterscParam(NamedTuple): thelium=4.75, bmax=13.008974843466492, strain=0.001601605753441172, - bc20max=32.969999999999999, - tc0max=16.059999999999999, + bc20max=SuperconductorModel.ITER_NB3SN.b_crit_zero_field_strain, + tc0max=SuperconductorModel.ITER_NB3SN.temp_crit_zero_field_strain, expected_jcrit=692348194.774593, expected_bcrit=27.092853296363597, expected_tcrit=11.338458919718571, @@ -41,8 +41,8 @@ class IterscParam(NamedTuple): thelium=6.2510000000000003, bmax=13.008974843466492, strain=0.001601605753441172, - bc20max=32.969999999999999, - tc0max=16.059999999999999, + bc20max=SuperconductorModel.ITER_NB3SN.b_crit_zero_field_strain, + tc0max=SuperconductorModel.ITER_NB3SN.temp_crit_zero_field_strain, expected_jcrit=495889332.08959526, expected_bcrit=24.442648486388464, expected_tcrit=11.338458919718571, @@ -101,8 +101,8 @@ class JcritNbtiParam(NamedTuple): temperature=4.75, bmax=8.0517923638507547, c0=10000000000, - bc20max=15, - tc0max=9.3000000000000007, + bc20max=SuperconductorModel.OLD_LUBELL_NBTI.b_crit_zero_field_strain, + tc0max=SuperconductorModel.OLD_LUBELL_NBTI.temp_crit_zero_field_strain, expected_jcrit=906668274.04561484, expected_tcrit=5.9060082696285683, ), @@ -110,8 +110,8 @@ class JcritNbtiParam(NamedTuple): temperature=6, bmax=8.0517923638507547, c0=10000000000, - bc20max=15, - tc0max=9.3000000000000007, + bc20max=SuperconductorModel.OLD_LUBELL_NBTI.b_crit_zero_field_strain, + tc0max=SuperconductorModel.OLD_LUBELL_NBTI.temp_crit_zero_field_strain, expected_jcrit=-73718607.547511846, expected_tcrit=5.9060082696285683, ), @@ -143,7 +143,12 @@ def test_jcrit_nbti(jcritnbtiparam): def test_jcrit_rebco(): - jcrit_rebco, validity, _, _ = superconductors.jcrit_rebco(4.75, 7.0, 90.0, 132.5) + jcrit_rebco, validity, _, _ = superconductors.jcrit_rebco( + temp_conductor=4.75, + b_conductor=7.0, + temp_c0_max=SuperconductorModel.CROCO_REBCO.temp_crit_zero_field_strain, + b_c20_max=SuperconductorModel.CROCO_REBCO.b_crit_zero_field_strain, + ) assert jcrit_rebco == pytest.approx(55870234414.171684) assert validity diff --git a/tests/unit/models/tfcoil/test_sctfcoil.py b/tests/unit/models/tfcoil/test_sctfcoil.py index 0880dbf5ed..883dfa63e3 100644 --- a/tests/unit/models/tfcoil/test_sctfcoil.py +++ b/tests/unit/models/tfcoil/test_sctfcoil.py @@ -3,6 +3,7 @@ import numpy as np import pytest +from process.models.superconductors import SuperconductorModel from process.models.tfcoil import superconducting as sctf @@ -2035,19 +2036,79 @@ def test_superconducting_tf_coil_area_and_masses( ), [ # ITER Nb3Sn, standard parameters - (1, 1e8, 12.0, 0.0, 32.97, 16.06, 1e10, 4.5, 5.679499736095401), + ( + 1, + 1e8, + 12.0, + 0.0, + SuperconductorModel.ITER_NB3SN.b_crit_zero_field_strain, + SuperconductorModel.ITER_NB3SN.temp_crit_zero_field_strain, + 1e10, + 4.5, + 5.679499736095401, + ), # NbTi - (3, 1e8, 8.0, 0.0, 15.0, 9.3, 1e10, 4.5, 1.3048296694055175), + ( + 3, + 1e8, + 8.0, + 0.0, + SuperconductorModel.OLD_LUBELL_NBTI.b_crit_zero_field_strain, + SuperconductorModel.OLD_LUBELL_NBTI.temp_crit_zero_field_strain, + 1e10, + 4.5, + 1.3048296694055175, + ), # User-defined Nb3Sn (4, 1e8, 10.0, 0.0, 30.0, 15.0, 1e10, 4.5, 5.539631803535094), # WST Nb3Sn - (5, 1e8, 13.0, 0.0, 32.97, 16.06, 1e10, 4.5, 5.221287311831414), + ( + 5, + 1e8, + 13.0, + 0.0, + SuperconductorModel.WST_NB3SN.b_crit_zero_field_strain, + SuperconductorModel.WST_NB3SN.temp_crit_zero_field_strain, + 1e10, + 4.5, + 5.221287311831414, + ), # Durham Ginzburg-Landau Nb-Ti - (7, 1e8, 7.0, 0.0, 14.85, 9.04, 1e10, 4.5, 1.263064155425198), + ( + 7, + 1e8, + 7.0, + 0.0, + SuperconductorModel.DURHAM_NBTI.b_crit_zero_field_strain, + SuperconductorModel.DURHAM_NBTI.temp_crit_zero_field_strain, + 1e10, + 4.5, + 1.3679852289396255, + ), # Durham Ginzburg-Landau REBCO - (8, 1e8, 10.0, 0.0, 430, 185, 1e10, 20.0, 31.82616792800119), + ( + 8, + 1e8, + 10.0, + 0.0, + SuperconductorModel.DURHAM_REBCO.b_crit_zero_field_strain, + SuperconductorModel.DURHAM_REBCO.temp_crit_zero_field_strain, + 1e10, + 20.0, + 31.82616792800119, + ), # Hazelton-Zhai REBCO - (9, 1e8, 10.0, 0.0, 138, 92, 1e10, 20.0, 48.363687012510425), + ( + 9, + 1e8, + 10.0, + 0.0, + SuperconductorModel.HAZELTON_ZHAI_REBCO.b_crit_zero_field_strain, + SuperconductorModel.HAZELTON_ZHAI_REBCO.temp_crit_zero_field_strain, + 1e10, + 20.0, + 48.363687012510425, + ), ], ) def test_calculate_superconductor_temperature_margin( From 605a6f3159ba93cf5cf654e1fe23d24981f8b0d3 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Wed, 12 Aug 2026 15:47:15 +0100 Subject: [PATCH 12/21] Refactor jcrit_from_material to use named parameters for clarity --- process/models/stellarator/coils/coils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/process/models/stellarator/coils/coils.py b/process/models/stellarator/coils/coils.py index 6757033b98..f32f365f39 100644 --- a/process/models/stellarator/coils/coils.py +++ b/process/models/stellarator/coils/coils.py @@ -141,7 +141,7 @@ def jcrit_from_material( b_c20m = SuperconductorModel.CROCO_REBCO.b_crit_zero_field_strain t_c0m = SuperconductorModel.CROCO_REBCO.temp_crit_zero_field_strain j_crit_sc, _validity, _, _ = superconductors.jcrit_rebco( - t_helium, b_max, b_c20m, t_c0m + temp_conductor=t_helium, b_conductor=b_max, b_c20_max=b_c20m, temp_c0_max=t_c0m ) j_crit_sc = max(1.0e-9, j_crit_sc) j_crit_cable = j_crit_cable_from_fraction(j_crit_sc, f_tf_conductor_copper, f_he) From 1fef6387dbcd5fd29611b30cd7a866e454d7104c Mon Sep 17 00:00:00 2001 From: mn3981 Date: Wed, 12 Aug 2026 15:53:22 +0100 Subject: [PATCH 13/21] Refactor critical surface scripts to use dynamic values from SuperconductorModel --- .../plotting_scripts/2nd_gen_rebco_critical_surface.py | 9 ++++++--- .../plotting_scripts/durham_nbti_critical_surface.py | 5 +++-- .../plotting_scripts/durham_rebco_critical_surface.py | 5 +++-- .../plotting_scripts/eutf4_nb3sn_critical_surface.py | 10 ++++++---- .../hazelton_zhai_rebco_critical_surface.py | 5 +++-- .../plotting_scripts/western_nb3sn_critical_surface.py | 9 ++++++--- process/models/stellarator/coils/coils.py | 5 ++++- process/models/superconductors.py | 8 ++++---- 8 files changed, 35 insertions(+), 21 deletions(-) diff --git a/documentation/scripts/plotting_scripts/2nd_gen_rebco_critical_surface.py b/documentation/scripts/plotting_scripts/2nd_gen_rebco_critical_surface.py index 20252f631f..9b1d693919 100644 --- a/documentation/scripts/plotting_scripts/2nd_gen_rebco_critical_surface.py +++ b/documentation/scripts/plotting_scripts/2nd_gen_rebco_critical_surface.py @@ -5,11 +5,14 @@ import plotly.graph_objects as go from process.models import superconductors +from process.models.superconductors import SuperconductorModel -temp_c0max = 90.0 # Critical temperature (K) at zero field and strain +temp_c0max = ( + SuperconductorModel.CROCO_REBCO.temp_crit_zero_field_strain +) # Critical temperature (K) at zero field and strain b_c20max = ( - 132.5 # Upper critical field (T) for superconductor at zero temperature and strain -) + SuperconductorModel.CROCO_REBCO.b_crit_zero_field_strain +) # Upper critical field (T) for superconductor at zero temperature and strain epsilon = 0.00 # Strain in superconductor # Create a grid of temperature and field values diff --git a/documentation/scripts/plotting_scripts/durham_nbti_critical_surface.py b/documentation/scripts/plotting_scripts/durham_nbti_critical_surface.py index b54ad80008..047c04ec76 100644 --- a/documentation/scripts/plotting_scripts/durham_nbti_critical_surface.py +++ b/documentation/scripts/plotting_scripts/durham_nbti_critical_surface.py @@ -5,6 +5,7 @@ import plotly.graph_objects as go from process.models import superconductors +from process.models.superconductors import SuperconductorModel # Create a grid of temperature and field values temp_conductor = np.linspace(1, 8.0, 50) # Temperature range (K) @@ -23,8 +24,8 @@ temp_conductor=temp_grid[i, j], b_conductor=b_grid[i, j], strain=0.0, - b_c20max=14.9, - t_c0=9.0, + b_c20max=SuperconductorModel.DURHAM_NBTI.b_crit_zero_field_strain, + t_c0=SuperconductorModel.DURHAM_NBTI.temp_crit_zero_field_strain, ) # Convert from A/m² to kA/mm² (1 A/m² = 1e-6 A/mm²) j_scaling[i, j] *= 1e-9 diff --git a/documentation/scripts/plotting_scripts/durham_rebco_critical_surface.py b/documentation/scripts/plotting_scripts/durham_rebco_critical_surface.py index 5de14533a9..d513d5b8ed 100644 --- a/documentation/scripts/plotting_scripts/durham_rebco_critical_surface.py +++ b/documentation/scripts/plotting_scripts/durham_rebco_critical_surface.py @@ -5,6 +5,7 @@ import plotly.graph_objects as go from process.models import superconductors +from process.models.superconductors import SuperconductorModel # Create a grid of temperature and field values temp_conductor = np.linspace(4.2, 30.0, 50) # Temperature range (K) @@ -23,8 +24,8 @@ temp_conductor=temp_grid[i, j], b_conductor=b_grid[i, j], strain=0.0, - b_c20max=429.0, - t_c0=185.0, + b_c20max=SuperconductorModel.DURHAM_REBCO.b_crit_zero_field_strain, + t_c0=SuperconductorModel.DURHAM_REBCO.temp_crit_zero_field_strain, ) # Convert from A/m² to kA/mm² (1 A/m² = 1e-6 A/mm²) j_scaling[i, j] *= 1e-9 diff --git a/documentation/scripts/plotting_scripts/eutf4_nb3sn_critical_surface.py b/documentation/scripts/plotting_scripts/eutf4_nb3sn_critical_surface.py index 162080fca1..565c0d7507 100644 --- a/documentation/scripts/plotting_scripts/eutf4_nb3sn_critical_surface.py +++ b/documentation/scripts/plotting_scripts/eutf4_nb3sn_critical_surface.py @@ -5,11 +5,13 @@ import plotly.graph_objects as go from process.models import superconductors +from process.models.superconductors import SuperconductorModel + +b_c20max = SuperconductorModel.ITER_NB3SN.b_crit_zero_field_strain +temp_c0max = ( + SuperconductorModel.ITER_NB3SN.temp_crit_zero_field_strain +) # Critical temperature (K) at zero field and strain -temp_c0max = 16.06 # Critical temperature (K) at zero field and strain -b_c20max = ( - 32.97 # Upper critical field (T) for superconductor at zero temperature and strain -) epsilon = 0.00 # Strain in superconductor # Create a grid of temperature and field values diff --git a/documentation/scripts/plotting_scripts/hazelton_zhai_rebco_critical_surface.py b/documentation/scripts/plotting_scripts/hazelton_zhai_rebco_critical_surface.py index dddd17b688..8ad53caeb2 100644 --- a/documentation/scripts/plotting_scripts/hazelton_zhai_rebco_critical_surface.py +++ b/documentation/scripts/plotting_scripts/hazelton_zhai_rebco_critical_surface.py @@ -5,6 +5,7 @@ import plotly.graph_objects as go from process.models import superconductors +from process.models.superconductors import SuperconductorModel # Create a grid of temperature and field values temp_conductor = np.linspace(4.2, 40.0, 50) # Temperature range (K) @@ -22,8 +23,8 @@ ) = superconductors.hijc_rebco( temp_conductor=temp_grid[i, j], b_conductor=b_grid[i, j], - b_c20max=138.0, - t_c0=92.0, + b_c20max=SuperconductorModel.HAZELTON_ZHAI_REBCO.b_crit_zero_field_strain, + t_c0=SuperconductorModel.HAZELTON_ZHAI_REBCO.temp_crit_zero_field_strain, tape_width=1.0, rebco_thickness=1.0, tape_thickness=1.0, diff --git a/documentation/scripts/plotting_scripts/western_nb3sn_critical_surface.py b/documentation/scripts/plotting_scripts/western_nb3sn_critical_surface.py index 10d0fafd95..c3f6adb234 100644 --- a/documentation/scripts/plotting_scripts/western_nb3sn_critical_surface.py +++ b/documentation/scripts/plotting_scripts/western_nb3sn_critical_surface.py @@ -7,11 +7,14 @@ import plotly.graph_objects as go from process.models import superconductors +from process.models.superconductors import SuperconductorModel -temp_c0max = 16.34 # Critical temperature (K) at zero field and strain +temp_c0max = ( + SuperconductorModel.WESTERN_NB3SN.temp_crit_zero_field_strain +) # Critical temperature (K) at zero field and strain b_c20max = ( - 33.24 # Upper critical field (T) for superconductor at zero temperature and strain -) + SuperconductorModel.WESTERN_NB3SN.b_crit_zero_field_strain +) # Upper critical field (T) for superconductor at zero temperature and strain epsilon = 0.00 # Strain in superconductor # Create a grid of temperature and field values diff --git a/process/models/stellarator/coils/coils.py b/process/models/stellarator/coils/coils.py index f32f365f39..fd927eaf6b 100644 --- a/process/models/stellarator/coils/coils.py +++ b/process/models/stellarator/coils/coils.py @@ -141,7 +141,10 @@ def jcrit_from_material( b_c20m = SuperconductorModel.CROCO_REBCO.b_crit_zero_field_strain t_c0m = SuperconductorModel.CROCO_REBCO.temp_crit_zero_field_strain j_crit_sc, _validity, _, _ = superconductors.jcrit_rebco( - temp_conductor=t_helium, b_conductor=b_max, b_c20_max=b_c20m, temp_c0_max=t_c0m + temp_conductor=t_helium, + b_conductor=b_max, + b_c20_max=b_c20m, + temp_c0_max=t_c0m, ) j_crit_sc = max(1.0e-9, j_crit_sc) j_crit_cable = j_crit_cable_from_fraction(j_crit_sc, f_tf_conductor_copper, f_he) diff --git a/process/models/superconductors.py b/process/models/superconductors.py index d9685ca4cf..6491d59f05 100644 --- a/process/models/superconductors.py +++ b/process/models/superconductors.py @@ -312,10 +312,10 @@ def current_sharing_rebco(bfield, j): def deltaj_rebco(temperature): jcritical, _, _, _ = jcrit_rebco( - temperature, - bfield, - SuperconductorModel.CROCO_REBCO.temp_crit_zero_field_strain, - SuperconductorModel.CROCO_REBCO.b_crit_zero_field_strain, + temp_conductor=temperature, + b_conductor=bfield, + temp_c0_max=SuperconductorModel.CROCO_REBCO.temp_crit_zero_field_strain, + b_c20_max=SuperconductorModel.CROCO_REBCO.b_crit_zero_field_strain, ) return jcritical - j From 19e1d150274003f37afe5351e885c811e97093be Mon Sep 17 00:00:00 2001 From: mn3981 Date: Thu, 13 Aug 2026 09:36:22 +0100 Subject: [PATCH 14/21] Removed wrongly added due to rebase, HTS tapes in CICC class --- process/models/tfcoil/superconducting.py | 101 ++++------------------- 1 file changed, 14 insertions(+), 87 deletions(-) diff --git a/process/models/tfcoil/superconducting.py b/process/models/tfcoil/superconducting.py index 3ea0da50b0..d212eab543 100644 --- a/process/models/tfcoil/superconducting.py +++ b/process/models/tfcoil/superconducting.py @@ -1228,12 +1228,23 @@ def calculate_superconductor_temperature_margin( # Temperature margin (already calculated in superconductors.bi2212 for # i_tf_superconductor=2) - if i_tf_superconductor == 2: + if SuperconductorModel(i_tf_superconductor) == SuperconductorModel.BI2212: # Bi-2212: temperature margin already calculated elsewhere temp_tf_superconductor_margin = 0.0 # Find temperature at which current density margin = 0 - elif i_tf_superconductor in {1, 3, 4, 5, 7, 8, 9}: - if i_tf_superconductor == 3: + elif SuperconductorModel(i_tf_superconductor) in { + SuperconductorModel.ITER_NB3SN, + SuperconductorModel.OLD_LUBELL_NBTI, + SuperconductorModel.USER_DEFINED_NB3SN, + SuperconductorModel.WST_NB3SN, + SuperconductorModel.DURHAM_NBTI, + SuperconductorModel.DURHAM_REBCO, + SuperconductorModel.HAZELTON_ZHAI_REBCO, + }: + if ( + SuperconductorModel(i_tf_superconductor) + == SuperconductorModel.OLD_LUBELL_NBTI + ): arguments = ( i_tf_superconductor, j_superconductor, @@ -3113,90 +3124,6 @@ def tf_cable_in_conduit_superconductor_properties( # ================================================================= - # Durham Ginzburg-Landau critical surface model for REBCO - elif i_tf_superconductor == SuperconductorModel.DURHAM_REBCO: - bc20m = SuperconductorModel.DURHAM_REBCO.b_crit_zero_field_strain # [T] - tc0m = SuperconductorModel.DURHAM_REBCO.temp_crit_zero_field_strain # [K] - - # If strain limit achieved, throw a warning and use the lower strain - if abs(strain) > 0.7e-2: - logger.error( - f"TF strain={strain} was outside the region of applicability. " - f"Used lower strain." - ) - strain = np.sign(strain) * 0.7e-2 - - j_superconductor_critical, _, _ = superconductors.gl_rebco( - temp_conductor=temp_tf_coolant_peak_field, - b_conductor=b_tf_inboard_peak, - strain=strain, - b_c20max=bc20m, - t_c0=tc0m, - ) - # Scale for the copper area fraction of the cable - j_cables_critical = j_superconductor_critical * ( - 1.0e0 - f_a_tf_turn_cable_copper - ) - - # Critical current in turn all turn cables - c_turn_cables_critical = j_cables_critical * a_tf_turn_cable_space_effective - - # Strand critical current calulation for costing in $ / kAm - # Already includes buffer and support layers so no need to include - # f_a_tf_turn_cable_copper here - data.tfcoil.j_crit_str_tf = j_superconductor_critical - - # REBCO measurements from 2 T to 14 T, extrapolating outside this - if (b_tf_inboard_peak) >= 14.0: - logger.error( - "Field on superconductor > 14 T (outside of interpolation range)" - ) - - # ================================================================= - - # Hazelton experimental data + Zhai conceptual model for REBCO - elif i_tf_superconductor == SuperconductorModel.HAZELTON_ZHAI_REBCO: - bc20m = ( - SuperconductorModel.HAZELTON_ZHAI_REBCO.b_crit_zero_field_strain - ) # [T] - tc0m = ( - SuperconductorModel.HAZELTON_ZHAI_REBCO.temp_crit_zero_field_strain - ) # [K] - - # If strain limit achieved, throw a warning and use the lower strain - if abs(strain) > 0.7e-2: - logger.error( - f"TF strain={strain} was outside the region of applicability. " - f"Used lower strain." - ) - strain = np.sign(strain) * 0.7e-2 - - # 'high current density' as per parameterisation described in Wolf, - # and based on Hazelton experimental data and Zhai conceptual model; - # see subroutine for full references - j_superconductor_critical, _, _ = superconductors.hijc_rebco( - temp_conductor=temp_tf_coolant_peak_field, - b_conductor=b_tf_inboard_peak, - b_c20max=bc20m, - t_c0=tc0m, - dr_hts_tape=data.superconducting_tfcoil.dr_tf_hts_tape, - dx_hts_tape_rebco=data.superconducting_tfcoil.dx_tf_hts_tape_rebco, - dx_hts_tape_total=data.superconducting_tfcoil.dx_tf_hts_tape_total, - ) - # Scale for the copper area fraction of the cable - j_cables_critical = j_superconductor_critical * ( - 1.0e0 - f_a_tf_turn_cable_copper - ) - - # Critical current in turn all turn cables - c_turn_cables_critical = j_cables_critical * a_tf_turn_cable_space_effective - - # Strand critical current calulation for costing in $ / kAm - # = superconducting filaments jc * (1 -strand copper fraction) - data.tfcoil.j_crit_str_tf = j_superconductor_critical * ( - 1.0e0 - f_a_tf_turn_cable_copper - ) - else: raise ProcessValueError( "Illegal value for i_tf_sc_mat", i_tf_superconductor=i_tf_superconductor From cd2bce7026e5a71fcae47ddc46e9da8a1adf1b02 Mon Sep 17 00:00:00 2001 From: Christopher Ashe <91618944+chris-ashe@users.noreply.github.com> Date: Thu, 13 Aug 2026 09:37:19 +0100 Subject: [PATCH 15/21] Update documentation/scripts/plotting_scripts/eutf4_nb3sn_critical_surface.py Co-authored-by: clmould <86794332+clmould@users.noreply.github.com> --- .../scripts/plotting_scripts/eutf4_nb3sn_critical_surface.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/documentation/scripts/plotting_scripts/eutf4_nb3sn_critical_surface.py b/documentation/scripts/plotting_scripts/eutf4_nb3sn_critical_surface.py index 565c0d7507..6269cb5cc3 100644 --- a/documentation/scripts/plotting_scripts/eutf4_nb3sn_critical_surface.py +++ b/documentation/scripts/plotting_scripts/eutf4_nb3sn_critical_surface.py @@ -7,7 +7,9 @@ from process.models import superconductors from process.models.superconductors import SuperconductorModel +# Upper critical field (T) for superconductor at zero temperature and strain b_c20max = SuperconductorModel.ITER_NB3SN.b_crit_zero_field_strain + temp_c0max = ( SuperconductorModel.ITER_NB3SN.temp_crit_zero_field_strain ) # Critical temperature (K) at zero field and strain From 1fabe5780149f956be0a4e9b25547c7ff92920f3 Mon Sep 17 00:00:00 2001 From: Christopher Ashe <91618944+chris-ashe@users.noreply.github.com> Date: Thu, 13 Aug 2026 09:37:46 +0100 Subject: [PATCH 16/21] Update documentation/scripts/plotting_scripts/western_nb3sn_critical_surface.py Co-authored-by: clmould <86794332+clmould@users.noreply.github.com> --- .../scripts/plotting_scripts/western_nb3sn_critical_surface.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/scripts/plotting_scripts/western_nb3sn_critical_surface.py b/documentation/scripts/plotting_scripts/western_nb3sn_critical_surface.py index c3f6adb234..6f12ec841d 100644 --- a/documentation/scripts/plotting_scripts/western_nb3sn_critical_surface.py +++ b/documentation/scripts/plotting_scripts/western_nb3sn_critical_surface.py @@ -13,7 +13,7 @@ SuperconductorModel.WESTERN_NB3SN.temp_crit_zero_field_strain ) # Critical temperature (K) at zero field and strain b_c20max = ( - SuperconductorModel.WESTERN_NB3SN.b_crit_zero_field_strain + SuperconductorModel.WST_NB3SN.b_crit_zero_field_strain ) # Upper critical field (T) for superconductor at zero temperature and strain epsilon = 0.00 # Strain in superconductor From caca5faa6e6dc5fcc72ec15195429169e29d67d9 Mon Sep 17 00:00:00 2001 From: Christopher Ashe <91618944+chris-ashe@users.noreply.github.com> Date: Thu, 13 Aug 2026 09:38:00 +0100 Subject: [PATCH 17/21] Update documentation/scripts/plotting_scripts/2nd_gen_rebco_critical_surface.py Co-authored-by: clmould <86794332+clmould@users.noreply.github.com> --- .../plotting_scripts/2nd_gen_rebco_critical_surface.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/documentation/scripts/plotting_scripts/2nd_gen_rebco_critical_surface.py b/documentation/scripts/plotting_scripts/2nd_gen_rebco_critical_surface.py index 9b1d693919..fba5d0ba40 100644 --- a/documentation/scripts/plotting_scripts/2nd_gen_rebco_critical_surface.py +++ b/documentation/scripts/plotting_scripts/2nd_gen_rebco_critical_surface.py @@ -29,7 +29,12 @@ _, _, _, - ) = superconductors.jcrit_rebco(temp_grid[i, j], b_grid[i, j]) + ) = superconductors.jcrit_rebco( + temp_conductor=temp_grid[i, j], + b_conductor=b_grid[i, j], + b_c20_max=b_c20max, + temp_c0_max=temp_c0max, + ) # Convert from A/m² to kA/mm² (1 A/m² = 1e-6 A/mm²) j_scaling[i, j] *= 1e-9 print(f"j_scaling[{i}, {j}] = {j_scaling[i, j]} kA/mm²") From e879428ddab82501e528fedce6740a171f4d76d3 Mon Sep 17 00:00:00 2001 From: Christopher Ashe <91618944+chris-ashe@users.noreply.github.com> Date: Thu, 13 Aug 2026 09:38:23 +0100 Subject: [PATCH 18/21] Update documentation/scripts/plotting_scripts/western_nb3sn_critical_surface.py Co-authored-by: clmould <86794332+clmould@users.noreply.github.com> --- .../scripts/plotting_scripts/western_nb3sn_critical_surface.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/scripts/plotting_scripts/western_nb3sn_critical_surface.py b/documentation/scripts/plotting_scripts/western_nb3sn_critical_surface.py index 6f12ec841d..133e756225 100644 --- a/documentation/scripts/plotting_scripts/western_nb3sn_critical_surface.py +++ b/documentation/scripts/plotting_scripts/western_nb3sn_critical_surface.py @@ -10,7 +10,7 @@ from process.models.superconductors import SuperconductorModel temp_c0max = ( - SuperconductorModel.WESTERN_NB3SN.temp_crit_zero_field_strain + SuperconductorModel.WST_NB3SN.temp_crit_zero_field_strain ) # Critical temperature (K) at zero field and strain b_c20max = ( SuperconductorModel.WST_NB3SN.b_crit_zero_field_strain From eeb9420a4013f2c9ff9a38464586864d8ae04dbb Mon Sep 17 00:00:00 2001 From: mn3981 Date: Fri, 14 Aug 2026 10:53:02 +0100 Subject: [PATCH 19/21] Refactor: Replace hardcoded b_c20m and tc0m values with SuperconductorModel parameters --- .../old_empirical_nbti_critical_surface.py | 5 +++-- tests/unit/models/tfcoil/test_sctfcoil.py | 8 ++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/documentation/scripts/plotting_scripts/old_empirical_nbti_critical_surface.py b/documentation/scripts/plotting_scripts/old_empirical_nbti_critical_surface.py index 53e96b8f93..cb380ed60f 100644 --- a/documentation/scripts/plotting_scripts/old_empirical_nbti_critical_surface.py +++ b/documentation/scripts/plotting_scripts/old_empirical_nbti_critical_surface.py @@ -5,6 +5,7 @@ import plotly.graph_objects as go from process.models import superconductors +from process.models.superconductors import SuperconductorModel # Create a grid of temperature and field values temp_conductor = np.linspace(1, 10.0, 50) # Temperature range (K) @@ -22,8 +23,8 @@ temp_conductor=temp_grid[i, j], b_conductor=b_grid[i, j], c0=1e10, - b_c20max=15.0, - temp_c0max=9.3, + b_c20max=SuperconductorModel.OLD_LUBELL_NBTI.b_crit_zero_field_strain, + temp_c0max=SuperconductorModel.OLD_LUBELL_NBTI.temp_crit_zero_field_strain, ) # Convert from A/m² to kA/mm² (1 A/m² = 1e-6 A/mm²) j_scaling[i, j] *= 1e-9 diff --git a/tests/unit/models/tfcoil/test_sctfcoil.py b/tests/unit/models/tfcoil/test_sctfcoil.py index 883dfa63e3..dc182e8f0b 100644 --- a/tests/unit/models/tfcoil/test_sctfcoil.py +++ b/tests/unit/models/tfcoil/test_sctfcoil.py @@ -281,8 +281,8 @@ class SuperconParam(NamedTuple): expected_j_superconductor_critical=832616175.5329928, expected_f_c_tf_turn_operating_critical=0.46510052068203006, expected_j_tf_coil_turn=23124470.793774802, - expected_bc20m=32.97, - expected_tc0m=16.06, + expected_bc20m=SuperconductorModel.ITER_NB3SN.b_crit_zero_field_strain, + expected_tc0m=SuperconductorModel.ITER_NB3SN.temp_crit_zero_field_strain, expected_c_turn_cables_critical=159162.9081148869, expected_j_superconductor=387250216.7686755, ), @@ -327,8 +327,8 @@ class SuperconParam(NamedTuple): expected_j_superconductor_critical=832616175.5329928, expected_f_c_tf_turn_operating_critical=0.46510052068203006, expected_j_tf_coil_turn=23124470.793774802, - expected_bc20m=32.97, - expected_tc0m=16.06, + expected_bc20m=SuperconductorModel.ITER_NB3SN.b_crit_zero_field_strain, + expected_tc0m=SuperconductorModel.ITER_NB3SN.temp_crit_zero_field_strain, expected_c_turn_cables_critical=159162.9081148869, expected_j_superconductor=387250216.7686755, ), From a867b50b124580990663e4e56b166679c3a81a45 Mon Sep 17 00:00:00 2001 From: Christopher Ashe <91618944+chris-ashe@users.noreply.github.com> Date: Fri, 14 Aug 2026 10:53:24 +0100 Subject: [PATCH 20/21] Update tests/unit/models/tfcoil/test_sctfcoil.py Co-authored-by: clmould <86794332+clmould@users.noreply.github.com> --- tests/unit/models/tfcoil/test_sctfcoil.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/models/tfcoil/test_sctfcoil.py b/tests/unit/models/tfcoil/test_sctfcoil.py index dc182e8f0b..b4bf7071aa 100644 --- a/tests/unit/models/tfcoil/test_sctfcoil.py +++ b/tests/unit/models/tfcoil/test_sctfcoil.py @@ -252,7 +252,7 @@ class SuperconParam(NamedTuple): tf_fit_t=0.80807838916035957, tf_fit_z=0.3149613642807837, f_b_tf_inboard_peak_ripple_symmetric=1.0658869305062604, - i_tf_superconductor=5, + i_tf_superconductor=SuperconductorModel.WST_NB3SN, iprint=0, outfile=11, a_tf_turn_cable_space=0.001293323051622732, From 4b59b1eefd192e269ad33be87b6b84098425a439 Mon Sep 17 00:00:00 2001 From: Christopher Ashe <91618944+chris-ashe@users.noreply.github.com> Date: Fri, 14 Aug 2026 10:53:37 +0100 Subject: [PATCH 21/21] Update tests/unit/models/tfcoil/test_sctfcoil.py Co-authored-by: clmould <86794332+clmould@users.noreply.github.com> --- tests/unit/models/tfcoil/test_sctfcoil.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/unit/models/tfcoil/test_sctfcoil.py b/tests/unit/models/tfcoil/test_sctfcoil.py index b4bf7071aa..5dd134b05f 100644 --- a/tests/unit/models/tfcoil/test_sctfcoil.py +++ b/tests/unit/models/tfcoil/test_sctfcoil.py @@ -281,8 +281,8 @@ class SuperconParam(NamedTuple): expected_j_superconductor_critical=832616175.5329928, expected_f_c_tf_turn_operating_critical=0.46510052068203006, expected_j_tf_coil_turn=23124470.793774802, - expected_bc20m=SuperconductorModel.ITER_NB3SN.b_crit_zero_field_strain, - expected_tc0m=SuperconductorModel.ITER_NB3SN.temp_crit_zero_field_strain, + expected_bc20m=SuperconductorModel.WST_NB3SN.b_crit_zero_field_strain, + expected_tc0m=SuperconductorModel.WST_NB3SN.temp_crit_zero_field_strain, expected_c_turn_cables_critical=159162.9081148869, expected_j_superconductor=387250216.7686755, ), @@ -300,7 +300,7 @@ class SuperconParam(NamedTuple): tf_fit_t=0.80807838916035957, tf_fit_z=0.3149613642807837, f_b_tf_inboard_peak_ripple_symmetric=1.0658869305062604, - i_tf_superconductor=5, + i_tf_superconductor=SuperconductorModel.WST_NB3SN, iprint=0, outfile=11, a_tf_turn_cable_space=0.001293323051622732, @@ -327,8 +327,8 @@ class SuperconParam(NamedTuple): expected_j_superconductor_critical=832616175.5329928, expected_f_c_tf_turn_operating_critical=0.46510052068203006, expected_j_tf_coil_turn=23124470.793774802, - expected_bc20m=SuperconductorModel.ITER_NB3SN.b_crit_zero_field_strain, - expected_tc0m=SuperconductorModel.ITER_NB3SN.temp_crit_zero_field_strain, + expected_bc20m=SuperconductorModel.WST_NB3SN.b_crit_zero_field_strain, + expected_tc0m=SuperconductorModel.WST_NB3SN.temp_crit_zero_field_strain, expected_c_turn_cables_critical=159162.9081148869, expected_j_superconductor=387250216.7686755, ),