Skip to content
34 changes: 26 additions & 8 deletions process/core/init.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@
from process.data_structure.times_variables import init_times_variables
from process.data_structure.vacuum_variables import init_vacuum_variables
from process.models.stellarator.initialization import st_init
from process.models.superconductors import (
SuperconductorMaterial,
SuperconductorModel,
SuperconductorType,
)
from process.models.tfcoil.base import TFCoilShapeModel


Expand Down Expand Up @@ -955,7 +960,7 @@ def check_process(inputs): # noqa: ARG001
# Integer turns option not yet available for REBCO taped turns

if (
data_structure.tfcoil_variables.i_tf_sc_mat == 6
data_structure.tfcoil_variables.i_tf_sc_mat == SuperconductorModel.CROCO_REBCO
and data_structure.tfcoil_variables.i_tf_turns_integer == 1
):
raise ProcessValidationError(
Expand Down Expand Up @@ -995,16 +1000,28 @@ def check_process(inputs): # noqa: ARG001
data_structure.tfcoil_variables.eyoung_cond_trans = 0
elif data_structure.tfcoil_variables.i_tf_cond_eyoung_axial == 2:
# Select sensible defaults from the literature
if data_structure.tfcoil_variables.i_tf_sc_mat in [1, 4, 5]:
if (
SuperconductorModel(data_structure.tfcoil_variables.i_tf_sc_mat).material
== SuperconductorMaterial.NB3SN
):
# Nb3Sn: Nyilas, A et. al, Superconductor Science and Technology 16, no. 9 (2003): 1036-42. https://doi.org/10.1088/0953-2048/16/9/313.
data_structure.tfcoil_variables.eyoung_cond_axial = 32e9
elif data_structure.tfcoil_variables.i_tf_sc_mat == 2:
elif (
SuperconductorModel(data_structure.tfcoil_variables.i_tf_sc_mat).material
== SuperconductorMaterial.BI2212
):
# Bi-2212: Brown, M. et al, IOP Conference Series: Materials Science and Engineering 279 (2017): 012022. https://doi.org/10.1088/1757-899X/279/1/012022.
data_structure.tfcoil_variables.eyoung_cond_axial = 80e9
elif data_structure.tfcoil_variables.i_tf_sc_mat in [3, 7]:
elif (
SuperconductorModel(data_structure.tfcoil_variables.i_tf_sc_mat).material
== SuperconductorMaterial.NBTI
):
# NbTi: Vedrine, P. et. al, IEEE Transactions on Applied Superconductivity 9, no. 2 (1999): 236-39. https://doi.org/10.1109/77.783280.
data_structure.tfcoil_variables.eyoung_cond_axial = 6.8e9
elif data_structure.tfcoil_variables.i_tf_sc_mat in [6, 8, 9]:
elif (
SuperconductorModel(data_structure.tfcoil_variables.i_tf_sc_mat).material
== SuperconductorMaterial.REBCO
):
# REBCO: Fujishiro, H. et. al, Physica C: Superconductivity, 426-431 (2005): 699-704. https://doi.org/10.1016/j.physc.2005.01.045.
data_structure.tfcoil_variables.eyoung_cond_axial = 145e9

Expand Down Expand Up @@ -1113,7 +1130,8 @@ def check_process(inputs): # noqa: ARG001

# Checking the SC temperature for LTS
if (
data_structure.tfcoil_variables.i_tf_sc_mat in [1, 3, 4, 5]
SuperconductorModel(data_structure.tfcoil_variables.i_tf_sc_mat).sc_type
== SuperconductorType.LOW_TEMPERATURE
and data_structure.tfcoil_variables.tftmp > 10.0
):
raise ProcessValidationError(
Expand Down Expand Up @@ -1213,8 +1231,8 @@ def check_process(inputs): # noqa: ARG001
]
== 36
).any() and (
data_structure.tfcoil_variables.i_tf_sc_mat == 8
or data_structure.tfcoil_variables.i_tf_sc_mat == 9
SuperconductorModel(data_structure.tfcoil_variables.i_tf_sc_mat).sc_type
== SuperconductorMaterial.REBCO
):
raise ProcessValidationError(
"turn off TF temperature margin constraint icc = 36 when using REBCO"
Expand Down
7 changes: 3 additions & 4 deletions process/core/io/plot_proc.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
import process.core.constants as constants
import process.core.io.mfile as mf
import process.data_structure.pfcoil_variables as pfcoil_variables
import process.models.tfcoil.superconducting as sctf
from process.core.io.mfile import MFileErrorClass
from process.core.solver.objectives import OBJECTIVE_NAMES
from process.data_structure import impurity_radiation_module
Expand Down Expand Up @@ -71,8 +70,8 @@
from process.models.physics.impurity_radiation import read_impurity_file
from process.models.physics.l_h_transition import PlasmaConfinementTransitionModel
from process.models.physics.plasma_current import PlasmaCurrent, PlasmaCurrentModel
from process.models.superconductors import SuperconductorModel
from process.models.tfcoil.base import TFCoilShapeModel
from process.models.tfcoil.superconducting import SUPERCONDUCTING_TF_TYPES

mpl.rcParams["figure.max_open_warning"] = 40

Expand Down Expand Up @@ -7448,7 +7447,7 @@ def _pack_strands_rectangular_with_obstacles(

textstr_superconductor = (
f"$\\mathbf{{Superconductor:}}$\n \n"
f"Superconductor used: {sctf.SUPERCONDUCTING_TF_TYPES[mfile.get('i_tf_sc_mat', scan=scan)]}\n"
f"Superconductor used: {SuperconductorModel(mfile.get('i_tf_sc_mat', scan=scan)).full_name}\n"
f"Critical field at zero \ntemperature and strain: {mfile.get('b_tf_superconductor_critical_zero_temp_strain', scan=scan):.4f} T\n"
f"Critical temperature at \nzero field and strain: {mfile.get('temp_tf_superconductor_critical_zero_field_strain', scan=scan):.4f} K\n"
f"Temperature at conductor: {mfile.get('tftmp', scan=scan):.4f} K\n"
Expand Down Expand Up @@ -8077,7 +8076,7 @@ def plot_magnetics_info(axis: plt.Axes, mfile: mf.MFile, scan: int):
i_tf_sc_mat = 0

if i_tf_sc_mat > 0:
tftype = SUPERCONDUCTING_TF_TYPES[int(mfile.get("i_tf_sc_mat", scan=scan))]
tftype = SuperconductorModel(int(mfile.get("i_tf_sc_mat", scan=scan))).full_name
else:
tftype = "Resistive Copper"

Expand Down
51 changes: 11 additions & 40 deletions process/models/pfcoil.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
from process.data_structure import rebco_variables as rcv
from process.data_structure import tfcoil_variables as tfv
from process.data_structure import times_variables as tv
from process.models.superconductors import SuperconductorMaterial, SuperconductorModel
from process.models.tfcoil.base import TFCoilShapeModel

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -2397,19 +2398,18 @@ def outpf(self):

# REBCO fractures in strains above ~+/- 0.7%
if (
pfcoil_variables.i_cs_superconductor == 6
or pfcoil_variables.i_cs_superconductor == 8
or pfcoil_variables.i_cs_superconductor == 9
SuperconductorModel(pfcoil_variables.i_pf_superconductor).material
== SuperconductorMaterial.REBCO
) and abs(tfv.str_cs_con_res) > 0.7e-2:
logger.error(
"Non physical strain used in CS. Use superconductor strain < +/- 0.7%"
)

if (
pfcoil_variables.i_pf_superconductor == 6
or pfcoil_variables.i_pf_superconductor == 8
or pfcoil_variables.i_pf_superconductor == 9
) and abs(tfv.str_pf_con_res) > 0.7e-2:
SuperconductorModel(pfcoil_variables.i_pf_superconductor).material
== SuperconductorMaterial.REBCO
and abs(tfv.str_pf_con_res) > 0.7e-2
):
logger.error(
"Non physical strain used in PF. Use superconductor strain < +/- 0.7%"
)
Expand All @@ -2428,39 +2428,10 @@ def outpf(self):
pfcoil_variables.i_pf_superconductor,
)

if pfcoil_variables.i_pf_superconductor == 1:
op.ocmmnt(self.outfile, " (ITER Nb3Sn critical surface model)")
elif pfcoil_variables.i_pf_superconductor == 2:
op.ocmmnt(self.outfile, " (Bi-2212 high temperature superconductor)")
elif pfcoil_variables.i_pf_superconductor == 3:
op.ocmmnt(self.outfile, " (NbTi)")
elif pfcoil_variables.i_pf_superconductor == 4:
op.ocmmnt(
self.outfile,
" (ITER Nb3Sn critical surface model, user-defined parameters)",
)
elif pfcoil_variables.i_pf_superconductor == 5:
op.ocmmnt(self.outfile, " (WST Nb3Sn critical surface model)")
elif pfcoil_variables.i_pf_superconductor == 6:
op.ocmmnt(
self.outfile,
" (REBCO 2nd generation HTS superconductor in CrCo strand)",
)
elif pfcoil_variables.i_pf_superconductor == 7:
op.ocmmnt(
self.outfile,
" (Durham Ginzburg-Landau critical surface model for Nb-Ti)",
)
elif pfcoil_variables.i_pf_superconductor == 8:
op.ocmmnt(
self.outfile,
" (Durham Ginzburg-Landau critical surface model for REBCO)",
)
elif pfcoil_variables.i_pf_superconductor == 9:
op.ocmmnt(
self.outfile,
" (Hazelton experimental data + Zhai conceptual model for REBCO)",
)
op.ocmmnt(
self.outfile,
f" -> {SuperconductorModel(pfcoil_variables.i_pf_superconductor).full_name}",
)

op.ovarre(
self.outfile,
Expand Down
99 changes: 99 additions & 0 deletions process/models/superconductors.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import logging
from enum import IntEnum
from types import DynamicClassAttribute

import numpy as np
from scipy import optimize
Expand All @@ -9,6 +11,103 @@
logger = logging.getLogger(__name__)


class SuperconductorType(IntEnum):
"""Enumeration of superconductor types."""

LOW_TEMPERATURE = (1, "LTS")
HIGH_TEMPERATURE = (2, "HTS")

def __new__(cls, value, abbreviation):
obj = int.__new__(cls, value)
obj._value_ = value
obj._abbreviation_ = abbreviation
return obj

@DynamicClassAttribute
def abbreviation(self):
"""Return the abbreviation for this superconductor type."""
return self._abbreviation_


class SuperconductorMaterial(IntEnum):
"""Enumeration of superconductor materials."""

NB3SN = (1, SuperconductorType.LOW_TEMPERATURE, "Nb₃Sn")
NBTI = (2, SuperconductorType.LOW_TEMPERATURE, "NbTi")
BI2212 = (3, SuperconductorType.HIGH_TEMPERATURE, "Bi-2212")
REBCO = (4, SuperconductorType.HIGH_TEMPERATURE, "REBCO")

def __new__(cls, value, sc_type, material_name):
obj = int.__new__(cls, value)
obj._value_ = value
obj._sc_type_ = sc_type
obj._material_name_ = material_name
return obj

@DynamicClassAttribute
def sc_type(self):
"""Return the superconductor type (LTS or HTS) for this material."""
return self._sc_type_.abbreviation

@DynamicClassAttribute
def material_name(self):
"""Return the name of the superconductor material."""
return self._material_name_


class SuperconductorModel(IntEnum):
"""Enumeration of superconductor models."""

ITER_NB3SN = (
1,
SuperconductorMaterial.NB3SN,
"ITER Nb₃Sn critical surface model",
)
BI2212 = (2, SuperconductorMaterial.BI2212, "Bi-2212")
OLD_LUBELL_NBTI = (3, SuperconductorMaterial.NBTI, "Old Lubell NbTi")
USER_DEFINED_NB3SN = (
4,
SuperconductorMaterial.NB3SN,
"User-defined ITER Nb₃Sn",
)
WST_NB3SN = (5, SuperconductorMaterial.NB3SN, "Western Superconducting Nb₃Sn")
CROCO_REBCO = (6, SuperconductorMaterial.REBCO, "CROCO REBCO")
DURHAM_NBTI = (7, SuperconductorMaterial.NBTI, "Durham Ginzburg-Landau NbTi")
DURHAM_REBCO = (
8,
SuperconductorMaterial.REBCO,
"Durham Ginzburg-Landau REBCO",
)
HAZELTON_ZHAI_REBCO = (9, SuperconductorMaterial.REBCO, "Hazelton-Zhai REBCO")

def __new__(cls, value, material, full_name):
obj = int.__new__(cls, value)
obj._value_ = value
obj._material_ = material
obj._full_name_ = full_name
return obj

@DynamicClassAttribute
def material(self):
"""Return the superconductor material associated with this model."""
return self._material_

@DynamicClassAttribute
def material_name(self):
"""Return the name of the superconductor material associated with this model."""
return self._material_.material_name

@DynamicClassAttribute
def sc_type(self):
"""Return the superconductor type (LTS or HTS) associated with this model."""
return self._material_.sc_type

@DynamicClassAttribute
def full_name(self):
"""Return the full name of this superconductor model."""
return self._full_name_


def jcrit_rebco(temp_conductor: float, b_conductor: float) -> tuple[float, bool]:
"""Calculate the critical current density for a "REBCO" 2nd generation HTS superconductor.

Expand Down
38 changes: 5 additions & 33 deletions process/models/tfcoil/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
tfcoil_variables,
)
from process.data_structure import build_variables as bv
from process.models.superconductors import SuperconductorModel

if TYPE_CHECKING:
from process.models.build import Build
Expand Down Expand Up @@ -571,39 +572,10 @@ def outtf(self):
tfcoil_variables.i_tf_sc_mat,
)

if tfcoil_variables.i_tf_sc_mat == 1:
po.ocmmnt(self.outfile, " -> ITER Nb3Sn critical surface model")
elif tfcoil_variables.i_tf_sc_mat == 2:
po.ocmmnt(self.outfile, " -> Bi-2212 high temperature superconductor")
elif tfcoil_variables.i_tf_sc_mat == 3:
po.ocmmnt(self.outfile, " -> NbTi")
elif tfcoil_variables.i_tf_sc_mat == 4:
po.ocmmnt(
self.outfile,
" -> ITER Nb3Sn critical surface model, user-defined parameters",
)
elif tfcoil_variables.i_tf_sc_mat == 5:
po.ocmmnt(self.outfile, " -> WST Nb3Sn")
elif tfcoil_variables.i_tf_sc_mat == 6:
po.ocmmnt(
self.outfile,
" -> High temperature superconductor: REBCO HTS tape in CroCo strand",
)
elif tfcoil_variables.i_tf_sc_mat == 7:
po.ocmmnt(
self.outfile,
" -> Durham Ginzburg-Landau critical surface model for Nb-Ti",
)
elif tfcoil_variables.i_tf_sc_mat == 8:
po.ocmmnt(
self.outfile,
" -> Durham Ginzburg-Landau critical surface model for REBCO",
)
elif tfcoil_variables.i_tf_sc_mat == 9:
po.ocmmnt(
self.outfile,
" -> Hazelton experimental data + Zhai conceptual model for REBCO",
)
po.ocmmnt(
self.outfile,
f" -> {SuperconductorModel(tfcoil_variables.i_tf_sc_mat).full_name}",
)

# Joints strategy
po.ovarin(
Expand Down
Loading
Loading