fiqus 2024.7.0__py3-none-any.whl → 2024.12.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- fiqus/MainFiQuS.py +290 -134
- fiqus/data/DataConductor.py +301 -301
- fiqus/data/DataFiQuS.py +128 -84
- fiqus/data/DataFiQuSCCT.py +150 -150
- fiqus/data/DataFiQuSConductor.py +84 -84
- fiqus/data/DataFiQuSConductorAC_Strand.py +565 -565
- fiqus/data/DataFiQuSMultipole.py +716 -42
- fiqus/data/DataFiQuSPancake3D.py +737 -278
- fiqus/data/DataMultipole.py +180 -15
- fiqus/data/DataRoxieParser.py +90 -51
- fiqus/data/DataSettings.py +121 -0
- fiqus/data/DataWindingsCCT.py +37 -37
- fiqus/data/RegionsModelFiQuS.py +18 -6
- fiqus/geom_generators/GeometryCCT.py +905 -905
- fiqus/geom_generators/GeometryConductorAC_Strand.py +1391 -1391
- fiqus/geom_generators/GeometryMultipole.py +1827 -227
- fiqus/geom_generators/GeometryPancake3D.py +316 -117
- fiqus/geom_generators/GeometryPancake3DUtils.py +549 -0
- fiqus/getdp_runners/RunGetdpCCT.py +4 -4
- fiqus/getdp_runners/RunGetdpConductorAC_Strand.py +201 -201
- fiqus/getdp_runners/RunGetdpMultipole.py +115 -42
- fiqus/getdp_runners/RunGetdpPancake3D.py +28 -6
- fiqus/mains/MainCCT.py +2 -2
- fiqus/mains/MainConductorAC_Strand.py +132 -132
- fiqus/mains/MainMultipole.py +113 -62
- fiqus/mains/MainPancake3D.py +63 -23
- fiqus/mesh_generators/MeshCCT.py +209 -209
- fiqus/mesh_generators/MeshConductorAC_Strand.py +656 -656
- fiqus/mesh_generators/MeshMultipole.py +1243 -181
- fiqus/mesh_generators/MeshPancake3D.py +275 -192
- fiqus/parsers/ParserCOND.py +825 -0
- fiqus/parsers/ParserDAT.py +16 -16
- fiqus/parsers/ParserGetDPOnSection.py +212 -212
- fiqus/parsers/ParserGetDPTimeTable.py +134 -134
- fiqus/parsers/ParserMSH.py +53 -53
- fiqus/parsers/ParserPOS.py +214 -214
- fiqus/parsers/ParserRES.py +142 -142
- fiqus/plotters/PlotPythonCCT.py +133 -133
- fiqus/plotters/PlotPythonConductorAC.py +855 -855
- fiqus/plotters/PlotPythonMultipole.py +18 -18
- fiqus/post_processors/PostProcessCCT.py +440 -440
- fiqus/post_processors/PostProcessConductorAC.py +49 -49
- fiqus/post_processors/PostProcessMultipole.py +353 -229
- fiqus/post_processors/PostProcessPancake3D.py +8 -13
- fiqus/pre_processors/PreProcessCCT.py +175 -175
- fiqus/pro_assemblers/ProAssembler.py +14 -6
- fiqus/pro_material_functions/ironBHcurves.pro +246 -246
- fiqus/pro_templates/combined/CCT_template.pro +274 -274
- fiqus/pro_templates/combined/ConductorAC_template.pro +1025 -1025
- fiqus/pro_templates/combined/Multipole_template.pro +1694 -126
- fiqus/pro_templates/combined/Pancake3D_template.pro +2294 -1103
- fiqus/pro_templates/combined/TSA_materials.pro +162 -0
- fiqus/pro_templates/combined/materials.pro +36 -18
- fiqus/utils/Utils.py +508 -110
- fiqus/utils/update_data_settings.py +33 -0
- fiqus-2024.12.1.dist-info/METADATA +132 -0
- fiqus-2024.12.1.dist-info/RECORD +84 -0
- {fiqus-2024.7.0.dist-info → fiqus-2024.12.1.dist-info}/WHEEL +1 -1
- tests/test_FiQuS.py +1 -1
- tests/test_geometry_generators.py +101 -2
- tests/test_mesh_generators.py +154 -1
- tests/test_solvers.py +115 -21
- tests/utils/fiqus_test_classes.py +85 -21
- tests/utils/generate_reference_files_ConductorAC.py +57 -57
- tests/utils/generate_reference_files_Pancake3D.py +4 -5
- tests/utils/helpers.py +97 -97
- fiqus-2024.7.0.dist-info/METADATA +0 -103
- fiqus-2024.7.0.dist-info/RECORD +0 -79
- {fiqus-2024.7.0.dist-info → fiqus-2024.12.1.dist-info}/top_level.txt +0 -0
fiqus/data/DataFiQuSPancake3D.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import Literal, Optional, Annotated
|
|
1
|
+
from typing import Literal, Optional, Annotated, Union
|
|
2
2
|
from contextvars import ContextVar
|
|
3
3
|
import logging
|
|
4
4
|
import math
|
|
@@ -26,9 +26,9 @@ logger = logging.getLogger(__name__)
|
|
|
26
26
|
# ======================================================================================
|
|
27
27
|
# Available materials: =================================================================
|
|
28
28
|
NormalMaterialName = Literal[
|
|
29
|
-
"Copper", "Hastelloy", "Silver", "Indium", "Stainless Steel"
|
|
29
|
+
"Copper", "Hastelloy", "Silver", "Indium", "Stainless Steel", "Kapton", "G10"
|
|
30
30
|
]
|
|
31
|
-
SuperconductingMaterialName = Literal["HTSSuperPower", "HTSFujikura"]
|
|
31
|
+
SuperconductingMaterialName = Literal["HTSSuperPower", "HTSFujikura", "HTSSucci"]
|
|
32
32
|
# ======================================================================================
|
|
33
33
|
# ======================================================================================
|
|
34
34
|
|
|
@@ -47,6 +47,8 @@ thermalConductivityMacroNames = {
|
|
|
47
47
|
"Silver": "MATERIAL_ThermalConductivity_Silver_T",
|
|
48
48
|
"Indium": "MATERIAL_ThermalConductivity_Indium_T",
|
|
49
49
|
"Stainless Steel": "MATERIAL_ThermalConductivity_SSteel_T",
|
|
50
|
+
"Kapton": "MATERIAL_ThermalConductivity_Kapton_T",
|
|
51
|
+
"G10": "MATERIAL_ThermalConductivity_G10_T",
|
|
50
52
|
}
|
|
51
53
|
heatCapacityMacroNames = {
|
|
52
54
|
"Copper": "MATERIAL_SpecificHeatCapacity_Copper_T",
|
|
@@ -54,30 +56,29 @@ heatCapacityMacroNames = {
|
|
|
54
56
|
"Silver": "MATERIAL_SpecificHeatCapacity_Silver_T",
|
|
55
57
|
"Indium": "MATERIAL_SpecificHeatCapacity_Indium_T",
|
|
56
58
|
"Stainless Steel": "MATERIAL_SpecificHeatCapacity_SSteel_T",
|
|
59
|
+
"Kapton": "MATERIAL_SpecificHeatCapacity_Kapton_T",
|
|
60
|
+
"G10": "MATERIAL_SpecificHeatCapacity_G10_T",
|
|
57
61
|
}
|
|
58
|
-
|
|
59
|
-
"Indium": "
|
|
60
|
-
"Stainless Steel":
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
"
|
|
64
|
-
"Stainless Steel": None,
|
|
62
|
+
getdpTSAStiffnessThermalConductivityMacroNames = {
|
|
63
|
+
"Indium": "MATERIAL_ThermalConductivity_Indium_TSAStiffness_T",
|
|
64
|
+
"Stainless Steel": "MATERIAL_ThermalConductivity_SSteel_TSAStiffness_T",
|
|
65
|
+
"Kapton": "MATERIAL_ThermalConductivity_Kapton_TSAStiffness_T",
|
|
66
|
+
"G10": "MATERIAL_ThermalConductivity_G10_TSAStiffness_T",
|
|
67
|
+
"Copper": "MATERIAL_ThermalConductivity_Copper_TSAStiffness_T",
|
|
65
68
|
}
|
|
66
|
-
|
|
67
|
-
"Indium": "
|
|
68
|
-
"Stainless Steel":
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
"
|
|
72
|
-
"Stainless Steel": "TSA_CFUN_kSteel_T_constantThickness_mass",
|
|
73
|
-
}
|
|
74
|
-
getdpTSAStiffnessThermalConductivityFunctions = {
|
|
75
|
-
"Indium": "TSA_CFUN_kIn_constantThickness_stiffness",
|
|
76
|
-
"Stainless Steel": "TSA_CFUN_kSteel_T_constantThickness_stiffness",
|
|
69
|
+
getdpTSAMassThermalConductivityMacroNames = {
|
|
70
|
+
"Indium": "MATERIAL_ThermalConductivity_Indium_TSAMass_T",
|
|
71
|
+
"Stainless Steel": "MATERIAL_ThermalConductivity_SSteel_TSAMass_T",
|
|
72
|
+
"Kapton": "MATERIAL_ThermalConductivity_Kapton_TSAMass_T",
|
|
73
|
+
"G10": "MATERIAL_ThermalConductivity_G10_TSAMass_T",
|
|
74
|
+
"Copper": "MATERIAL_ThermalConductivity_Copper_TSAMass_T",
|
|
77
75
|
}
|
|
78
|
-
|
|
79
|
-
"Indium": "
|
|
80
|
-
"Stainless Steel": "
|
|
76
|
+
getdpTSAMassHeatCapacityMacroNames = {
|
|
77
|
+
"Indium": "MATERIAL_SpecificHeatCapacity_Indium_TSAMass_T",
|
|
78
|
+
"Stainless Steel": "MATERIAL_SpecificHeatCapacity_SSteel_TSAMass_T",
|
|
79
|
+
"Kapton": "MATERIAL_SpecificHeatCapacity_Kapton_TSAMass_T",
|
|
80
|
+
"G10": "MATERIAL_SpecificHeatCapacity_G10_TSAMass_T",
|
|
81
|
+
"Copper": "MATERIAL_SpecificHeatCapacity_Copper_TSAMass_T",
|
|
81
82
|
}
|
|
82
83
|
getdpTSARHSFunctions = {
|
|
83
84
|
"Indium": "TSA_CFUN_rhoIn_T_constantThickness_rhs",
|
|
@@ -87,9 +88,33 @@ getdpTSATripleFunctions = {
|
|
|
87
88
|
"Indium": "TSA_CFUN_rhoIn_T_constantThickness_triple",
|
|
88
89
|
"Stainless Steel": None,
|
|
89
90
|
}
|
|
91
|
+
getdpTSAOnlyResistivityFunctions = {
|
|
92
|
+
"Indium": "TSA_CFUN_rhoIn_T_constantThickness_fct_only",
|
|
93
|
+
"Stainless Steel": None,
|
|
94
|
+
}
|
|
95
|
+
getdpTSAMassResistivityMacroNames = {
|
|
96
|
+
"Indium": "MATERIAL_Resistivity_Indium_TSAMass_T",
|
|
97
|
+
"Stainless Steel": None,
|
|
98
|
+
"Copper": "MATERIAL_Resistivity_Copper_TSAMass_T",
|
|
99
|
+
}
|
|
100
|
+
getdpTSAStiffnessResistivityMacroNames = {
|
|
101
|
+
"Indium": "MATERIAL_Resistivity_Indium_TSAStiffness_T",
|
|
102
|
+
"Stainless Steel": None,
|
|
103
|
+
"Copper": "MATERIAL_Resistivity_Copper_TSAStiffness_T",
|
|
104
|
+
}
|
|
90
105
|
getdpCriticalCurrentDensityFunctions = {
|
|
91
106
|
"HTSSuperPower": "CFUN_HTS_JcFit_SUPERPOWER_T_B_theta",
|
|
92
107
|
"HTSFujikura": "CFUN_HTS_JcFit_Fujikura_T_B_theta",
|
|
108
|
+
"HTSSucci": "CFUN_HTS_JcFit_Succi_T_B",
|
|
109
|
+
}
|
|
110
|
+
getdpNormalMaterialNames = {
|
|
111
|
+
"Copper": "Copper",
|
|
112
|
+
"Hastelloy": "Hastelloy",
|
|
113
|
+
"Silver": "Silver",
|
|
114
|
+
"Indium": "Indium",
|
|
115
|
+
"Stainless Steel": "StainlessSteel",
|
|
116
|
+
"Kapton": "Kapton",
|
|
117
|
+
"G10": "G10",
|
|
93
118
|
}
|
|
94
119
|
# ======================================================================================
|
|
95
120
|
# ======================================================================================
|
|
@@ -112,6 +137,10 @@ PositionRequiredQuantityName = Literal[
|
|
|
112
137
|
"criticalCurrent",
|
|
113
138
|
"axialComponentOfTheMagneticField",
|
|
114
139
|
"debug",
|
|
140
|
+
"jHTS",
|
|
141
|
+
"currentSharingIndex",
|
|
142
|
+
"arcLength",
|
|
143
|
+
"turnNumber"
|
|
115
144
|
]
|
|
116
145
|
PositionNotRequiredQuantityName = Literal[
|
|
117
146
|
"currentThroughCoil",
|
|
@@ -120,7 +149,9 @@ PositionNotRequiredQuantityName = Literal[
|
|
|
120
149
|
"timeConstant",
|
|
121
150
|
"totalResistiveHeating",
|
|
122
151
|
"magneticEnergy",
|
|
123
|
-
"maximumTemperature"
|
|
152
|
+
"maximumTemperature",
|
|
153
|
+
"cryocoolerAveragePower",
|
|
154
|
+
"cryocoolerAverageTemperature"
|
|
124
155
|
]
|
|
125
156
|
# ======================================================================================
|
|
126
157
|
# ======================================================================================
|
|
@@ -145,6 +176,10 @@ EMQuantities = [
|
|
|
145
176
|
"totalResistiveHeating",
|
|
146
177
|
"magneticEnergy",
|
|
147
178
|
"axialComponentOfTheMagneticField",
|
|
179
|
+
"jHTS",
|
|
180
|
+
"currentSharingIndex",
|
|
181
|
+
"arcLength",
|
|
182
|
+
"turnNumber"
|
|
148
183
|
]
|
|
149
184
|
ThermalQuantities = [
|
|
150
185
|
"temperature",
|
|
@@ -153,6 +188,8 @@ ThermalQuantities = [
|
|
|
153
188
|
"specificHeatCapacity",
|
|
154
189
|
"maximumTemperature",
|
|
155
190
|
"debug",
|
|
191
|
+
"cryocoolerAveragePower",
|
|
192
|
+
"cryocoolerAverageTemperature"
|
|
156
193
|
]
|
|
157
194
|
quantityProperNames = {
|
|
158
195
|
"magneticField": "Magnetic Field",
|
|
@@ -177,6 +214,12 @@ quantityProperNames = {
|
|
|
177
214
|
"timeConstant": "Time Constant",
|
|
178
215
|
"axialComponentOfTheMagneticField": "Axial Component of the Magnetic Field",
|
|
179
216
|
"maximumTemperature": "Maximum Temperature",
|
|
217
|
+
"jHTS": "Current Density in HTS Layer",
|
|
218
|
+
"currentSharingIndex": "Current Sharing Index",
|
|
219
|
+
"cryocoolerAveragePower": "Cryocooler Average Power",
|
|
220
|
+
"arcLength": "Arc Length",
|
|
221
|
+
"turnNumber": "Turn Number",
|
|
222
|
+
"cryocoolerAverageTemperature": "Cryocooler Average Temperature"
|
|
180
223
|
}
|
|
181
224
|
|
|
182
225
|
quantityUnits = {
|
|
@@ -195,13 +238,19 @@ quantityUnits = {
|
|
|
195
238
|
"resistivity": "Ohm*m",
|
|
196
239
|
"thermalConductivity": "W/m*K",
|
|
197
240
|
"specificHeatCapacity": "J/kg*K",
|
|
198
|
-
"jHTSOverjCritical": "
|
|
241
|
+
"jHTSOverjCritical": "-",
|
|
199
242
|
"criticalCurrent": "A",
|
|
200
243
|
"debug": "1",
|
|
201
244
|
"inductance": "H",
|
|
202
245
|
"timeConstant": "s",
|
|
203
246
|
"axialComponentOfTheMagneticField": "T",
|
|
204
247
|
"maximumTemperature": "K",
|
|
248
|
+
"jHTS": "A/m^2",
|
|
249
|
+
"currentSharingIndex": "-",
|
|
250
|
+
"cryocoolerAveragePower": "W",
|
|
251
|
+
"arcLength": "m",
|
|
252
|
+
"turnNumber": "-",
|
|
253
|
+
"cryocoolerAverageTemperature": "K"
|
|
205
254
|
}
|
|
206
255
|
|
|
207
256
|
getdpQuantityNames = {
|
|
@@ -227,6 +276,12 @@ getdpQuantityNames = {
|
|
|
227
276
|
"timeConstant": "RESULT_timeConstant",
|
|
228
277
|
"axialComponentOfTheMagneticField": "RESULT_axialComponentOfTheMagneticField",
|
|
229
278
|
"maximumTemperature": "RESULT_maximumTemperature",
|
|
279
|
+
"jHTS": "RESULT_jHTS",
|
|
280
|
+
"currentSharingIndex": "RESULT_currentSharingIndex",
|
|
281
|
+
"cryocoolerAveragePower": "RESULT_cryocoolerAveragePower",
|
|
282
|
+
"arcLength": "RESULT_arcLength",
|
|
283
|
+
"turnNumber": "RESULT_turnNumber",
|
|
284
|
+
"cryocoolerAverageTemperature": "RESULT_cryocoolerAverageTemperature"
|
|
230
285
|
}
|
|
231
286
|
|
|
232
287
|
getdpPostOperationNames = {
|
|
@@ -252,6 +307,12 @@ getdpPostOperationNames = {
|
|
|
252
307
|
"timeConstant": "POSTOP_timeConstant",
|
|
253
308
|
"axialComponentOfTheMagneticField": "POSTOP_axialComponentOfTheMagneticField",
|
|
254
309
|
"maximumTemperature": "POSTOP_maximumTemperature",
|
|
310
|
+
"jHTS": "POSTOP_jHTS",
|
|
311
|
+
"currentSharingIndex": "POSTOP_currentSharingIndex",
|
|
312
|
+
"cryocoolerAveragePower": "POSTOP_cryocoolerAveragePower",
|
|
313
|
+
"arcLength": "POSTOP_arcLength",
|
|
314
|
+
"turnNumber": "POSTOP_turnNumber",
|
|
315
|
+
"cryocoolerAverageTemperature": "POSTOP_cryocoolerAverageTemperature"
|
|
255
316
|
}
|
|
256
317
|
|
|
257
318
|
# ======================================================================================
|
|
@@ -541,24 +602,20 @@ Pancake3DPosition = Pancake3DPositionInCoordinates | Pancake3DPositionInTurnNumb
|
|
|
541
602
|
# ======================================================================================
|
|
542
603
|
class Pancake3DGeometryWinding(BaseModel):
|
|
543
604
|
# Mandatory:
|
|
544
|
-
|
|
545
|
-
alias="innerRadius",
|
|
605
|
+
innerRadius: PositiveFloat = Field(
|
|
546
606
|
title="Inner Radius",
|
|
547
607
|
description="Inner radius of the winding.",
|
|
548
608
|
)
|
|
549
|
-
|
|
550
|
-
alias="thickness",
|
|
609
|
+
thickness: PositiveFloat = Field(
|
|
551
610
|
title="Winding Thickness",
|
|
552
611
|
description="Thickness of the winding.",
|
|
553
612
|
)
|
|
554
|
-
|
|
555
|
-
alias="numberOfTurns",
|
|
613
|
+
numberOfTurns: float = Field(
|
|
556
614
|
ge=3,
|
|
557
615
|
title="Number of Turns",
|
|
558
616
|
description="Number of turns of the winding.",
|
|
559
617
|
)
|
|
560
|
-
|
|
561
|
-
alias="height",
|
|
618
|
+
height: PositiveFloat = Field(
|
|
562
619
|
title="Winding Height",
|
|
563
620
|
description="Height/width of the winding.",
|
|
564
621
|
)
|
|
@@ -570,41 +627,40 @@ class Pancake3DGeometryWinding(BaseModel):
|
|
|
570
627
|
description="The The name to be used in the mesh..",
|
|
571
628
|
examples=["winding", "myWinding"],
|
|
572
629
|
)
|
|
573
|
-
|
|
630
|
+
numberOfVolumesPerTurn: int = Field(
|
|
574
631
|
default=2,
|
|
575
632
|
validate_default=True,
|
|
576
|
-
alias="numberOfVolumesPerTurn",
|
|
577
633
|
ge=2,
|
|
578
634
|
title="Number of Volumes Per Turn (Advanced Input)",
|
|
579
635
|
description="The number of volumes per turn (CAD related, not physical).",
|
|
580
636
|
)
|
|
581
637
|
|
|
582
|
-
@field_validator("
|
|
638
|
+
@field_validator("numberOfVolumesPerTurn")
|
|
583
639
|
@classmethod
|
|
584
|
-
def
|
|
640
|
+
def check_numberOfVolumesPerTurn(cls, numberOfVolumesPerTurn):
|
|
585
641
|
geometry = geometry_input.get()
|
|
586
642
|
mesh = mesh_input.get()
|
|
587
643
|
|
|
588
|
-
# Check if the
|
|
644
|
+
# Check if the numberOfVolumesPerTurn is compatible swith the azimuthal number of
|
|
589
645
|
# elements per turn:
|
|
590
646
|
for i, ane in enumerate(mesh["winding"]["azimuthalNumberOfElementsPerTurn"]):
|
|
591
|
-
if ane %
|
|
647
|
+
if ane % numberOfVolumesPerTurn != 0:
|
|
592
648
|
raise ValueError(
|
|
593
649
|
"The azimuthal number of elements per turn for the pancake coil"
|
|
594
650
|
f" number {i+1} is ({ane}), but it must be divisible by the number"
|
|
595
|
-
f" of volumes per turn ({geometry['winding']['
|
|
651
|
+
f" of volumes per turn ({geometry['winding']['numberOfVolumesPerTurn']})!"
|
|
596
652
|
" So it needs to be rounded to"
|
|
597
|
-
f" {math.ceil(ane/
|
|
598
|
-
f" {math.floor(ane/
|
|
653
|
+
f" {math.ceil(ane/numberOfVolumesPerTurn)*numberOfVolumesPerTurn:.5f} or"
|
|
654
|
+
f" {math.floor(ane/numberOfVolumesPerTurn)*numberOfVolumesPerTurn:.5f}."
|
|
599
655
|
)
|
|
600
656
|
|
|
601
657
|
structured = checkIfAirOrTerminalMeshIsStructured()
|
|
602
658
|
|
|
603
659
|
if structured:
|
|
604
660
|
# If the mesh is structured, the number of volumes per turn must be 4:
|
|
605
|
-
|
|
661
|
+
numberOfVolumesPerTurn = 4
|
|
606
662
|
|
|
607
|
-
return
|
|
663
|
+
return numberOfVolumesPerTurn
|
|
608
664
|
|
|
609
665
|
@computed_field
|
|
610
666
|
@cached_property
|
|
@@ -720,8 +776,7 @@ class Pancake3DGeometryWinding(BaseModel):
|
|
|
720
776
|
|
|
721
777
|
class Pancake3DGeometryContactLayer(BaseModel):
|
|
722
778
|
# Mandatory:
|
|
723
|
-
|
|
724
|
-
alias="thinShellApproximation",
|
|
779
|
+
thinShellApproximation: bool = Field(
|
|
725
780
|
title="Use Thin Shell Approximation",
|
|
726
781
|
description=(
|
|
727
782
|
"If True, the contact layer will be modeled with 2D shell elements (thin"
|
|
@@ -729,10 +784,13 @@ class Pancake3DGeometryContactLayer(BaseModel):
|
|
|
729
784
|
" with 3D elements."
|
|
730
785
|
),
|
|
731
786
|
)
|
|
732
|
-
|
|
733
|
-
alias="thickness",
|
|
787
|
+
thickness: PositiveFloat = Field(
|
|
734
788
|
title="Contact Layer Thickness",
|
|
735
|
-
description="Thickness of the contact layer."
|
|
789
|
+
description=("Thickness of the contact layer."
|
|
790
|
+
"It is the total thickness of the contact or insulation layer."
|
|
791
|
+
"In particular, for perfect insulation this would be the sum of the insulation layer of the two adjacent CC with an insulation layer of "
|
|
792
|
+
"thickness t/2 on each side."
|
|
793
|
+
),
|
|
736
794
|
)
|
|
737
795
|
|
|
738
796
|
# Optionals:
|
|
@@ -746,24 +804,23 @@ class Pancake3DGeometryContactLayer(BaseModel):
|
|
|
746
804
|
|
|
747
805
|
class Pancake3DGeometryTerminalBase(BaseModel):
|
|
748
806
|
# Mandatory:
|
|
749
|
-
|
|
750
|
-
alias="thickness",
|
|
807
|
+
thickness: PositiveFloat = Field(
|
|
751
808
|
title="Terminal Thickness",
|
|
752
809
|
description="Thickness of the terminal's tube.",
|
|
753
810
|
) # thickness
|
|
754
811
|
|
|
755
|
-
@field_validator("
|
|
812
|
+
@field_validator("thickness")
|
|
756
813
|
@classmethod
|
|
757
|
-
def check_t(cls,
|
|
814
|
+
def check_t(cls, thickness):
|
|
758
815
|
geometry = geometry_input.get()
|
|
759
816
|
|
|
760
|
-
if
|
|
817
|
+
if thickness < geometry["winding"]["thickness"] / 2:
|
|
761
818
|
raise ValueError(
|
|
762
819
|
"Terminal's thickness is smaller than half of the winding's thickness!"
|
|
763
820
|
" Please increase the terminal's thickness."
|
|
764
821
|
)
|
|
765
822
|
|
|
766
|
-
return
|
|
823
|
+
return thickness
|
|
767
824
|
|
|
768
825
|
|
|
769
826
|
class Pancake3DGeometryInnerTerminal(Pancake3DGeometryTerminalBase):
|
|
@@ -780,7 +837,7 @@ class Pancake3DGeometryInnerTerminal(Pancake3DGeometryTerminalBase):
|
|
|
780
837
|
"""Return inner radius of the inner terminal."""
|
|
781
838
|
geometry = geometry_input.get()
|
|
782
839
|
|
|
783
|
-
innerRadius = geometry["winding"]["innerRadius"] - 2 * self.
|
|
840
|
+
innerRadius = geometry["winding"]["innerRadius"] - 2 * self.thickness
|
|
784
841
|
if innerRadius < 0:
|
|
785
842
|
raise ValueError(
|
|
786
843
|
"Inner terminal's radius is smaller than 0! Please decrease the inner"
|
|
@@ -802,15 +859,15 @@ class Pancake3DGeometryOuterTerminal(Pancake3DGeometryTerminalBase):
|
|
|
802
859
|
@cached_property
|
|
803
860
|
def r(self) -> float:
|
|
804
861
|
"""Return outer radius of the outer terminal."""
|
|
805
|
-
outerRadius = getWindingOuterRadius() + 2 * self.
|
|
862
|
+
outerRadius = getWindingOuterRadius() + 2 * self.thickness
|
|
806
863
|
|
|
807
864
|
return outerRadius
|
|
808
865
|
|
|
809
866
|
|
|
810
867
|
class Pancake3DGeometryTerminals(BaseModel):
|
|
811
868
|
# 1) User inputs:
|
|
812
|
-
|
|
813
|
-
|
|
869
|
+
inner: Pancake3DGeometryInnerTerminal = Field()
|
|
870
|
+
outer: Pancake3DGeometryOuterTerminal = Field()
|
|
814
871
|
|
|
815
872
|
# Optionals:
|
|
816
873
|
firstName: str = Field(
|
|
@@ -829,8 +886,7 @@ class Pancake3DGeometryTerminals(BaseModel):
|
|
|
829
886
|
|
|
830
887
|
class Pancake3DGeometryAirBase(BaseModel):
|
|
831
888
|
# Mandatory:
|
|
832
|
-
|
|
833
|
-
alias="axialMargin",
|
|
889
|
+
axialMargin: PositiveFloat = Field(
|
|
834
890
|
title="Axial Margin of the Air",
|
|
835
891
|
description=(
|
|
836
892
|
"Axial margin between the ends of the air and first/last pancake coils."
|
|
@@ -846,7 +902,6 @@ class Pancake3DGeometryAirBase(BaseModel):
|
|
|
846
902
|
)
|
|
847
903
|
shellTransformation: bool = Field(
|
|
848
904
|
default=False,
|
|
849
|
-
alias="shellTransformation",
|
|
850
905
|
title="Use Shell Transformation",
|
|
851
906
|
description=(
|
|
852
907
|
"Generate outer shell air to apply shell transformation if True (GetDP"
|
|
@@ -856,7 +911,6 @@ class Pancake3DGeometryAirBase(BaseModel):
|
|
|
856
911
|
shellTransformationMultiplier: float = Field(
|
|
857
912
|
default=1.2,
|
|
858
913
|
gt=1.1,
|
|
859
|
-
alias="shellTransformationMultiplier",
|
|
860
914
|
title="Shell Transformation Multiplier (Advanced Input)",
|
|
861
915
|
description=(
|
|
862
916
|
"multiply the air's outer dimension by this value to get the shell's outer"
|
|
@@ -875,9 +929,8 @@ class Pancake3DGeometryAirBase(BaseModel):
|
|
|
875
929
|
description="name of the shell volume to be used in the mesh",
|
|
876
930
|
examples=["air-Shell", "myAirShell"],
|
|
877
931
|
)
|
|
878
|
-
|
|
932
|
+
generateGapAirWithFragment: bool = Field(
|
|
879
933
|
default=False,
|
|
880
|
-
alias="generateGapAirWithFragment",
|
|
881
934
|
title="Generate Gap Air with Fragment (Advanced Input)",
|
|
882
935
|
description=(
|
|
883
936
|
"generate the gap air with gmsh/model/occ/fragment if true (CAD related,"
|
|
@@ -885,19 +938,19 @@ class Pancake3DGeometryAirBase(BaseModel):
|
|
|
885
938
|
),
|
|
886
939
|
)
|
|
887
940
|
|
|
888
|
-
@field_validator("
|
|
941
|
+
@field_validator("axialMargin")
|
|
889
942
|
@classmethod
|
|
890
|
-
def
|
|
943
|
+
def check_axialMargin(cls, axialMargin):
|
|
891
944
|
geometry = geometry_input.get()
|
|
892
945
|
windingHeight = geometry["winding"]["height"]
|
|
893
946
|
|
|
894
|
-
if
|
|
947
|
+
if axialMargin < windingHeight / 2:
|
|
895
948
|
raise ValueError(
|
|
896
949
|
"Axial margin is smaller than half of the winding's height! Please"
|
|
897
950
|
" increase the axial margin."
|
|
898
951
|
)
|
|
899
952
|
|
|
900
|
-
return
|
|
953
|
+
return axialMargin
|
|
901
954
|
|
|
902
955
|
@computed_field
|
|
903
956
|
@cached_property
|
|
@@ -910,69 +963,67 @@ class Pancake3DGeometryAirBase(BaseModel):
|
|
|
910
963
|
|
|
911
964
|
class Pancake3DGeometryAirCylinder(Pancake3DGeometryAirBase):
|
|
912
965
|
type: Literal["cylinder"] = Field(default="cylinder", title="Air Type")
|
|
913
|
-
|
|
966
|
+
radius: PositiveFloat = Field(
|
|
914
967
|
default=None,
|
|
915
|
-
alias="radius",
|
|
916
968
|
title="Air Radius",
|
|
917
969
|
description="Radius of the air (for cylinder type air).",
|
|
918
970
|
)
|
|
919
971
|
|
|
920
|
-
@field_validator("
|
|
972
|
+
@field_validator("radius")
|
|
921
973
|
@classmethod
|
|
922
|
-
def check_r(cls,
|
|
974
|
+
def check_r(cls, radius):
|
|
923
975
|
geometry = geometry_input.get()
|
|
924
976
|
outerTerminalOuterRadius = (
|
|
925
977
|
getWindingOuterRadius() + 2 * geometry["terminals"]["outer"]["thickness"]
|
|
926
978
|
)
|
|
927
979
|
|
|
928
|
-
if
|
|
980
|
+
if radius < outerTerminalOuterRadius * 1.5:
|
|
929
981
|
raise ValueError(
|
|
930
982
|
"Radius of the air must be at least 1.5 times the outer radius of the"
|
|
931
983
|
" winding! Please increase the radius of the air."
|
|
932
984
|
)
|
|
933
985
|
|
|
934
|
-
return
|
|
986
|
+
return radius
|
|
935
987
|
|
|
936
988
|
@computed_field
|
|
937
989
|
@cached_property
|
|
938
990
|
def shellOuterRadius(self) -> float:
|
|
939
991
|
"""Return outer radius of the air."""
|
|
940
|
-
shellOuterRadius = self.shellTransformationMultiplier * self.
|
|
992
|
+
shellOuterRadius = self.shellTransformationMultiplier * self.radius
|
|
941
993
|
|
|
942
994
|
return shellOuterRadius
|
|
943
995
|
|
|
944
996
|
|
|
945
997
|
class Pancake3DGeometryAirCuboid(Pancake3DGeometryAirBase):
|
|
946
998
|
type: Literal["cuboid"] = Field(default="cuboid", title="Air Type")
|
|
947
|
-
|
|
999
|
+
sideLength: PositiveFloat = Field(
|
|
948
1000
|
default=None,
|
|
949
|
-
alias="sideLength",
|
|
950
1001
|
title="Air Side Length",
|
|
951
1002
|
description="Side length of the air (for cuboid type air).",
|
|
952
1003
|
)
|
|
953
1004
|
|
|
954
|
-
@field_validator("
|
|
1005
|
+
@field_validator("sideLength")
|
|
955
1006
|
@classmethod
|
|
956
|
-
def check_a(cls,
|
|
1007
|
+
def check_a(cls, sideLength):
|
|
957
1008
|
geometry = geometry_input.get()
|
|
958
1009
|
outerTerminalOuterRadius = (
|
|
959
1010
|
getWindingOuterRadius() + 2 * geometry["terminals"]["outer"]["thickness"]
|
|
960
1011
|
)
|
|
961
1012
|
|
|
962
|
-
if
|
|
1013
|
+
if sideLength / 2 < outerTerminalOuterRadius * 1.5:
|
|
963
1014
|
raise ValueError(
|
|
964
1015
|
"Half of the side length of the air must be at least 1.5 times the"
|
|
965
1016
|
" outer radius of the winding! Please increase the side length of the"
|
|
966
1017
|
" air."
|
|
967
1018
|
)
|
|
968
1019
|
|
|
969
|
-
return
|
|
1020
|
+
return sideLength
|
|
970
1021
|
|
|
971
1022
|
@computed_field
|
|
972
1023
|
@cached_property
|
|
973
1024
|
def shellSideLength(self) -> float:
|
|
974
1025
|
"""Return outer radius of the air."""
|
|
975
|
-
shellSideLength = self.shellTransformationMultiplier * self.
|
|
1026
|
+
shellSideLength = self.shellTransformationMultiplier * self.sideLength
|
|
976
1027
|
|
|
977
1028
|
return shellSideLength
|
|
978
1029
|
|
|
@@ -991,8 +1042,7 @@ Pancake3DGeometryAir = Annotated[
|
|
|
991
1042
|
# ======================================================================================
|
|
992
1043
|
class Pancake3DMeshWinding(BaseModel):
|
|
993
1044
|
# Mandatory:
|
|
994
|
-
|
|
995
|
-
alias="axialNumberOfElements",
|
|
1045
|
+
axialNumberOfElements: list[PositiveInt] | PositiveInt = Field(
|
|
996
1046
|
title="Axial Number of Elements",
|
|
997
1047
|
description=(
|
|
998
1048
|
"The number of axial elements for the whole height of the coil. It can be"
|
|
@@ -1001,8 +1051,7 @@ class Pancake3DMeshWinding(BaseModel):
|
|
|
1001
1051
|
),
|
|
1002
1052
|
)
|
|
1003
1053
|
|
|
1004
|
-
|
|
1005
|
-
alias="azimuthalNumberOfElementsPerTurn",
|
|
1054
|
+
azimuthalNumberOfElementsPerTurn: list[PositiveInt] | PositiveInt = Field(
|
|
1006
1055
|
title="Azimuthal Number of Elements Per Turn",
|
|
1007
1056
|
description=(
|
|
1008
1057
|
"The number of azimuthal elements per turn of the coil. It can be either a"
|
|
@@ -1011,8 +1060,7 @@ class Pancake3DMeshWinding(BaseModel):
|
|
|
1011
1060
|
),
|
|
1012
1061
|
)
|
|
1013
1062
|
|
|
1014
|
-
|
|
1015
|
-
alias="radialNumberOfElementsPerTurn",
|
|
1063
|
+
radialNumberOfElementsPerTurn: list[PositiveInt] | PositiveInt = Field(
|
|
1016
1064
|
title="Winding Radial Number of Elements Per Turn",
|
|
1017
1065
|
description=(
|
|
1018
1066
|
"The number of radial elements per tape of the winding. It can be either a"
|
|
@@ -1022,9 +1070,8 @@ class Pancake3DMeshWinding(BaseModel):
|
|
|
1022
1070
|
)
|
|
1023
1071
|
|
|
1024
1072
|
# Optionals:
|
|
1025
|
-
|
|
1073
|
+
axialDistributionCoefficient: list[PositiveFloat] | PositiveFloat = Field(
|
|
1026
1074
|
default=[1],
|
|
1027
|
-
alias="axialDistributionCoefficient",
|
|
1028
1075
|
title="Axial Bump Coefficients",
|
|
1029
1076
|
description=(
|
|
1030
1077
|
"If 1, it won't affect anything. If smaller than 1, elements will get finer"
|
|
@@ -1049,7 +1096,7 @@ class Pancake3DMeshWinding(BaseModel):
|
|
|
1049
1096
|
),
|
|
1050
1097
|
)
|
|
1051
1098
|
|
|
1052
|
-
@field_validator("
|
|
1099
|
+
@field_validator("axialNumberOfElements", "azimuthalNumberOfElementsPerTurn", "radialNumberOfElementsPerTurn", "axialDistributionCoefficient", "elementType")
|
|
1053
1100
|
@classmethod
|
|
1054
1101
|
def check_inputs(cls, value, info: ValidationInfo):
|
|
1055
1102
|
geometry = geometry_input.get()
|
|
@@ -1101,8 +1148,7 @@ class Pancake3DMeshWinding(BaseModel):
|
|
|
1101
1148
|
|
|
1102
1149
|
class Pancake3DMeshContactLayer(BaseModel):
|
|
1103
1150
|
# Mandatory:
|
|
1104
|
-
|
|
1105
|
-
alias="radialNumberOfElementsPerTurn",
|
|
1151
|
+
radialNumberOfElementsPerTurn: list[PositiveInt] = Field(
|
|
1106
1152
|
title="Contact Layer Radial Number of Elements Per Turn",
|
|
1107
1153
|
description=(
|
|
1108
1154
|
"The number of radial elements per tape of the contact layer. It can be"
|
|
@@ -1111,7 +1157,7 @@ class Pancake3DMeshContactLayer(BaseModel):
|
|
|
1111
1157
|
),
|
|
1112
1158
|
)
|
|
1113
1159
|
|
|
1114
|
-
@field_validator("
|
|
1160
|
+
@field_validator("radialNumberOfElementsPerTurn")
|
|
1115
1161
|
@classmethod
|
|
1116
1162
|
def check_inputs(cls, value):
|
|
1117
1163
|
geometry = geometry_input.get()
|
|
@@ -1179,7 +1225,7 @@ class Pancake3DSolveAir(BaseModel):
|
|
|
1179
1225
|
)
|
|
1180
1226
|
|
|
1181
1227
|
|
|
1182
|
-
class
|
|
1228
|
+
class Pancake3DSolveIcVsLengthList(BaseModel):
|
|
1183
1229
|
lengthValues: list[float] = Field(
|
|
1184
1230
|
title="Tape Length Values",
|
|
1185
1231
|
description="Tape length values that corresponds to criticalCurrentValues.",
|
|
@@ -1188,15 +1234,39 @@ class Pancake3DSolveIcVsLength(BaseModel):
|
|
|
1188
1234
|
title="Critical Current Values",
|
|
1189
1235
|
description="Critical current values that corresponds to lengthValues.",
|
|
1190
1236
|
)
|
|
1237
|
+
lengthUnit: str = Field(
|
|
1238
|
+
title="Unit",
|
|
1239
|
+
description=(
|
|
1240
|
+
"Unit of the critical current values. "
|
|
1241
|
+
"It can be either the arc length in meter or "
|
|
1242
|
+
"the number of turns."
|
|
1243
|
+
),
|
|
1244
|
+
examples=["meter", "turnNumber"],
|
|
1245
|
+
)
|
|
1246
|
+
|
|
1247
|
+
class Pancake3DSolveIcVsLengthCSV(BaseModel):
|
|
1248
|
+
csvFile: str = Field(
|
|
1249
|
+
title="CSV File",
|
|
1250
|
+
description="The path of the CSV file that contains the critical current values.",
|
|
1251
|
+
)
|
|
1252
|
+
|
|
1253
|
+
lengthUnit: str = Field(
|
|
1254
|
+
title="Unit",
|
|
1255
|
+
description=(
|
|
1256
|
+
"Unit of the critical current values. "
|
|
1257
|
+
"It can be either the arc length in meter or "
|
|
1258
|
+
"the number of turns."
|
|
1259
|
+
),
|
|
1260
|
+
examples=["meter", "turnNumber"],
|
|
1261
|
+
)
|
|
1191
1262
|
|
|
1192
1263
|
|
|
1193
1264
|
class Pancake3DSolveMaterialBase(BaseModel):
|
|
1194
1265
|
name: str
|
|
1195
1266
|
|
|
1196
1267
|
# Optionals:
|
|
1197
|
-
|
|
1268
|
+
RRR: PositiveFloat = Field(
|
|
1198
1269
|
default=100,
|
|
1199
|
-
alias="residualResistanceRatio",
|
|
1200
1270
|
title="Residual Resistance Ratio",
|
|
1201
1271
|
description=(
|
|
1202
1272
|
"Residual-resistivity ratio (also known as Residual-resistance ratio or"
|
|
@@ -1204,9 +1274,8 @@ class Pancake3DSolveMaterialBase(BaseModel):
|
|
|
1204
1274
|
" temperature and at 0 K."
|
|
1205
1275
|
),
|
|
1206
1276
|
)
|
|
1207
|
-
|
|
1277
|
+
RRRRefTemp: PositiveFloat = Field(
|
|
1208
1278
|
default=295,
|
|
1209
|
-
alias="residualResistanceRatioReferenceTemperature",
|
|
1210
1279
|
title="Residual Resistance Ratio Reference Temperature",
|
|
1211
1280
|
description="Reference temperature for residual resistance ratio",
|
|
1212
1281
|
)
|
|
@@ -1249,48 +1318,48 @@ class Pancake3DSolveMaterialBase(BaseModel):
|
|
|
1249
1318
|
|
|
1250
1319
|
@computed_field
|
|
1251
1320
|
@cached_property
|
|
1252
|
-
def
|
|
1321
|
+
def getdpTSAMassResistivityMacroName(self) -> str:
|
|
1253
1322
|
"""Return the GetDP function name of the material's mass resistivity."""
|
|
1254
|
-
if self.name not in
|
|
1323
|
+
if self.name not in getdpTSAMassResistivityMacroNames:
|
|
1255
1324
|
return "NOT_DEFINED_IN_DATA_FIQUS_PANCAKE3D"
|
|
1256
1325
|
|
|
1257
|
-
return
|
|
1326
|
+
return getdpTSAMassResistivityMacroNames[self.name]
|
|
1258
1327
|
|
|
1259
1328
|
@computed_field
|
|
1260
1329
|
@cached_property
|
|
1261
|
-
def
|
|
1330
|
+
def getdpTSAStiffnessResistivityMacroName(self) -> str:
|
|
1262
1331
|
"""Return the GetDP function name of the material's stiffness resistivity."""
|
|
1263
|
-
if self.name not in
|
|
1332
|
+
if self.name not in getdpTSAStiffnessResistivityMacroNames:
|
|
1264
1333
|
return "NOT_DEFINED_IN_DATA_FIQUS_PANCAKE3D"
|
|
1265
1334
|
|
|
1266
|
-
return
|
|
1335
|
+
return getdpTSAStiffnessResistivityMacroNames[self.name]
|
|
1267
1336
|
|
|
1268
1337
|
@computed_field
|
|
1269
1338
|
@cached_property
|
|
1270
|
-
def
|
|
1339
|
+
def getdpTSAMassThermalConductivityMacroName(self) -> str:
|
|
1271
1340
|
"""Return the GetDP function name of the material's mass thermal conductivity."""
|
|
1272
|
-
if self.name not in
|
|
1341
|
+
if self.name not in getdpTSAMassThermalConductivityMacroNames:
|
|
1273
1342
|
return "NOT_DEFINED_IN_DATA_FIQUS_PANCAKE3D"
|
|
1274
1343
|
|
|
1275
|
-
return
|
|
1344
|
+
return getdpTSAMassThermalConductivityMacroNames[self.name]
|
|
1276
1345
|
|
|
1277
1346
|
@computed_field
|
|
1278
1347
|
@cached_property
|
|
1279
|
-
def
|
|
1348
|
+
def getdpTSAStiffnessThermalConductivityMacroName(self) -> str:
|
|
1280
1349
|
"""Return the GetDP function name of the material's stiffness thermal conductivity."""
|
|
1281
|
-
if self.name not in
|
|
1350
|
+
if self.name not in getdpTSAStiffnessThermalConductivityMacroNames:
|
|
1282
1351
|
return "NOT_DEFINED_IN_DATA_FIQUS_PANCAKE3D"
|
|
1283
1352
|
|
|
1284
|
-
return
|
|
1353
|
+
return getdpTSAStiffnessThermalConductivityMacroNames[self.name]
|
|
1285
1354
|
|
|
1286
1355
|
@computed_field
|
|
1287
1356
|
@cached_property
|
|
1288
|
-
def
|
|
1357
|
+
def getdpTSAMassHeatCapacityMacroName(self) -> str:
|
|
1289
1358
|
"""Return the GetDP function name of the material's mass heat capacity."""
|
|
1290
|
-
if self.name not in
|
|
1359
|
+
if self.name not in getdpTSAMassHeatCapacityMacroNames:
|
|
1291
1360
|
return "NOT_DEFINED_IN_DATA_FIQUS_PANCAKE3D"
|
|
1292
1361
|
|
|
1293
|
-
return
|
|
1362
|
+
return getdpTSAMassHeatCapacityMacroNames[self.name]
|
|
1294
1363
|
|
|
1295
1364
|
@computed_field
|
|
1296
1365
|
@cached_property
|
|
@@ -1317,33 +1386,43 @@ class Pancake3DSolveNormalMaterial(Pancake3DSolveMaterialBase):
|
|
|
1317
1386
|
title="Material Name",
|
|
1318
1387
|
)
|
|
1319
1388
|
|
|
1389
|
+
@computed_field
|
|
1390
|
+
@cached_property
|
|
1391
|
+
def getdpNormalMaterialGetDPName(self) -> str:
|
|
1392
|
+
"""Return the GetDP material name of the normal conducting material. To make names with spaces like 'Stainless Steel' more robust."""
|
|
1393
|
+
if self.name not in getdpNormalMaterialNames:
|
|
1394
|
+
raise ValueError(
|
|
1395
|
+
f"Normal conducting material '{self.name}' is not defined"
|
|
1396
|
+
" in FiQuS!"
|
|
1397
|
+
)
|
|
1398
|
+
|
|
1399
|
+
return getdpNormalMaterialNames[self.name]
|
|
1400
|
+
|
|
1320
1401
|
|
|
1321
1402
|
class Pancake3DSolveSuperconductingMaterial(Pancake3DSolveMaterialBase):
|
|
1322
1403
|
# Mandatory:
|
|
1323
1404
|
name: SuperconductingMaterialName = Field(
|
|
1324
|
-
title="
|
|
1405
|
+
title="Superconducting Material Name",
|
|
1325
1406
|
)
|
|
1326
1407
|
nValue: PositiveFloat = Field(
|
|
1327
1408
|
default=30,
|
|
1328
|
-
alias="N-Value for E-J Power Law",
|
|
1329
1409
|
description="N-value for E-J power law.",
|
|
1330
1410
|
)
|
|
1331
|
-
IcAtTAndBref: PositiveFloat |
|
|
1332
|
-
|
|
1333
|
-
title="Critical Current at Reference Temperature and Field",
|
|
1411
|
+
IcAtTAndBref: PositiveFloat | Pancake3DSolveIcVsLengthCSV | Pancake3DSolveIcVsLengthList = Field(
|
|
1412
|
+
title="Critical Current at Reference Temperature and Field in A",
|
|
1334
1413
|
description=(
|
|
1335
|
-
"Critical current at reference temperature and magnetic field."
|
|
1414
|
+
"Critical current in A at reference temperature and magnetic field."
|
|
1336
1415
|
"The critical current value will"
|
|
1337
|
-
" change with temperature depending on the superconductor material
|
|
1416
|
+
" change with temperature depending on the superconductor material.Either"
|
|
1338
1417
|
" the same critical current for the whole tape or the critical current with"
|
|
1339
1418
|
" respect to the tape length can be specified. To specify the same critical"
|
|
1340
1419
|
" current for the entire tape, just use a scalar. To specify critical"
|
|
1341
1420
|
" current with respect to the tape length: a CSV file can be used, or"
|
|
1342
1421
|
" lengthValues and criticalCurrentValues can be given as lists. The data"
|
|
1343
|
-
" will be linearly interpolated
|
|
1422
|
+
" will be linearly interpolated.If a CSV file is to be used, the input"
|
|
1344
1423
|
" should be the name of a CSV file (which is in the same folder as the"
|
|
1345
1424
|
" input file) instead of a scalar. The first column of the CSV file will be"
|
|
1346
|
-
" the tape length, and the second column will be the critical current."
|
|
1425
|
+
" the tape length in m, and the second column will be the critical current in A. "
|
|
1347
1426
|
),
|
|
1348
1427
|
examples=[230, "IcVSlength.csv"],
|
|
1349
1428
|
)
|
|
@@ -1367,40 +1446,21 @@ class Pancake3DSolveSuperconductingMaterial(Pancake3DSolveMaterialBase):
|
|
|
1367
1446
|
" A factor of 1 means no scaling such that the HTS layer is isotropic."
|
|
1368
1447
|
),
|
|
1369
1448
|
)
|
|
1370
|
-
minimumPossibleResistivity: NonNegativeFloat = Field(
|
|
1371
|
-
default=0,
|
|
1372
|
-
title="Minimum Possible Resistivity",
|
|
1373
|
-
description=(
|
|
1374
|
-
"The resistivity of the winding won't be lower than this value, no matter"
|
|
1375
|
-
" what."
|
|
1376
|
-
),
|
|
1377
|
-
)
|
|
1378
|
-
maximumPossibleResistivity: PositiveFloat = Field(
|
|
1379
|
-
default=1,
|
|
1380
|
-
title="Maximum Possible Resistivity",
|
|
1381
|
-
description=(
|
|
1382
|
-
"The resistivity of the winding won't be higher than this value, no matter"
|
|
1383
|
-
" what."
|
|
1384
|
-
),
|
|
1385
|
-
)
|
|
1386
1449
|
|
|
1387
1450
|
IcReferenceTemperature: PositiveFloat = Field(
|
|
1388
1451
|
default=77,
|
|
1389
|
-
alias="criticalCurrentReferenceTemperature",
|
|
1390
1452
|
title="Critical Current Reference Temperature",
|
|
1391
1453
|
description="Critical current reference temperature in Kelvin.",
|
|
1392
1454
|
)
|
|
1393
1455
|
|
|
1394
1456
|
IcReferenceBmagnitude: NonNegativeFloat = Field(
|
|
1395
1457
|
default=0.0,
|
|
1396
|
-
alias="criticalCurrentReferenceFieldMagnitude",
|
|
1397
1458
|
title="Critical Current Reference Magnetic Field Magnitude",
|
|
1398
1459
|
description="Critical current reference magnetic field magnitude in Tesla.",
|
|
1399
1460
|
)
|
|
1400
1461
|
|
|
1401
1462
|
IcReferenceBangle: NonNegativeFloat = Field(
|
|
1402
1463
|
default=90.0,
|
|
1403
|
-
alias="criticalCurrentReferenceFieldAngle",
|
|
1404
1464
|
title="Critical Current Reference Magnetic Field Angle",
|
|
1405
1465
|
description= (
|
|
1406
1466
|
"Critical current reference magnetic field angle in degrees."
|
|
@@ -1416,8 +1476,8 @@ class Pancake3DSolveSuperconductingMaterial(Pancake3DSolveMaterialBase):
|
|
|
1416
1476
|
"""Return the critical current values of the material."""
|
|
1417
1477
|
if hasattr(self.IcAtTAndBref, "criticalCurrentValues"):
|
|
1418
1478
|
return self.IcAtTAndBref.criticalCurrentValues
|
|
1419
|
-
elif
|
|
1420
|
-
csv_file_path = pathlib.Path(input_file_path.get()).parent / self.IcAtTAndBref
|
|
1479
|
+
elif hasattr(self.IcAtTAndBref, "csvFile"):
|
|
1480
|
+
csv_file_path = pathlib.Path(input_file_path.get()).parent / self.IcAtTAndBref.csvFile
|
|
1421
1481
|
# return the second column:
|
|
1422
1482
|
IcValues = list(pd.read_csv(csv_file_path, header=None).iloc[:, 1])
|
|
1423
1483
|
for Ic in IcValues:
|
|
@@ -1435,8 +1495,8 @@ class Pancake3DSolveSuperconductingMaterial(Pancake3DSolveMaterialBase):
|
|
|
1435
1495
|
"""Return the length values of the material."""
|
|
1436
1496
|
if hasattr(self.IcAtTAndBref, "lengthValues"):
|
|
1437
1497
|
return self.IcAtTAndBref.lengthValues
|
|
1438
|
-
elif
|
|
1439
|
-
csv_file_path = pathlib.Path(input_file_path.get()).parent / self.IcAtTAndBref
|
|
1498
|
+
elif hasattr(self.IcAtTAndBref, "csvFile"):
|
|
1499
|
+
csv_file_path = pathlib.Path(input_file_path.get()).parent / self.IcAtTAndBref.csvFile
|
|
1440
1500
|
# return the first column:
|
|
1441
1501
|
lengthValues = list(pd.read_csv(csv_file_path, header=None).iloc[:, 0])
|
|
1442
1502
|
for length in lengthValues:
|
|
@@ -1445,6 +1505,21 @@ class Pancake3DSolveSuperconductingMaterial(Pancake3DSolveMaterialBase):
|
|
|
1445
1505
|
return lengthValues
|
|
1446
1506
|
else:
|
|
1447
1507
|
return [1]
|
|
1508
|
+
|
|
1509
|
+
@computed_field
|
|
1510
|
+
@cached_property
|
|
1511
|
+
def IcInArcLength(self) -> int:
|
|
1512
|
+
"""Return 1 if Ic is given as a function of arc length in meters.
|
|
1513
|
+
Return 0 if Ic is given as a function of number of turns.
|
|
1514
|
+
Return -1 if Ic is given as a scalar value.
|
|
1515
|
+
"""
|
|
1516
|
+
if hasattr(self.IcAtTAndBref, "lengthUnit"):
|
|
1517
|
+
if self.IcAtTAndBref.lengthUnit == "meter":
|
|
1518
|
+
return 1
|
|
1519
|
+
else:
|
|
1520
|
+
return 0
|
|
1521
|
+
else:
|
|
1522
|
+
return -1
|
|
1448
1523
|
|
|
1449
1524
|
@computed_field
|
|
1450
1525
|
@cached_property
|
|
@@ -1457,8 +1532,7 @@ class Pancake3DSolveSuperconductingMaterial(Pancake3DSolveMaterialBase):
|
|
|
1457
1532
|
)
|
|
1458
1533
|
|
|
1459
1534
|
return getdpCriticalCurrentDensityFunctions[self.name]
|
|
1460
|
-
|
|
1461
|
-
|
|
1535
|
+
|
|
1462
1536
|
class Pancake3DSolveHTSMaterialBase(BaseModel):
|
|
1463
1537
|
relativeThickness: float = Field(
|
|
1464
1538
|
le=1,
|
|
@@ -1466,7 +1540,7 @@ class Pancake3DSolveHTSMaterialBase(BaseModel):
|
|
|
1466
1540
|
description=(
|
|
1467
1541
|
"Winding tapes generally consist of more than one material. Therefore, when"
|
|
1468
1542
|
" materials are given as a list in winding, their relative thickness,"
|
|
1469
|
-
" (thickness of the material) / (thickness of the
|
|
1543
|
+
" (thickness of the material) / (thickness of the bare conductor), should be"
|
|
1470
1544
|
" specified."
|
|
1471
1545
|
),
|
|
1472
1546
|
)
|
|
@@ -1622,6 +1696,33 @@ class Pancake3DSolveWindingMaterial(Pancake3DSolveMaterial):
|
|
|
1622
1696
|
description="Material properties of the shunt layer.",
|
|
1623
1697
|
)
|
|
1624
1698
|
|
|
1699
|
+
isotropic: Optional[bool] = Field(
|
|
1700
|
+
default=False,
|
|
1701
|
+
title="Isotropic Material",
|
|
1702
|
+
description=(
|
|
1703
|
+
"If True, resistivity and thermal conductivity are isotropic. If False, they are anisotropic. "
|
|
1704
|
+
"The default is anisotropic material."
|
|
1705
|
+
),
|
|
1706
|
+
)
|
|
1707
|
+
|
|
1708
|
+
minimumPossibleResistivity: NonNegativeFloat = Field(
|
|
1709
|
+
default=1e-20,
|
|
1710
|
+
title="Minimum Possible Resistivity",
|
|
1711
|
+
description=(
|
|
1712
|
+
"The resistivity of the winding won't be lower than this value, no matter"
|
|
1713
|
+
" what."
|
|
1714
|
+
),
|
|
1715
|
+
)
|
|
1716
|
+
|
|
1717
|
+
maximumPossibleResistivity: PositiveFloat = Field(
|
|
1718
|
+
default=0.01,
|
|
1719
|
+
title="Maximum Possible Resistivity",
|
|
1720
|
+
description=(
|
|
1721
|
+
"The resistivity of the winding won't be higher than this value, no matter"
|
|
1722
|
+
" what."
|
|
1723
|
+
),
|
|
1724
|
+
)
|
|
1725
|
+
|
|
1625
1726
|
@field_validator("material")
|
|
1626
1727
|
@classmethod
|
|
1627
1728
|
def checkIfRelativeThicknessesSumToOne(cls, material):
|
|
@@ -1698,6 +1799,58 @@ class Pancake3DSolveWindingMaterial(Pancake3DSolveMaterial):
|
|
|
1698
1799
|
"There should be only one superconductor in the winding!"
|
|
1699
1800
|
)
|
|
1700
1801
|
|
|
1802
|
+
class Pancake3DTerminalCryocoolerLumpedMass(Pancake3DSolveMaterial):
|
|
1803
|
+
|
|
1804
|
+
material: Optional[Pancake3DSolveNormalMaterial] = Field(
|
|
1805
|
+
default=Pancake3DSolveNormalMaterial(name="Copper", RRR=295),
|
|
1806
|
+
title="Material",
|
|
1807
|
+
description="Material from STEAM material library.",
|
|
1808
|
+
)
|
|
1809
|
+
|
|
1810
|
+
volume: NonNegativeFloat = Field(
|
|
1811
|
+
default=0,
|
|
1812
|
+
title="Cryocooler Lumped Block Volume",
|
|
1813
|
+
description=(
|
|
1814
|
+
"Volume of the lumped thermal mass between second stage of the cryocooler and pancake coil in m^3. "
|
|
1815
|
+
"A zero value effectively disables the lumped thermal mass between second stage of the cryocooler and pancake coil."
|
|
1816
|
+
)
|
|
1817
|
+
)
|
|
1818
|
+
|
|
1819
|
+
numberOfThinShellElements: PositiveInt = Field(
|
|
1820
|
+
default=1,
|
|
1821
|
+
title="Number of Thin Shell Elements for Cryocooler Lumped Mass",
|
|
1822
|
+
description=(
|
|
1823
|
+
"Number of thin shell elements in the FE formulation (GetDP related, not"
|
|
1824
|
+
" physical and only used when TSA is set to True)"
|
|
1825
|
+
),
|
|
1826
|
+
)
|
|
1827
|
+
|
|
1828
|
+
class Pancake3DTerminalCryocoolerBoundaryCondition(BaseModel):
|
|
1829
|
+
|
|
1830
|
+
coolingPowerMultiplier: NonNegativeFloat = Field(
|
|
1831
|
+
default=1,
|
|
1832
|
+
title="Cooling Power Multiplier",
|
|
1833
|
+
description=(
|
|
1834
|
+
"Multiplier for the cooling power. It can be used to scale"
|
|
1835
|
+
" the cooling power given by the coldhead capacity map by a non-negative float factor."
|
|
1836
|
+
),
|
|
1837
|
+
)
|
|
1838
|
+
|
|
1839
|
+
staticHeatLoadPower: NonNegativeFloat = Field(
|
|
1840
|
+
default=0,
|
|
1841
|
+
title="Static Heat Load Power",
|
|
1842
|
+
description=(
|
|
1843
|
+
"Static heat load power in W. It can be used to add a static heat load"
|
|
1844
|
+
" to the cryocooler, i.e., decrease the power available for cooling. "
|
|
1845
|
+
" The actual cooling power is P(t) = P_cryocooler(T) - P_staticLoad."
|
|
1846
|
+
),
|
|
1847
|
+
)
|
|
1848
|
+
|
|
1849
|
+
lumpedMass: Pancake3DTerminalCryocoolerLumpedMass = Field(
|
|
1850
|
+
default = Pancake3DTerminalCryocoolerLumpedMass(),
|
|
1851
|
+
title="Cryocooler Lumped Mass",
|
|
1852
|
+
description="Thermal lumped mass between second stage of the cryocooler and pancake coil modeled via TSA.",
|
|
1853
|
+
)
|
|
1701
1854
|
|
|
1702
1855
|
class Pancake3DSolveTerminalMaterialAndBoundaryCondition(Pancake3DSolveMaterial):
|
|
1703
1856
|
cooling: Literal["adiabatic", "fixedTemperature", "cryocooler"] = Field(
|
|
@@ -1708,6 +1861,13 @@ class Pancake3DSolveTerminalMaterialAndBoundaryCondition(Pancake3DSolveMaterial)
|
|
|
1708
1861
|
" temperature, or cryocooler."
|
|
1709
1862
|
),
|
|
1710
1863
|
)
|
|
1864
|
+
|
|
1865
|
+
cryocoolerOptions: Optional[Pancake3DTerminalCryocoolerBoundaryCondition] = Field(
|
|
1866
|
+
default=Pancake3DTerminalCryocoolerBoundaryCondition(),
|
|
1867
|
+
title="Cryocooler Boundary Condition",
|
|
1868
|
+
description="Additional inputs for the cryocooler boundary condition.",
|
|
1869
|
+
)
|
|
1870
|
+
|
|
1711
1871
|
transitionNotch: Pancake3DSolveMaterial = Field(
|
|
1712
1872
|
title="Transition Notch Properties",
|
|
1713
1873
|
description="Material properties of the transition notch volume.",
|
|
@@ -1736,7 +1896,6 @@ class Pancake3DSolveToleranceBase(BaseModel):
|
|
|
1736
1896
|
normType: Literal["L1Norm", "MeanL1Norm", "L2Norm", "MeanL2Norm", "LinfNorm"] = (
|
|
1737
1897
|
Field(
|
|
1738
1898
|
default="L2Norm",
|
|
1739
|
-
alias="normType",
|
|
1740
1899
|
title="Norm Type",
|
|
1741
1900
|
description=(
|
|
1742
1901
|
"Sometimes, tolerances return a vector instead of a scalar (ex,"
|
|
@@ -1799,7 +1958,7 @@ class Pancake3DSolveSettingsWithTolerances(BaseModel):
|
|
|
1799
1958
|
if "SolutionVector" not in tolerance.quantity
|
|
1800
1959
|
]
|
|
1801
1960
|
return tolerances
|
|
1802
|
-
|
|
1961
|
+
|
|
1803
1962
|
|
|
1804
1963
|
@computed_field
|
|
1805
1964
|
@cached_property
|
|
@@ -1811,17 +1970,15 @@ class Pancake3DSolveSettingsWithTolerances(BaseModel):
|
|
|
1811
1970
|
if "SolutionVector" in tolerance.quantity
|
|
1812
1971
|
]
|
|
1813
1972
|
return tolerances
|
|
1814
|
-
|
|
1973
|
+
|
|
1815
1974
|
|
|
1816
1975
|
class Pancake3DSolveAdaptiveTimeLoopSettings(Pancake3DSolveSettingsWithTolerances):
|
|
1817
1976
|
# Mandatory:
|
|
1818
1977
|
initialStep: PositiveFloat = Field(
|
|
1819
|
-
alias="initialStep",
|
|
1820
1978
|
title="Initial Step for Adaptive Time Stepping",
|
|
1821
1979
|
description="Initial step for adaptive time stepping",
|
|
1822
1980
|
)
|
|
1823
1981
|
minimumStep: PositiveFloat = Field(
|
|
1824
|
-
alias="minimumStep",
|
|
1825
1982
|
title="Minimum Step for Adaptive Time Stepping",
|
|
1826
1983
|
description=(
|
|
1827
1984
|
"The simulation will be aborted if a finer time step is required than this"
|
|
@@ -1829,7 +1986,6 @@ class Pancake3DSolveAdaptiveTimeLoopSettings(Pancake3DSolveSettingsWithTolerance
|
|
|
1829
1986
|
),
|
|
1830
1987
|
)
|
|
1831
1988
|
maximumStep: PositiveFloat = Field(
|
|
1832
|
-
alias="maximumStep",
|
|
1833
1989
|
description="Bigger steps than this won't be allowed",
|
|
1834
1990
|
)
|
|
1835
1991
|
|
|
@@ -1838,13 +1994,11 @@ class Pancake3DSolveAdaptiveTimeLoopSettings(Pancake3DSolveSettingsWithTolerance
|
|
|
1838
1994
|
"Euler", "Gear_2", "Gear_3", "Gear_4", "Gear_5", "Gear_6"
|
|
1839
1995
|
] = Field(
|
|
1840
1996
|
default="Euler",
|
|
1841
|
-
alias="integrationMethod",
|
|
1842
1997
|
title="Integration Method",
|
|
1843
1998
|
description="Integration method for transient analysis",
|
|
1844
1999
|
)
|
|
1845
2000
|
breakPoints_input: list[float] = Field(
|
|
1846
2001
|
default=[0],
|
|
1847
|
-
alias="breakPoints",
|
|
1848
2002
|
title="Break Points for Adaptive Time Stepping",
|
|
1849
2003
|
description="Make sure to solve the system for these times.",
|
|
1850
2004
|
)
|
|
@@ -1951,7 +2105,6 @@ class Pancake3DSolveTimeBase(BaseModel):
|
|
|
1951
2105
|
# Optionals:
|
|
1952
2106
|
extrapolationOrder: Literal[0, 1, 2, 3] = Field(
|
|
1953
2107
|
default=1,
|
|
1954
|
-
alias="extrapolationOrder",
|
|
1955
2108
|
title="Extrapolation Order",
|
|
1956
2109
|
description=(
|
|
1957
2110
|
"Before solving for the next time steps, the previous solutions can be"
|
|
@@ -1974,8 +2127,7 @@ class Pancake3DSolveTimeBase(BaseModel):
|
|
|
1974
2127
|
|
|
1975
2128
|
class Pancake3DSolveTimeAdaptive(Pancake3DSolveTimeBase):
|
|
1976
2129
|
timeSteppingType: Literal["adaptive"] = "adaptive"
|
|
1977
|
-
|
|
1978
|
-
alias="adaptiveSteppingSettings",
|
|
2130
|
+
adaptiveSteppingSettings: Pancake3DSolveAdaptiveTimeLoopSettings = Field(
|
|
1979
2131
|
title="Adaptive Time Loop Settings",
|
|
1980
2132
|
description=(
|
|
1981
2133
|
"Adaptive time loop settings (only used if stepping type is adaptive)."
|
|
@@ -1988,7 +2140,7 @@ class Pancake3DSolveTimeAdaptive(Pancake3DSolveTimeBase):
|
|
|
1988
2140
|
"""
|
|
1989
2141
|
Checks if the time steps are consistent.
|
|
1990
2142
|
"""
|
|
1991
|
-
if model.
|
|
2143
|
+
if model.adaptiveSteppingSettings.initialStep > model.end:
|
|
1992
2144
|
raise ValueError("Initial time step cannot be greater than the end time!")
|
|
1993
2145
|
|
|
1994
2146
|
return model
|
|
@@ -1996,10 +2148,9 @@ class Pancake3DSolveTimeAdaptive(Pancake3DSolveTimeBase):
|
|
|
1996
2148
|
|
|
1997
2149
|
class Pancake3DSolveTimeFixed(Pancake3DSolveTimeBase):
|
|
1998
2150
|
timeSteppingType: Literal["fixed"] = "fixed"
|
|
1999
|
-
|
|
2151
|
+
fixedSteppingSettings: (
|
|
2000
2152
|
list[Pancake3DSolveFixedLoopInterval] | Pancake3DSolveFixedTimeLoopSettings
|
|
2001
2153
|
) = Field(
|
|
2002
|
-
alias="fixedSteppingSettings",
|
|
2003
2154
|
title="Fixed Time Loop Settings",
|
|
2004
2155
|
description="Fixed time loop settings (only used if stepping type is fixed).",
|
|
2005
2156
|
)
|
|
@@ -2007,27 +2158,27 @@ class Pancake3DSolveTimeFixed(Pancake3DSolveTimeBase):
|
|
|
2007
2158
|
@model_validator(mode="after")
|
|
2008
2159
|
@classmethod
|
|
2009
2160
|
def check_time_steps(cls, model: "Pancake3DSolveTimeFixed"):
|
|
2010
|
-
if isinstance(model.
|
|
2011
|
-
for i in range(len(model.
|
|
2012
|
-
if model.
|
|
2161
|
+
if isinstance(model.fixedSteppingSettings, list):
|
|
2162
|
+
for i in range(len(model.fixedSteppingSettings) - 1):
|
|
2163
|
+
if model.fixedSteppingSettings[i].endTime != model.fixedSteppingSettings[i + 1].startTime:
|
|
2013
2164
|
raise ValueError(
|
|
2014
2165
|
"End time of the previous interval must be equal to the start"
|
|
2015
2166
|
" time of the next interval!"
|
|
2016
2167
|
)
|
|
2017
2168
|
|
|
2018
|
-
if model.
|
|
2169
|
+
if model.fixedSteppingSettings[0].startTime != model.start:
|
|
2019
2170
|
raise ValueError(
|
|
2020
2171
|
"Start time of the first interval must be equal to the start time"
|
|
2021
2172
|
" of the simulation!"
|
|
2022
2173
|
)
|
|
2023
2174
|
|
|
2024
2175
|
else:
|
|
2025
|
-
if model.
|
|
2176
|
+
if model.fixedSteppingSettings.step > model.end:
|
|
2026
2177
|
raise ValueError("Time step cannot be greater than the end time!")
|
|
2027
2178
|
|
|
2028
2179
|
if not (
|
|
2029
2180
|
math.isclose(
|
|
2030
|
-
(model.end - model.start) % model.
|
|
2181
|
+
(model.end - model.start) % model.fixedSteppingSettings.step, 0, abs_tol=1e-8
|
|
2031
2182
|
)
|
|
2032
2183
|
):
|
|
2033
2184
|
raise ValueError("Time interval must be a multiple of the time step!")
|
|
@@ -2041,16 +2192,14 @@ Pancake3DSolveTime = Annotated[
|
|
|
2041
2192
|
|
|
2042
2193
|
class Pancake3DSolveNonlinearSolverSettings(Pancake3DSolveSettingsWithTolerances):
|
|
2043
2194
|
# Optionals:
|
|
2044
|
-
|
|
2195
|
+
maximumNumberOfIterations: PositiveInt = Field(
|
|
2045
2196
|
default=100,
|
|
2046
|
-
alias="maximumNumberOfIterations",
|
|
2047
2197
|
title="Maximum Number of Iterations",
|
|
2048
2198
|
description="Maximum number of iterations allowed for the nonlinear solver.",
|
|
2049
2199
|
)
|
|
2050
2200
|
relaxationFactor: float = Field(
|
|
2051
2201
|
default=0.7,
|
|
2052
2202
|
gt=0,
|
|
2053
|
-
alias="relaxationFactor",
|
|
2054
2203
|
title="Relaxation Factor",
|
|
2055
2204
|
description=(
|
|
2056
2205
|
"Calculated step changes of the solution vector will be multiplied with"
|
|
@@ -2063,33 +2212,34 @@ class Pancake3DSolveInitialConditions(BaseModel):
|
|
|
2063
2212
|
# 1) User inputs:
|
|
2064
2213
|
|
|
2065
2214
|
# Mandatory:
|
|
2066
|
-
|
|
2067
|
-
alias="temperature",
|
|
2215
|
+
temperature: PositiveFloat = Field(
|
|
2068
2216
|
title="Initial Temperature",
|
|
2069
2217
|
description="Initial temperature of the pancake coils.",
|
|
2070
2218
|
)
|
|
2071
2219
|
|
|
2220
|
+
class Pancake3DSolveImposedField(BaseModel):
|
|
2221
|
+
|
|
2222
|
+
imposedAxialField: float = Field(
|
|
2223
|
+
title="Imposed Axial Magnetic Field",
|
|
2224
|
+
description="Imposed axial magnetic field in Tesla. Only constant, purely axial magnetic fields are supported at the moment.",
|
|
2225
|
+
)
|
|
2072
2226
|
|
|
2073
2227
|
class Pancake3DSolveLocalDefect(BaseModel):
|
|
2074
2228
|
# Mandatory:
|
|
2075
2229
|
value: NonNegativeFloat = Field(
|
|
2076
|
-
alias="value",
|
|
2077
2230
|
title="Value",
|
|
2078
2231
|
description="Value of the local defect.",
|
|
2079
2232
|
)
|
|
2080
2233
|
startTurn: NonNegativeFloat = Field(
|
|
2081
|
-
alias="startTurn",
|
|
2082
2234
|
title="Start Turn",
|
|
2083
2235
|
description="Start turn of the local defect.",
|
|
2084
2236
|
)
|
|
2085
2237
|
endTurn: PositiveFloat = Field(
|
|
2086
|
-
alias="endTurn",
|
|
2087
2238
|
title="End Turn",
|
|
2088
2239
|
description="End turn of the local defect.",
|
|
2089
2240
|
)
|
|
2090
2241
|
|
|
2091
2242
|
startTime: NonNegativeFloat = Field(
|
|
2092
|
-
alias="startTime",
|
|
2093
2243
|
title="Start Time",
|
|
2094
2244
|
description="Start time of the local defect.",
|
|
2095
2245
|
)
|
|
@@ -2161,7 +2311,7 @@ class Pancake3DSolveLocalDefect(BaseModel):
|
|
|
2161
2311
|
"whickPancakeCoil (pancake coil number) should be given if there"
|
|
2162
2312
|
" are more than one pancake coil!"
|
|
2163
2313
|
)
|
|
2164
|
-
|
|
2314
|
+
|
|
2165
2315
|
return whichPancakeCoil
|
|
2166
2316
|
|
|
2167
2317
|
@computed_field
|
|
@@ -2194,17 +2344,16 @@ class Pancake3DSolveLocalDefect(BaseModel):
|
|
|
2194
2344
|
class Pancake3DSolveLocalDefects(BaseModel):
|
|
2195
2345
|
# 1) User inputs:
|
|
2196
2346
|
|
|
2197
|
-
|
|
2347
|
+
criticalCurrentDensity: Optional[Pancake3DSolveLocalDefect] = Field(
|
|
2198
2348
|
default=None,
|
|
2199
|
-
alias="criticalCurrentDensity",
|
|
2200
2349
|
title="Local Defect for Critical Current Density",
|
|
2201
2350
|
description="Set critical current density locally.",
|
|
2202
2351
|
)
|
|
2203
2352
|
|
|
2204
|
-
@field_validator("
|
|
2353
|
+
@field_validator("criticalCurrentDensity")
|
|
2205
2354
|
@classmethod
|
|
2206
|
-
def
|
|
2207
|
-
if
|
|
2355
|
+
def check_criticalCurrentDensity_local_defect(cls, criticalCurrentDensity):
|
|
2356
|
+
if criticalCurrentDensity is not None:
|
|
2208
2357
|
solve = solve_input.get()
|
|
2209
2358
|
|
|
2210
2359
|
if "material" in solve["winding"]:
|
|
@@ -2214,15 +2363,164 @@ class Pancake3DSolveLocalDefects(BaseModel):
|
|
|
2214
2363
|
else:
|
|
2215
2364
|
windingMaterials = []
|
|
2216
2365
|
|
|
2217
|
-
superconducting_material_is_used = "HTSSuperPower" in windingMaterials or "HTSFujikura" in windingMaterials
|
|
2366
|
+
superconducting_material_is_used = "HTSSuperPower" in windingMaterials or "HTSFujikura" in windingMaterials or "HTSSucci" in windingMaterials
|
|
2218
2367
|
|
|
2219
2368
|
if not superconducting_material_is_used:
|
|
2220
2369
|
raise ValueError(
|
|
2221
2370
|
"Local defects can only be set if superconducting material is used!"
|
|
2222
2371
|
)
|
|
2223
2372
|
|
|
2224
|
-
return
|
|
2373
|
+
return criticalCurrentDensity
|
|
2374
|
+
|
|
2375
|
+
|
|
2376
|
+
class Pancake3DSolveConvectiveCooling(BaseModel):
|
|
2377
|
+
|
|
2378
|
+
heatTransferCoefficient: Optional[NonNegativeFloat] = Field(
|
|
2379
|
+
default=0,
|
|
2380
|
+
title="Heat Transfer Coefficient",
|
|
2381
|
+
description=(
|
|
2382
|
+
"The heat transfer coefficient for the heat transfer between the winding and the air. "
|
|
2383
|
+
"If zero, no heat transfer to the air is considered."
|
|
2384
|
+
"This feature is only implemented for the thin shell approximation."
|
|
2385
|
+
"At the moment, only constant values are supported."
|
|
2386
|
+
),
|
|
2387
|
+
)
|
|
2388
|
+
|
|
2389
|
+
exteriorBathTemperature: Optional[NonNegativeFloat] = Field(
|
|
2390
|
+
default=4.2,
|
|
2391
|
+
title="Exterior Bath Temperature",
|
|
2392
|
+
description=(
|
|
2393
|
+
"The temperature of the exterior bath for convective cooling boundary condition. "
|
|
2394
|
+
),
|
|
2395
|
+
)
|
|
2396
|
+
|
|
2397
|
+
class Pancake3DSolveEECircuit(BaseModel):
|
|
2398
|
+
|
|
2399
|
+
inductanceInSeriesWithPancakeCoil: Optional[NonNegativeFloat] = Field(
|
|
2400
|
+
default=0,
|
|
2401
|
+
title="Inductance in Series with Pancake Coil",
|
|
2402
|
+
description=(
|
|
2403
|
+
"A lumped inductance in series with the pancake coil to model a bigger coil. "
|
|
2404
|
+
),
|
|
2405
|
+
)
|
|
2225
2406
|
|
|
2407
|
+
enable: bool = Field(
|
|
2408
|
+
default=False,
|
|
2409
|
+
title="Enable Detection Circuit",
|
|
2410
|
+
description=(
|
|
2411
|
+
"Enable the detection circuit for the pancake coil. "
|
|
2412
|
+
),
|
|
2413
|
+
)
|
|
2414
|
+
|
|
2415
|
+
ResistanceEnergyExtractionOpenSwitch: Optional[NonNegativeFloat] = Field(
|
|
2416
|
+
default=1E6,
|
|
2417
|
+
title="Resistance of Energy Extraction Open Switch",
|
|
2418
|
+
description=(
|
|
2419
|
+
"The resistance of the energy extraction switch when modeled as open. "
|
|
2420
|
+
),
|
|
2421
|
+
)
|
|
2422
|
+
|
|
2423
|
+
ResistanceEnergyExtractionClosedSwitch: Optional[NonNegativeFloat] = Field(
|
|
2424
|
+
default=1E-6,
|
|
2425
|
+
title="Resistance of Energy Extraction Closed Switch",
|
|
2426
|
+
description=(
|
|
2427
|
+
"The resistance of the energy extraction switch when modeled as closed. "
|
|
2428
|
+
),
|
|
2429
|
+
)
|
|
2430
|
+
|
|
2431
|
+
ResistanceCrowbarOpenSwitch: Optional[NonNegativeFloat] = Field(
|
|
2432
|
+
default=1E6,
|
|
2433
|
+
title="Resistance of Crowbar Open Switch",
|
|
2434
|
+
description=(
|
|
2435
|
+
"The resistance of the crowbar switch when modeled as open. "
|
|
2436
|
+
),
|
|
2437
|
+
)
|
|
2438
|
+
|
|
2439
|
+
ResistanceCrowbarClosedSwitch: Optional[NonNegativeFloat] = Field(
|
|
2440
|
+
default=1E-6,
|
|
2441
|
+
title="Resistance of Crowbar Closed Switch",
|
|
2442
|
+
description=(
|
|
2443
|
+
"The resistance of the crowbar switch when modeled as closed. "
|
|
2444
|
+
),
|
|
2445
|
+
)
|
|
2446
|
+
|
|
2447
|
+
stopSimulationAtCurrent: Optional[NonNegativeFloat] = Field(
|
|
2448
|
+
default=0,
|
|
2449
|
+
title="Stop Simulation at Current",
|
|
2450
|
+
description=(
|
|
2451
|
+
"If a quench is detected and the current reaches this value, the simulation will be stopped after. "
|
|
2452
|
+
"stopSimulationWaitingTime seconds."
|
|
2453
|
+
),
|
|
2454
|
+
)
|
|
2455
|
+
|
|
2456
|
+
stopSimulationWaitingTime: Optional[NonNegativeFloat] = Field(
|
|
2457
|
+
default=0,
|
|
2458
|
+
title="Stop Simulation Waiting Time",
|
|
2459
|
+
description=(
|
|
2460
|
+
"The time to wait after a quench is detected and the current reaches stopSimulationAtCurrent before stopping the simulation."
|
|
2461
|
+
),
|
|
2462
|
+
)
|
|
2463
|
+
|
|
2464
|
+
# or use t_off from power supply? I don't like it since it's used as time value to turn off and not time interval.
|
|
2465
|
+
TurnOffDeltaTimePowerSupply: Optional[NonNegativeFloat] = Field(
|
|
2466
|
+
default=0,
|
|
2467
|
+
title="Time Interval Between Quench Detection and Power Supply Turn Off",
|
|
2468
|
+
description=(
|
|
2469
|
+
"The time it takes for the power supply to be turned off after quench detection. "
|
|
2470
|
+
"A linear ramp-down is assumed between the time of quench detection and the time of power supply turn off."
|
|
2471
|
+
),
|
|
2472
|
+
)
|
|
2473
|
+
|
|
2474
|
+
class Pancake3DSolvePowerDensity(BaseModel):
|
|
2475
|
+
power: Optional[NonNegativeFloat] = Field(
|
|
2476
|
+
default=0,
|
|
2477
|
+
title="Power Density",
|
|
2478
|
+
description=(
|
|
2479
|
+
"The power in W for an imposed power density in the winding. "
|
|
2480
|
+
"'startTime', 'endTime', 'startTurn', and 'endTurn' "
|
|
2481
|
+
"are also required to be set."
|
|
2482
|
+
),
|
|
2483
|
+
)
|
|
2484
|
+
|
|
2485
|
+
startTime: Optional[NonNegativeFloat] = Field(
|
|
2486
|
+
default=0,
|
|
2487
|
+
title="Power Density Start Time",
|
|
2488
|
+
description=(
|
|
2489
|
+
"The start time for the imposed power density in the winding. "
|
|
2490
|
+
"'power', 'endTime', 'startTurn', and 'endTurn' "
|
|
2491
|
+
"are also required to be set."
|
|
2492
|
+
),
|
|
2493
|
+
)
|
|
2494
|
+
|
|
2495
|
+
endTime: Optional[NonNegativeFloat] = Field(
|
|
2496
|
+
default=0,
|
|
2497
|
+
title="Power Density End Time",
|
|
2498
|
+
description=(
|
|
2499
|
+
"The end time for the imposed power density in the winding. "
|
|
2500
|
+
"'power', 'startTime', 'startTurn', and 'endTurn' "
|
|
2501
|
+
"are also required to be set."
|
|
2502
|
+
),
|
|
2503
|
+
)
|
|
2504
|
+
|
|
2505
|
+
startArcLength: Optional[NonNegativeFloat] = Field(
|
|
2506
|
+
default=0,
|
|
2507
|
+
title="Power Density Start Arc Length",
|
|
2508
|
+
description=(
|
|
2509
|
+
"The start arc length in m for the imposed power density in the winding. "
|
|
2510
|
+
"'power', 'startTime', 'endTime', and 'endArcLength' "
|
|
2511
|
+
"are also required to be set."
|
|
2512
|
+
),
|
|
2513
|
+
)
|
|
2514
|
+
|
|
2515
|
+
endArcLength: Optional[NonNegativeFloat] = Field(
|
|
2516
|
+
default=0,
|
|
2517
|
+
title="Power Density End Arc Length",
|
|
2518
|
+
description=(
|
|
2519
|
+
"The end arc length in m for the imposed power density in the winding. "
|
|
2520
|
+
"'power', 'startTime', 'endTime', and 'startArcLength' "
|
|
2521
|
+
"are also required to be set."
|
|
2522
|
+
),
|
|
2523
|
+
)
|
|
2226
2524
|
|
|
2227
2525
|
class Pancake3DSolveQuantityBase(BaseModel):
|
|
2228
2526
|
# Mandatory:
|
|
@@ -2252,7 +2550,7 @@ class Pancake3DSolveQuantityBase(BaseModel):
|
|
|
2252
2550
|
|
|
2253
2551
|
class Pancake3DSolveSaveQuantity(Pancake3DSolveQuantityBase):
|
|
2254
2552
|
# Optionals:
|
|
2255
|
-
timesToBeSaved: list[float] = Field(
|
|
2553
|
+
timesToBeSaved: Union[list[float], None] = Field(
|
|
2256
2554
|
default=None,
|
|
2257
2555
|
title="Times to be Saved",
|
|
2258
2556
|
description=(
|
|
@@ -2264,7 +2562,8 @@ class Pancake3DSolveSaveQuantity(Pancake3DSolveQuantityBase):
|
|
|
2264
2562
|
@field_validator("timesToBeSaved")
|
|
2265
2563
|
@classmethod
|
|
2266
2564
|
def updateGlobalBreakPointsList(cls, timesToBeSaved):
|
|
2267
|
-
|
|
2565
|
+
if timesToBeSaved is not None:
|
|
2566
|
+
all_break_points.extend(timesToBeSaved)
|
|
2268
2567
|
return timesToBeSaved
|
|
2269
2568
|
|
|
2270
2569
|
@field_validator("timesToBeSaved")
|
|
@@ -2274,11 +2573,12 @@ class Pancake3DSolveSaveQuantity(Pancake3DSolveQuantityBase):
|
|
|
2274
2573
|
start_time = solve["time"]["start"]
|
|
2275
2574
|
end_time = solve["time"]["end"]
|
|
2276
2575
|
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2576
|
+
if timesToBeSaved is not None:
|
|
2577
|
+
for time in timesToBeSaved:
|
|
2578
|
+
if time < start_time or time > end_time:
|
|
2579
|
+
raise ValueError(
|
|
2580
|
+
"Times to be saved should be between the start and end times!"
|
|
2581
|
+
)
|
|
2282
2582
|
|
|
2283
2583
|
|
|
2284
2584
|
# ======================================================================================
|
|
@@ -2352,11 +2652,11 @@ class Pancake3DPostprocessTimeSeriesPlotPositionNotRequired(
|
|
|
2352
2652
|
)
|
|
2353
2653
|
|
|
2354
2654
|
|
|
2355
|
-
Pancake3DPostprocessTimeSeriesPlot = Annotated[
|
|
2655
|
+
Pancake3DPostprocessTimeSeriesPlot = Optional[Annotated[
|
|
2356
2656
|
Pancake3DPostprocessTimeSeriesPlotPositionRequired
|
|
2357
2657
|
| Pancake3DPostprocessTimeSeriesPlotPositionNotRequired,
|
|
2358
2658
|
Field(discriminator="quantity"),
|
|
2359
|
-
]
|
|
2659
|
+
]]
|
|
2360
2660
|
|
|
2361
2661
|
|
|
2362
2662
|
class Pancake3DPostprocessMagneticFieldOnPlane(BaseModel):
|
|
@@ -2379,12 +2679,12 @@ class Pancake3DPostprocessMagneticFieldOnPlane(BaseModel):
|
|
|
2379
2679
|
default="linear",
|
|
2380
2680
|
title="Interpolation Method",
|
|
2381
2681
|
description=(
|
|
2382
|
-
"Interpolation type for the plot
|
|
2682
|
+
"Interpolation type for the plot.Because of the FEM basis function"
|
|
2383
2683
|
" selections of FiQuS, each mesh element has a constant magnetic field"
|
|
2384
2684
|
" vector. Therefore, for smooth 2D plots, interpolation can be"
|
|
2385
|
-
" used
|
|
2386
|
-
" the plotting point
|
|
2387
|
-
" magnetic field values
|
|
2685
|
+
" used.Types:nearest: it will plot the nearest magnetic field value to"
|
|
2686
|
+
" the plotting point.linear: it will do linear interpolation to the"
|
|
2687
|
+
" magnetic field values.cubic: it will do cubic interpolation to the"
|
|
2388
2688
|
" magnetic field values."
|
|
2389
2689
|
),
|
|
2390
2690
|
)
|
|
@@ -2616,48 +2916,40 @@ class Pancake3DGeometry(BaseModel):
|
|
|
2616
2916
|
)
|
|
2617
2917
|
|
|
2618
2918
|
# Mandatory:
|
|
2619
|
-
|
|
2919
|
+
numberOfPancakes: PositiveInt = Field(
|
|
2620
2920
|
ge=1,
|
|
2621
|
-
alias="numberOfPancakes",
|
|
2622
2921
|
title="Number of Pancakes",
|
|
2623
2922
|
description="Number of pancake coils stacked on top of each other.",
|
|
2624
2923
|
)
|
|
2625
2924
|
|
|
2626
|
-
|
|
2627
|
-
alias="gapBetweenPancakes",
|
|
2925
|
+
gapBetweenPancakes: PositiveFloat = Field(
|
|
2628
2926
|
title="Gap Between Pancakes",
|
|
2629
2927
|
description="Gap distance between the pancake coils.",
|
|
2630
2928
|
)
|
|
2631
2929
|
|
|
2632
|
-
|
|
2633
|
-
alias="winding",
|
|
2930
|
+
winding: Pancake3DGeometryWinding = Field(
|
|
2634
2931
|
title="Winding Geometry",
|
|
2635
2932
|
description="This dictionary contains the winding geometry information.",
|
|
2636
2933
|
)
|
|
2637
2934
|
|
|
2638
|
-
|
|
2639
|
-
alias="contactLayer",
|
|
2935
|
+
contactLayer: Pancake3DGeometryContactLayer = Field(
|
|
2640
2936
|
title="Contact Layer Geometry",
|
|
2641
2937
|
description="This dictionary contains the contact layer geometry information.",
|
|
2642
2938
|
)
|
|
2643
2939
|
|
|
2644
|
-
|
|
2645
|
-
alias="terminals",
|
|
2940
|
+
terminals: Pancake3DGeometryTerminals = Field(
|
|
2646
2941
|
title="Terminals Geometry",
|
|
2647
2942
|
description="This dictionary contains the terminals geometry information.",
|
|
2648
2943
|
)
|
|
2649
2944
|
|
|
2650
|
-
|
|
2651
|
-
alias="air",
|
|
2945
|
+
air: Pancake3DGeometryAir = Field(
|
|
2652
2946
|
title="Air Geometry",
|
|
2653
2947
|
description="This dictionary contains the air geometry information.",
|
|
2654
2948
|
)
|
|
2655
2949
|
|
|
2656
2950
|
# Optionals:
|
|
2657
|
-
|
|
2951
|
+
dimensionTolerance: PositiveFloat = Field(
|
|
2658
2952
|
default=1e-8,
|
|
2659
|
-
gt=1e-5,
|
|
2660
|
-
alias="dimensionTolerance",
|
|
2661
2953
|
description="dimension tolerance (CAD related, not physical)",
|
|
2662
2954
|
)
|
|
2663
2955
|
pancakeBoundaryName: str = Field(
|
|
@@ -2677,34 +2969,41 @@ class Pancake3DGeometry(BaseModel):
|
|
|
2677
2969
|
|
|
2678
2970
|
class Pancake3DMesh(BaseModel):
|
|
2679
2971
|
# Mandatory:
|
|
2680
|
-
|
|
2681
|
-
alias="winding",
|
|
2972
|
+
winding: Pancake3DMeshWinding = Field(
|
|
2682
2973
|
title="Winding Mesh",
|
|
2683
2974
|
description="This dictionary contains the winding mesh information.",
|
|
2684
2975
|
)
|
|
2685
|
-
|
|
2686
|
-
alias="contactLayer",
|
|
2976
|
+
contactLayer: Pancake3DMeshContactLayer = Field(
|
|
2687
2977
|
title="Contact Layer Mesh",
|
|
2688
2978
|
description="This dictionary contains the contact layer mesh information.",
|
|
2689
2979
|
)
|
|
2690
2980
|
|
|
2691
2981
|
# Optionals:
|
|
2692
|
-
|
|
2982
|
+
terminals: Pancake3DMeshAirAndTerminals = Field(
|
|
2693
2983
|
default=Pancake3DMeshAirAndTerminals(),
|
|
2694
|
-
alias="terminals",
|
|
2695
2984
|
title="Terminal Mesh",
|
|
2696
2985
|
description="This dictionary contains the terminal mesh information.",
|
|
2697
2986
|
)
|
|
2698
|
-
|
|
2987
|
+
air: Pancake3DMeshAirAndTerminals = Field(
|
|
2699
2988
|
default=Pancake3DMeshAirAndTerminals(),
|
|
2700
|
-
alias="air",
|
|
2701
2989
|
title="Air Mesh",
|
|
2702
2990
|
description="This dictionary contains the air mesh information.",
|
|
2703
2991
|
)
|
|
2704
2992
|
|
|
2993
|
+
computeCohomologyForInsulating: bool = Field(
|
|
2994
|
+
default=True,
|
|
2995
|
+
title="Compute Cohomology for Insulating",
|
|
2996
|
+
description=(
|
|
2997
|
+
"Expert option only. "
|
|
2998
|
+
"If False, the cohomology regions needed for simulating an insulating coil"
|
|
2999
|
+
"will not be computed. This will reduce the time spent for the meshing "
|
|
3000
|
+
"or more accurately the cohomology computing phase. BEWARE: The simulation "
|
|
3001
|
+
"will fail if set to False and a perfectlyInsulating coil is simulated."
|
|
3002
|
+
),
|
|
3003
|
+
)
|
|
3004
|
+
|
|
2705
3005
|
# Mandatory:
|
|
2706
|
-
|
|
2707
|
-
alias="minimumElementSize",
|
|
3006
|
+
minimumElementSize: PositiveFloat = Field(
|
|
2708
3007
|
title="Minimum Element Size",
|
|
2709
3008
|
description=(
|
|
2710
3009
|
"The minimum mesh element size in terms of the largest mesh size in the"
|
|
@@ -2713,8 +3012,7 @@ class Pancake3DMesh(BaseModel):
|
|
|
2713
3012
|
" size as it gets away from the winding."
|
|
2714
3013
|
),
|
|
2715
3014
|
)
|
|
2716
|
-
|
|
2717
|
-
alias="maximumElementSize",
|
|
3015
|
+
maximumElementSize: PositiveFloat = Field(
|
|
2718
3016
|
title="Maximum Element Size",
|
|
2719
3017
|
description=(
|
|
2720
3018
|
"The maximum mesh element size in terms of the largest mesh size in the"
|
|
@@ -2724,16 +3022,16 @@ class Pancake3DMesh(BaseModel):
|
|
|
2724
3022
|
),
|
|
2725
3023
|
)
|
|
2726
3024
|
|
|
2727
|
-
@field_validator("
|
|
3025
|
+
@field_validator("maximumElementSize")
|
|
2728
3026
|
@classmethod
|
|
2729
|
-
def check_rel_size_max(cls,
|
|
2730
|
-
if
|
|
3027
|
+
def check_rel_size_max(cls, maximumElementSize, info: ValidationInfo):
|
|
3028
|
+
if maximumElementSize < info.data["minimumElementSize"]:
|
|
2731
3029
|
raise ValueError(
|
|
2732
3030
|
"Maximum mesh element size (maximumElementSize) cannot be smaller than"
|
|
2733
3031
|
" the minimum mesh element size (minimumElementSize)!"
|
|
2734
3032
|
)
|
|
2735
3033
|
|
|
2736
|
-
return
|
|
3034
|
+
return maximumElementSize
|
|
2737
3035
|
|
|
2738
3036
|
@computed_field
|
|
2739
3037
|
@cached_property
|
|
@@ -2744,7 +3042,7 @@ class Pancake3DMesh(BaseModel):
|
|
|
2744
3042
|
meshLengthsPerElement = []
|
|
2745
3043
|
|
|
2746
3044
|
# azimuthal elements:
|
|
2747
|
-
for numberOfElements in self.
|
|
3045
|
+
for numberOfElements in self.winding.azimuthalNumberOfElementsPerTurn:
|
|
2748
3046
|
terminalOuterRadius = (
|
|
2749
3047
|
getWindingOuterRadius()
|
|
2750
3048
|
+ 2 * geometry["terminals"]["outer"]["thickness"]
|
|
@@ -2754,25 +3052,25 @@ class Pancake3DMesh(BaseModel):
|
|
|
2754
3052
|
)
|
|
2755
3053
|
|
|
2756
3054
|
# radial elements:
|
|
2757
|
-
for numberOfElements in self.
|
|
3055
|
+
for numberOfElements in self.winding.radialNumberOfElementsPerTurn:
|
|
2758
3056
|
meshLengthsPerElement.append(
|
|
2759
3057
|
geometry["winding"]["thickness"] / numberOfElements
|
|
2760
3058
|
)
|
|
2761
3059
|
|
|
2762
3060
|
if not geometry["contactLayer"]["thinShellApproximation"]:
|
|
2763
3061
|
# radial elements:
|
|
2764
|
-
for numberOfElements in self.
|
|
3062
|
+
for numberOfElements in self.contactLayer.radialNumberOfElementsPerTurn:
|
|
2765
3063
|
meshLengthsPerElement.append(
|
|
2766
3064
|
geometry["contactLayer"]["thickness"] / numberOfElements
|
|
2767
3065
|
)
|
|
2768
3066
|
|
|
2769
3067
|
# axial elements:
|
|
2770
|
-
for numberOfElements in self.
|
|
3068
|
+
for numberOfElements in self.winding.axialNumberOfElements:
|
|
2771
3069
|
meshLengthsPerElement.append(
|
|
2772
3070
|
geometry["winding"]["height"] / numberOfElements
|
|
2773
3071
|
)
|
|
2774
3072
|
|
|
2775
|
-
return max(meshLengthsPerElement) * self.
|
|
3073
|
+
return max(meshLengthsPerElement) * self.minimumElementSize
|
|
2776
3074
|
|
|
2777
3075
|
@computed_field
|
|
2778
3076
|
@cached_property
|
|
@@ -2783,7 +3081,7 @@ class Pancake3DMesh(BaseModel):
|
|
|
2783
3081
|
meshLengthsPerElement = []
|
|
2784
3082
|
|
|
2785
3083
|
# azimuthal elements:
|
|
2786
|
-
for numberOfElements in self.
|
|
3084
|
+
for numberOfElements in self.winding.azimuthalNumberOfElementsPerTurn:
|
|
2787
3085
|
terminalOuterRadius = (
|
|
2788
3086
|
getWindingOuterRadius()
|
|
2789
3087
|
+ 2 * geometry["terminals"]["outer"]["thickness"]
|
|
@@ -2793,25 +3091,25 @@ class Pancake3DMesh(BaseModel):
|
|
|
2793
3091
|
)
|
|
2794
3092
|
|
|
2795
3093
|
# radial elements:
|
|
2796
|
-
for numberOfElements in self.
|
|
3094
|
+
for numberOfElements in self.winding.radialNumberOfElementsPerTurn:
|
|
2797
3095
|
meshLengthsPerElement.append(
|
|
2798
3096
|
geometry["winding"]["thickness"] / numberOfElements
|
|
2799
3097
|
)
|
|
2800
3098
|
|
|
2801
3099
|
if not geometry["contactLayer"]["thinShellApproximation"]:
|
|
2802
3100
|
# radial elements:
|
|
2803
|
-
for numberOfElements in self.
|
|
3101
|
+
for numberOfElements in self.contactLayer.radialNumberOfElementsPerTurn:
|
|
2804
3102
|
meshLengthsPerElement.append(
|
|
2805
3103
|
geometry["contactLayer"]["thickness"] / numberOfElements
|
|
2806
3104
|
)
|
|
2807
3105
|
|
|
2808
3106
|
# axial elements:
|
|
2809
|
-
for numberOfElements in self.
|
|
3107
|
+
for numberOfElements in self.winding.axialNumberOfElements:
|
|
2810
3108
|
meshLengthsPerElement.append(
|
|
2811
3109
|
geometry["winding"]["height"] / numberOfElements
|
|
2812
3110
|
)
|
|
2813
3111
|
|
|
2814
|
-
return max(meshLengthsPerElement) * self.
|
|
3112
|
+
return max(meshLengthsPerElement) * self.maximumElementSize
|
|
2815
3113
|
|
|
2816
3114
|
@computed_field
|
|
2817
3115
|
@cached_property
|
|
@@ -2849,50 +3147,48 @@ class Pancake3DMesh(BaseModel):
|
|
|
2849
3147
|
|
|
2850
3148
|
class Pancake3DSolve(BaseModel):
|
|
2851
3149
|
# 1) User inputs:
|
|
2852
|
-
|
|
2853
|
-
alias="time",
|
|
3150
|
+
time: Pancake3DSolveTime = Field(
|
|
2854
3151
|
title="Time Settings",
|
|
2855
3152
|
description="All the time related settings for transient analysis.",
|
|
2856
3153
|
)
|
|
2857
3154
|
|
|
2858
|
-
|
|
2859
|
-
alias="nonlinearSolver",
|
|
3155
|
+
nonlinearSolver: Optional[Pancake3DSolveNonlinearSolverSettings] = Field(
|
|
2860
3156
|
title="Nonlinear Solver Settings",
|
|
2861
3157
|
description="All the nonlinear solver related settings.",
|
|
2862
3158
|
)
|
|
2863
3159
|
|
|
2864
|
-
|
|
2865
|
-
alias="winding",
|
|
3160
|
+
winding: Pancake3DSolveWindingMaterial = Field(
|
|
2866
3161
|
title="Winding Properties",
|
|
2867
3162
|
description="This dictionary contains the winding material properties.",
|
|
2868
3163
|
)
|
|
2869
|
-
|
|
2870
|
-
alias="contactLayer",
|
|
3164
|
+
contactLayer: Pancake3DSolveContactLayerMaterial = Field(
|
|
2871
3165
|
title="Contact Layer Properties",
|
|
2872
3166
|
description="This dictionary contains the contact layer material properties.",
|
|
2873
3167
|
)
|
|
2874
|
-
|
|
2875
|
-
alias="terminals",
|
|
3168
|
+
terminals: Pancake3DSolveTerminalMaterialAndBoundaryCondition = Field(
|
|
2876
3169
|
title="Terminals Properties",
|
|
2877
3170
|
description=(
|
|
2878
3171
|
"This dictionary contains the terminals material properties and cooling"
|
|
2879
3172
|
" condition."
|
|
2880
3173
|
),
|
|
2881
3174
|
)
|
|
2882
|
-
|
|
2883
|
-
alias="air",
|
|
3175
|
+
air: Pancake3DSolveAir = Field(
|
|
2884
3176
|
title="Air Properties",
|
|
2885
3177
|
description="This dictionary contains the air material properties.",
|
|
2886
3178
|
)
|
|
2887
3179
|
|
|
2888
|
-
|
|
2889
|
-
alias="initialConditions",
|
|
3180
|
+
initialConditions: Pancake3DSolveInitialConditions = Field(
|
|
2890
3181
|
title="Initial Conditions",
|
|
2891
3182
|
description="Initial conditions of the problem.",
|
|
2892
3183
|
)
|
|
2893
3184
|
|
|
2894
|
-
|
|
2895
|
-
|
|
3185
|
+
boundaryConditions: Union[Literal["vanishingTangentialElectricField"], Pancake3DSolveImposedField] = Field(
|
|
3186
|
+
default="vanishingTangentialElectricField",
|
|
3187
|
+
title="Boundary Conditions",
|
|
3188
|
+
description="Boundary conditions of the problem.",
|
|
3189
|
+
)
|
|
3190
|
+
|
|
3191
|
+
quantitiesToBeSaved: list[Pancake3DSolveSaveQuantity] = Field(
|
|
2896
3192
|
default=None,
|
|
2897
3193
|
title="Quantities to be Saved",
|
|
2898
3194
|
description="List of quantities to be saved.",
|
|
@@ -2903,7 +3199,7 @@ class Pancake3DSolve(BaseModel):
|
|
|
2903
3199
|
Field(
|
|
2904
3200
|
title="Simulation Type",
|
|
2905
3201
|
description=(
|
|
2906
|
-
"FiQuS/Pancake3D can solve only
|
|
3202
|
+
"FiQuS/Pancake3D can solve only electromagnetic and thermal or"
|
|
2907
3203
|
" electromagnetic and thermal coupled. In the weaklyCoupled setting,"
|
|
2908
3204
|
" thermal and electromagnetics systems will be put into different"
|
|
2909
3205
|
" matrices, whereas in the stronglyCoupled setting, they all will be"
|
|
@@ -2920,7 +3216,6 @@ class Pancake3DSolve(BaseModel):
|
|
|
2920
3216
|
|
|
2921
3217
|
localDefects: Pancake3DSolveLocalDefects = Field(
|
|
2922
3218
|
default=Pancake3DSolveLocalDefects(),
|
|
2923
|
-
alias="localDefects",
|
|
2924
3219
|
title="Local Defects",
|
|
2925
3220
|
description=(
|
|
2926
3221
|
"Local defects (like making a small part of the winding normal conductor at"
|
|
@@ -2934,7 +3229,9 @@ class Pancake3DSolve(BaseModel):
|
|
|
2934
3229
|
description=(
|
|
2935
3230
|
"The simulation is continued from an existing .res file. The .res file is"
|
|
2936
3231
|
" from a previous computation on the same geometry and mesh. The .res file"
|
|
2937
|
-
" is taken from the folder Solution_<<initFromPrevious
|
|
3232
|
+
" is taken from the folder Solution_<<initFromPrevious>>."
|
|
3233
|
+
" IMPORTANT: When the option is used, the start time should be identical to the last "
|
|
3234
|
+
" time value for the <<initFromPrevious>> simulation."
|
|
2938
3235
|
),
|
|
2939
3236
|
)
|
|
2940
3237
|
|
|
@@ -2948,15 +3245,101 @@ class Pancake3DSolve(BaseModel):
|
|
|
2948
3245
|
),
|
|
2949
3246
|
)
|
|
2950
3247
|
|
|
3248
|
+
voltageTapPositions: Optional[list[Pancake3DPosition]] = Field(
|
|
3249
|
+
default=[],
|
|
3250
|
+
title="Voltage Tap Positions",
|
|
3251
|
+
description=(
|
|
3252
|
+
"List of voltage tap positions. The "
|
|
3253
|
+
"position can be given in the form of a list of [x, y, z] coordinates or "
|
|
3254
|
+
"as turnNumber and number of pancake coil."
|
|
3255
|
+
),
|
|
3256
|
+
)
|
|
3257
|
+
|
|
3258
|
+
EECircuit: Optional[Pancake3DSolveEECircuit] = Field(
|
|
3259
|
+
default = Pancake3DSolveEECircuit(),
|
|
3260
|
+
title="Detection Circuit",
|
|
3261
|
+
description=(
|
|
3262
|
+
"This dictionary contains the detection circuit settings."
|
|
3263
|
+
),
|
|
3264
|
+
)
|
|
3265
|
+
|
|
3266
|
+
noOfMPITasks: Optional[Union[bool, int]] = Field(
|
|
3267
|
+
default=False,
|
|
3268
|
+
title="No. of tasks for MPI parallel run of GetDP",
|
|
3269
|
+
description=(
|
|
3270
|
+
"If integer, GetDP will be run in parallel using MPI. This is only valid"
|
|
3271
|
+
" if MPI is installed on the system and an MPI-enabled GetDP is used."
|
|
3272
|
+
" If False, GetDP will be run in serial without invoking mpiexec."
|
|
3273
|
+
),
|
|
3274
|
+
)
|
|
3275
|
+
|
|
3276
|
+
resistiveHeatingTerminals: bool = Field(
|
|
3277
|
+
default=True,
|
|
3278
|
+
title="Resistive Heating in Terminals",
|
|
3279
|
+
description=(
|
|
3280
|
+
"If True, terminals are subject to Joule heating. If False, terminal regions are"
|
|
3281
|
+
" not subject to Joule heating. In both cases, heat conduction through the terminal is "
|
|
3282
|
+
" considered."
|
|
3283
|
+
),
|
|
3284
|
+
)
|
|
3285
|
+
|
|
3286
|
+
heatFlowBetweenTurns: bool = Field(
|
|
3287
|
+
default=True,
|
|
3288
|
+
title="Heat Equation Between Turns",
|
|
3289
|
+
description=(
|
|
3290
|
+
"If True, heat flow between turns is considered. If False, it is not considered. "
|
|
3291
|
+
"In the latter case, heat conduction is only considered to the middle of the winding in the thin shell approximation "
|
|
3292
|
+
"in order to keep the thermal mass of the insulation included. In the middle between the turns, an adiabatic condition is applied. "
|
|
3293
|
+
"Between the turns refers to the region between the winding turns, NOT to the region between terminals "
|
|
3294
|
+
"and the first and last turn. "
|
|
3295
|
+
"This feature is only implemented for the thin shell approximation."
|
|
3296
|
+
),
|
|
3297
|
+
)
|
|
3298
|
+
|
|
3299
|
+
convectiveCooling: Optional[Pancake3DSolveConvectiveCooling] = Field(
|
|
3300
|
+
default=Pancake3DSolveConvectiveCooling(),
|
|
3301
|
+
title="Convective Cooling",
|
|
3302
|
+
description=(
|
|
3303
|
+
"This dictionary contains the convective cooling settings."
|
|
3304
|
+
),
|
|
3305
|
+
)
|
|
3306
|
+
|
|
3307
|
+
imposedPowerDensity: Optional[Pancake3DSolvePowerDensity] = Field(
|
|
3308
|
+
default=None,
|
|
3309
|
+
title="Power Density",
|
|
3310
|
+
description=(
|
|
3311
|
+
"The power density for an imposed power density in the winding."
|
|
3312
|
+
),
|
|
3313
|
+
)
|
|
3314
|
+
|
|
3315
|
+
materialParametersUseCoilField: bool = Field(
|
|
3316
|
+
default=True,
|
|
3317
|
+
title="Use Coil Field for Critical Current",
|
|
3318
|
+
description=(
|
|
3319
|
+
"If True, the total field (i.e., coil field plus potentially imposed field)"
|
|
3320
|
+
"will be used for the material (default)."
|
|
3321
|
+
"If False, only the imposed field (can be zero) will be used."
|
|
3322
|
+
),
|
|
3323
|
+
)
|
|
3324
|
+
|
|
3325
|
+
stopWhenTemperatureReaches: Optional[float] = Field(
|
|
3326
|
+
default=0,
|
|
3327
|
+
title="Stop When Temperature Reaches",
|
|
3328
|
+
description=(
|
|
3329
|
+
"If the maximum temperature reaches this value, the simulation will"
|
|
3330
|
+
" be stopped."
|
|
3331
|
+
),
|
|
3332
|
+
)
|
|
3333
|
+
|
|
2951
3334
|
@computed_field
|
|
2952
3335
|
@cached_property
|
|
2953
3336
|
def systemsOfEquationsType(self) -> str:
|
|
2954
3337
|
|
|
2955
|
-
windingMaterialIsGiven = self.
|
|
2956
|
-
contactLayerMaterialIsGiven = self.
|
|
2957
|
-
terminalMaterialIsGiven = self.
|
|
2958
|
-
notchMaterialIsGiven = self.
|
|
2959
|
-
terminalContactLayerMaterialIsGiven = self.
|
|
3338
|
+
windingMaterialIsGiven = self.winding.material is not None
|
|
3339
|
+
contactLayerMaterialIsGiven = self.contactLayer.material is not None
|
|
3340
|
+
terminalMaterialIsGiven = self.terminals.material is not None
|
|
3341
|
+
notchMaterialIsGiven = self.terminals.transitionNotch.material is not None
|
|
3342
|
+
terminalContactLayerMaterialIsGiven = self.terminals.terminalContactLayer.material is not None
|
|
2960
3343
|
|
|
2961
3344
|
if (
|
|
2962
3345
|
windingMaterialIsGiven
|
|
@@ -2970,14 +3353,14 @@ class Pancake3DSolve(BaseModel):
|
|
|
2970
3353
|
systemsOfEquationsType = "linear"
|
|
2971
3354
|
|
|
2972
3355
|
return systemsOfEquationsType
|
|
2973
|
-
|
|
3356
|
+
|
|
2974
3357
|
@model_validator(mode="before")
|
|
2975
3358
|
@classmethod
|
|
2976
3359
|
def check_nls_system_tolerances(cls, model: "Pancake3DSolve"):
|
|
2977
|
-
|
|
3360
|
+
|
|
2978
3361
|
if not "nonlinearSolver" in model or not "tolerances" in model["nonlinearSolver"]:
|
|
2979
3362
|
return model
|
|
2980
|
-
|
|
3363
|
+
|
|
2981
3364
|
all_tolerances = model["nonlinearSolver"]["tolerances"]
|
|
2982
3365
|
|
|
2983
3366
|
for tolerance in all_tolerances:
|
|
@@ -2988,7 +3371,7 @@ class Pancake3DSolve(BaseModel):
|
|
|
2988
3371
|
"The 'electromagneticSolutionVector' tolerance can be used only"
|
|
2989
3372
|
" in 'electromagnetic' or 'weaklyCoupled' simulations."
|
|
2990
3373
|
)
|
|
2991
|
-
|
|
3374
|
+
|
|
2992
3375
|
if tolerance["quantity"] == "thermalSolutionVector":
|
|
2993
3376
|
if model["type"] == "electromagnetic" or model["type"] == "stronglyCoupled":
|
|
2994
3377
|
raise ValueError(
|
|
@@ -2996,7 +3379,7 @@ class Pancake3DSolve(BaseModel):
|
|
|
2996
3379
|
"The 'thermalSolutionVector' tolerance can be used only"
|
|
2997
3380
|
" in 'thermal' or 'weaklyCoupled' simulations."
|
|
2998
3381
|
)
|
|
2999
|
-
|
|
3382
|
+
|
|
3000
3383
|
if tolerance["quantity"] == "coupledSolutionVector":
|
|
3001
3384
|
if model["type"] == "electromagnetic" or model["type"] == "thermal" or model["type"] == "weaklyCoupled":
|
|
3002
3385
|
raise ValueError(
|
|
@@ -3005,11 +3388,11 @@ class Pancake3DSolve(BaseModel):
|
|
|
3005
3388
|
" in 'stronglyCoupled' simulations."
|
|
3006
3389
|
)
|
|
3007
3390
|
return model
|
|
3008
|
-
|
|
3391
|
+
|
|
3009
3392
|
@model_validator(mode="before")
|
|
3010
3393
|
@classmethod
|
|
3011
3394
|
def check_adaptive_system_tolerances(cls, model: "Pancake3DSolve"):
|
|
3012
|
-
|
|
3395
|
+
|
|
3013
3396
|
if model["time"]["timeSteppingType"] == "fixed":
|
|
3014
3397
|
return model
|
|
3015
3398
|
|
|
@@ -3023,7 +3406,7 @@ class Pancake3DSolve(BaseModel):
|
|
|
3023
3406
|
"The 'electromagneticSolutionVector' tolerance can be used only"
|
|
3024
3407
|
" in 'electromagnetic' or 'weaklyCoupled' simulations."
|
|
3025
3408
|
)
|
|
3026
|
-
|
|
3409
|
+
|
|
3027
3410
|
if tolerance["quantity"] == "thermalSolutionVector":
|
|
3028
3411
|
if model["type"] == "electromagnetic" or model["type"] == "stronglyCoupled":
|
|
3029
3412
|
raise ValueError(
|
|
@@ -3031,7 +3414,7 @@ class Pancake3DSolve(BaseModel):
|
|
|
3031
3414
|
"The 'thermalSolutionVector' tolerance can be used only"
|
|
3032
3415
|
" in 'thermal' or 'weaklyCoupled' simulations."
|
|
3033
3416
|
)
|
|
3034
|
-
|
|
3417
|
+
|
|
3035
3418
|
if tolerance["quantity"] == "coupledSolutionVector":
|
|
3036
3419
|
if model["type"] == "electromagnetic" or model["type"] == "thermal" or model["type"] == "weaklyCoupled":
|
|
3037
3420
|
raise ValueError(
|
|
@@ -3040,7 +3423,83 @@ class Pancake3DSolve(BaseModel):
|
|
|
3040
3423
|
" in 'stronglyCoupled' simulations."
|
|
3041
3424
|
)
|
|
3042
3425
|
return model
|
|
3426
|
+
|
|
3427
|
+
@model_validator(mode="before")
|
|
3428
|
+
@classmethod
|
|
3429
|
+
def check_convective_cooling(cls, model: "Pancake3DSolve"):
|
|
3430
|
+
if "convectiveCooling" in model:
|
|
3431
|
+
|
|
3432
|
+
convectiveCooling = model["convectiveCooling"]
|
|
3433
|
+
|
|
3434
|
+
if not "heatTransferCoefficient" in convectiveCooling or not "exteriorBathTemperature" in convectiveCooling:
|
|
3435
|
+
raise ValueError(
|
|
3436
|
+
"If convective cooling is turned on, the heatTransferCoefficient and exteriorBathTemperature must be provided."
|
|
3437
|
+
)
|
|
3043
3438
|
|
|
3439
|
+
return model
|
|
3440
|
+
|
|
3441
|
+
@model_validator(mode="before")
|
|
3442
|
+
@classmethod
|
|
3443
|
+
def check_power_density(cls, model: "Pancake3DSolve"):
|
|
3444
|
+
if "imposedPowerDensity" in model:
|
|
3445
|
+
|
|
3446
|
+
powerDensity = model["imposedPowerDensity"]
|
|
3447
|
+
|
|
3448
|
+
if powerDensity:
|
|
3449
|
+
if not "startTime" in powerDensity or not "endTime" in powerDensity or not "startArcLength" in powerDensity or not "endArcLength" in powerDensity or not "power" in powerDensity:
|
|
3450
|
+
raise ValueError(
|
|
3451
|
+
"If the power density provided, the power, startTime, endTime, startTurn, and endTurn must be provided."
|
|
3452
|
+
)
|
|
3453
|
+
|
|
3454
|
+
return model
|
|
3455
|
+
|
|
3456
|
+
@model_validator(mode="before")
|
|
3457
|
+
@classmethod
|
|
3458
|
+
def check_heat_equation_between_turns(cls, model: "Pancake3DSolve"):
|
|
3459
|
+
if "heatFlowBetweenTurns" in model and not model["heatFlowBetweenTurns"]:
|
|
3460
|
+
|
|
3461
|
+
geometry = geometry_input.get()
|
|
3462
|
+
|
|
3463
|
+
if not geometry["contactLayer"]["thinShellApproximation"]:
|
|
3464
|
+
raise ValueError(
|
|
3465
|
+
"The heat equation between turns can only be turned off in the thin shell approximation."
|
|
3466
|
+
)
|
|
3467
|
+
|
|
3468
|
+
if not model["contactLayer"]["resistivity"] == "perfectlyInsulating":
|
|
3469
|
+
raise ValueError(
|
|
3470
|
+
"The heat equation between turns can only be turned off for perfectly insulated coils. That is, coils with contactLayer resistivity set to 'perfectlyInsulating'."
|
|
3471
|
+
)
|
|
3472
|
+
|
|
3473
|
+
return model
|
|
3474
|
+
|
|
3475
|
+
@model_validator(mode="before")
|
|
3476
|
+
@classmethod
|
|
3477
|
+
def check_voltage_taps(cls, model: "Pancake3DSolve"):
|
|
3478
|
+
|
|
3479
|
+
if "voltageTapPositions" in model:
|
|
3480
|
+
if len(model['voltageTapPositions'])>0:
|
|
3481
|
+
if model["type"] == "thermal":
|
|
3482
|
+
raise ValueError(
|
|
3483
|
+
"Voltage taps can only be used in electromagnetic simulations."
|
|
3484
|
+
)
|
|
3485
|
+
|
|
3486
|
+
if not model["contactLayer"]["resistivity"] == "perfectlyInsulating":
|
|
3487
|
+
raise ValueError(
|
|
3488
|
+
"For now, voltage taps can only be used for perfectly insulated coils. That is, coils with contactLayer resistivity set to 'perfectlyInsulating'."
|
|
3489
|
+
)
|
|
3490
|
+
|
|
3491
|
+
geometry = geometry_input.get()
|
|
3492
|
+
|
|
3493
|
+
if not geometry["contactLayer"]["thinShellApproximation"]:
|
|
3494
|
+
raise ValueError(
|
|
3495
|
+
"Voltage taps are only available in the thin shell approximation for now."
|
|
3496
|
+
)
|
|
3497
|
+
|
|
3498
|
+
|
|
3499
|
+
return model
|
|
3500
|
+
|
|
3501
|
+
# TODO: add model_validator to check if MPI is installed on the system and an MPI-enabled GetDP is used if useMPI is True
|
|
3502
|
+
|
|
3044
3503
|
# TODO: add model_validator to check postprocess quantities are available for this solve type (e.g. thermal quantities cannot be chosen for electromagnetic solve)
|
|
3045
3504
|
|
|
3046
3505
|
# TODO: add model_validator to check convergence quantities are available for this solve type (e.g. thermal quantities cannot be chosen for electromagnetic solve)
|
|
@@ -3051,13 +3510,13 @@ class Pancake3DPostprocess(BaseModel):
|
|
|
3051
3510
|
"""
|
|
3052
3511
|
|
|
3053
3512
|
# 1) User inputs:
|
|
3054
|
-
timeSeriesPlots: list[Pancake3DPostprocessTimeSeriesPlot] = Field(
|
|
3513
|
+
timeSeriesPlots: Optional[list[Pancake3DPostprocessTimeSeriesPlot]] = Field(
|
|
3055
3514
|
default=None,
|
|
3056
3515
|
title="Time Series Plots",
|
|
3057
3516
|
description="Values can be plotted with respect to time.",
|
|
3058
3517
|
)
|
|
3059
3518
|
|
|
3060
|
-
magneticFieldOnCutPlane: Pancake3DPostprocessMagneticFieldOnPlane = Field(
|
|
3519
|
+
magneticFieldOnCutPlane: Optional[Pancake3DPostprocessMagneticFieldOnPlane] = Field(
|
|
3061
3520
|
default=None,
|
|
3062
3521
|
title="Magnetic Field on a Cut Plane",
|
|
3063
3522
|
description=(
|
|
@@ -3089,7 +3548,7 @@ class Pancake3D(BaseModel):
|
|
|
3089
3548
|
description="This dictionary contains the solve information.",
|
|
3090
3549
|
)
|
|
3091
3550
|
postproc: Pancake3DPostprocess = Field(
|
|
3092
|
-
default=
|
|
3551
|
+
default=Pancake3DPostprocess(),
|
|
3093
3552
|
title="Postprocess",
|
|
3094
3553
|
description="This dictionary contains the postprocess information.",
|
|
3095
3554
|
)
|