fiqus 2025.11.0__py3-none-any.whl → 2026.1.0__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.
Files changed (36) hide show
  1. fiqus/MainFiQuS.py +9 -0
  2. fiqus/data/DataConductor.py +112 -3
  3. fiqus/data/DataFiQuS.py +4 -3
  4. fiqus/data/DataFiQuSConductorAC_CC.py +345 -0
  5. fiqus/data/DataFiQuSConductorAC_Rutherford.py +569 -0
  6. fiqus/data/DataFiQuSConductorAC_Strand.py +3 -3
  7. fiqus/data/DataFiQuSHomogenizedConductor.py +478 -0
  8. fiqus/geom_generators/GeometryConductorAC_CC.py +1906 -0
  9. fiqus/geom_generators/GeometryConductorAC_Rutherford.py +706 -0
  10. fiqus/geom_generators/GeometryConductorAC_Strand_RutherfordCopy.py +1848 -0
  11. fiqus/geom_generators/GeometryHomogenizedConductor.py +183 -0
  12. fiqus/getdp_runners/RunGetdpConductorAC_CC.py +123 -0
  13. fiqus/getdp_runners/RunGetdpConductorAC_Rutherford.py +200 -0
  14. fiqus/getdp_runners/RunGetdpHomogenizedConductor.py +178 -0
  15. fiqus/mains/MainConductorAC_CC.py +148 -0
  16. fiqus/mains/MainConductorAC_Rutherford.py +76 -0
  17. fiqus/mains/MainHomogenizedConductor.py +112 -0
  18. fiqus/mesh_generators/MeshConductorAC_CC.py +1305 -0
  19. fiqus/mesh_generators/MeshConductorAC_Rutherford.py +235 -0
  20. fiqus/mesh_generators/MeshConductorAC_Strand_RutherfordCopy.py +718 -0
  21. fiqus/mesh_generators/MeshHomogenizedConductor.py +229 -0
  22. fiqus/post_processors/PostProcessAC_CC.py +65 -0
  23. fiqus/post_processors/PostProcessAC_Rutherford.py +142 -0
  24. fiqus/post_processors/PostProcessHomogenizedConductor.py +114 -0
  25. fiqus/pro_templates/combined/CAC_CC_template.pro +542 -0
  26. fiqus/pro_templates/combined/CAC_Rutherford_template.pro +1742 -0
  27. fiqus/pro_templates/combined/HomogenizedConductor_template.pro +1663 -0
  28. {fiqus-2025.11.0.dist-info → fiqus-2026.1.0.dist-info}/METADATA +9 -12
  29. {fiqus-2025.11.0.dist-info → fiqus-2026.1.0.dist-info}/RECORD +36 -13
  30. tests/test_geometry_generators.py +40 -0
  31. tests/test_mesh_generators.py +76 -0
  32. tests/test_solvers.py +137 -0
  33. /fiqus/pro_templates/combined/{ConductorAC_template.pro → CAC_Strand_template.pro} +0 -0
  34. {fiqus-2025.11.0.dist-info → fiqus-2026.1.0.dist-info}/LICENSE.txt +0 -0
  35. {fiqus-2025.11.0.dist-info → fiqus-2026.1.0.dist-info}/WHEEL +0 -0
  36. {fiqus-2025.11.0.dist-info → fiqus-2026.1.0.dist-info}/top_level.txt +0 -0
fiqus/MainFiQuS.py CHANGED
@@ -25,6 +25,9 @@ from fiqus.mains.MainCCT import MainCCT
25
25
  from fiqus.mains.MainMultipole import MainMultipole
26
26
  from fiqus.mains.MainPancake3D import MainPancake3D
27
27
  from fiqus.mains.MainConductorAC_Strand import MainConductorAC_Strand
28
+ from fiqus.mains.MainHomogenizedConductor import MainHomogenizedConductor
29
+ from fiqus.mains.MainConductorAC_Rutherford import MainConductorAC_Rutherford
30
+ from fiqus.mains.MainConductorAC_CC import MainConductorAC_CC
28
31
 
29
32
  class MainFiQuS:
30
33
  """
@@ -90,6 +93,12 @@ class MainFiQuS:
90
93
  self.main_magnet = MainPancake3D(fdm=self.fdm, verbose=verbose)
91
94
  elif self.fdm.magnet.type == "CACStrand":
92
95
  self.main_magnet = MainConductorAC_Strand(fdm=self.fdm, inputs_folder_path=pathlib.Path(input_file_path).parent, outputs_folder_path=model_folder, verbose=verbose)
96
+ elif self.fdm.magnet.type == "CACCC":
97
+ self.main_magnet = MainConductorAC_CC(fdm=self.fdm, inputs_folder_path=pathlib.Path(input_file_path).parent, verbose=verbose)
98
+ elif self.fdm.magnet.type == "HomogenizedConductor":
99
+ self.main_magnet = MainHomogenizedConductor(fdm=self.fdm, inputs_folder_path=pathlib.Path(input_file_path).parent, outputs_folder_path=model_folder, verbose=verbose)
100
+ elif self.fdm.magnet.type == "CACRutherford":
101
+ self.main_magnet = MainConductorAC_Rutherford(fdm=self.fdm, inputs_folder_path=pathlib.Path(input_file_path).parent, verbose=verbose)
93
102
  elif self.fdm.magnet.type == "multipole":
94
103
  self.file_name = os.path.basename(input_file_path)[:-5]
95
104
  if not self.fdm.magnet.geometry.geom_file_path:
@@ -116,6 +116,27 @@ class ProDefined(BaseModel):
116
116
  v: Optional[float] = None # [-]
117
117
  B0: Optional[float] = None # [-]
118
118
 
119
+ class Succi_fixed(BaseModel):
120
+ """
121
+ Level 3: Class for cable Succi's YBCO fit
122
+ """
123
+
124
+ type: Literal["Succi_fixed"]
125
+ Jc_factor: Optional[float] = Field(gt=0.0,
126
+ default = 1.0,
127
+ description = "This factor multiplies the Jc returned by the function."
128
+ )
129
+ # all other parameters of the Succi fit are hardcoded
130
+ class Fujikura(BaseModel):
131
+ """
132
+ Level 3: Class for cable Fujikura's fit
133
+ """
134
+
135
+ type: Literal["Fujikura"]
136
+ Jc_factor: Optional[float] = Field(gt=0.0,
137
+ default = 1.0,
138
+ description = "This factor multiplies the Jc returned by the function."
139
+ )
119
140
 
120
141
  class BSCCO_2212_LBNL(BaseModel):
121
142
  """
@@ -223,6 +244,31 @@ class Ribbon(BaseModel):
223
244
  material_outer_voids: Optional[str] = None
224
245
  material_core: Optional[str] = None
225
246
 
247
+ class TSTC(BaseModel):
248
+ """
249
+ Twisted Stacked-Tape Cable (TSTC) type:
250
+ """
251
+ type: Literal["TSTC"]
252
+ stack_layout: Optional[List[Literal[-1,0,1]]] = Field(default=None,description="2D: Tape stack layout ordered TOP->BOTTOM. The numbers represent: 1 = a CC tape, -1 = a flipped CC tape, 0 = a shunt.")
253
+ nb_tapes: Optional[int] = Field(default=None, description="3D: Number of tapes in the stack")
254
+ tape_width: Optional[float] = Field(default=None, description="3D and 2D: Width of each tape")
255
+ tape_thickness: Optional[float] = Field(default=None, description="3D and 2D: Thickness of each tape")
256
+ twist_pitch: Optional[float] = Field(default=None, description="3D: Length over which tapes are twisted by full rotation")
257
+ pitch_fraction: Optional[float] = Field(default=1.0, description="3D: Fraction of the twist pitch to be modelled (1.0 = full pitch, 0.5 = half pitch, etc.)")
258
+ bare_cable_width: Optional[float] = Field(default=None, description="Cable width, typically the same as CC width")
259
+ bare_cable_height_low: Optional[float] = Field(default=None, description="Narrow end (if applicable) cable height (thickness), typically the same as (CC thickness + Cu stabilizer thickness) * number of tapes.")
260
+ bare_cable_height_high: Optional[float] = Field(default=None, description="Wide end (if applicable) cable height (thickness), typically the same as (CC thickness + Cu stabilizer thickness) * number of tapes.")
261
+ bare_cable_height_mean: Optional[float] = Field(default=None, description="Average (if applicable) cable height (thickness), typically the same as (CC thickness + Cu stabilizer thickness) * number of tapes.")
262
+ th_insulation_along_width: Optional[float] = Field(default=None, description="Insulation thickness along the width ")
263
+ th_insulation_along_height: Optional[float] = Field(default=None, description="Insulation thickness along the height ")
264
+ f_superconductor: Optional[float] = Field(default=None, description="Fraction of superconductor related to the total area of the cable (winding cell)")
265
+ f_stabilizer: Optional[float] = Field(default=None, description="Fraction of stabilizer related to the total area of the cable (winding cell)")
266
+ f_silver: Optional[float] = Field(default=None, description="Fraction of silver related to the total area of the cable (winding cell)")
267
+ f_substrate: Optional[float] = Field(default=None, description="Fraction of substrate (including buffer layers and silver overlay) related to the total area of the cable (winding cell)")
268
+ f_shunt: Optional[float] = Field(default=None, description="Fraction of substrate (including buffer layers and silver overlay) related to the total area of the cable (winding cell)")
269
+ f_insulation: Optional[float] = Field(default=None, description="Fraction of cable insulation related to the total area of the cable (winding cell)")
270
+ f_inner_voids: Optional[float] = Field(default=None, description="Fraction of additional material (typically insulation) related to the total area of the cable (winding cell)")
271
+ f_outer_voids: Optional[float] = Field(default=None, description="Fraction of additional material (typically helium impregnating the windings) related to the total area of the cable (winding cell)")
226
272
 
227
273
  # ------------------- Conductors ---------------------------#
228
274
 
@@ -328,6 +374,69 @@ class Rectangular(BaseModel):
328
374
  # superconductor: MaterialSuperconductor = MaterialSuperconductor()
329
375
  # stabilizer: MaterialStabilizer = MaterialStabilizer()
330
376
 
377
+ class Copper_thickness(BaseModel):
378
+ left: Optional[float] = Field(default=None, description="On the left side.")
379
+ right: Optional[float] = Field(default=None, description="On the right side.")
380
+ top: Optional[float] = Field(default=None, description="On the top side.")
381
+ bottom: Optional[float] = Field(default=None, description="On the bottom side.")
382
+
383
+ class Silver_thickness(BaseModel):
384
+ top: Optional[float] = Field(default=None, description="On the top side.")
385
+ bottom: Optional[float] = Field(default=None, description="On the bottom side.")
386
+
387
+ class CC(BaseModel):
388
+ """
389
+ Level 2: Class for coated conductor parameters
390
+ """
391
+ type: Literal["CC"]
392
+
393
+ # Core layer sizes
394
+ HTS_thickness: Optional[float] = Field(default=None, description="HTS thickness in meters.")
395
+ HTS_width: Optional[float] = Field(default=None, description="HTS width in meters.")
396
+ number_of_filaments: Optional[int] = Field(default=1, ge=1, description="Number of HTS filaments. If 1, no striation case")
397
+ gap_between_filaments: Optional[float] = Field(default=None, description="Gap between HTS filaments in meters. Only applies when number_of_filaments > 1.")
398
+ substrate_thickness: Optional[float] = Field(default=None, description="Substrate layer thickness in meters.")
399
+
400
+ # Plating/stabilizer
401
+ copper_thickness: Copper_thickness = Field(default=Copper_thickness(), description="Copper thickness in meters")
402
+ silver_thickness: Silver_thickness = Field(default=Silver_thickness(), description="Silver thickness in meters")
403
+
404
+ # -- Superconductor parameters -- #
405
+ material_superconductor: Optional[str] = Field(default=None, description="Material of the superconductor. E.g. NbTi, Nb3Sn, etc.")
406
+ n_value_superconductor: Optional[float] = Field(default=None, description="n value of the superconductor (for power law fit).")
407
+ ec_superconductor: Optional[float] = Field(default=None, description="Critical electric field of the superconductor.")
408
+ minimum_jc_fraction: Optional[float] = Field(gt=0, le=1, default=None, description="Fraction of Jc(minimum_jc_field, T) to use as minimum Jc for the power law"
409
+ " fit to avoid division by zero when Jc(B_local, T) decreases to zero."
410
+ "Typical value would be 0.001 (so the Jc_minimum is 0.1% of Jc(minimum_jc_field, T))"
411
+ "This fraction is only allowed to be greater than 0.0 and less than or equal to 1.0")
412
+ minimum_jc_field: Optional[float] = Field(default=None, description="Magnetic flux density in tesla used for calculation of Jc(minimum_jc_field, T)."
413
+ "This gets multiplied by minimum_jc_fraction and used as minimum Jc for the power law")
414
+ k_material_superconductor: Optional[Union[str, float]] = Field(default=None, description="Thermal conductivity of the superconductor.")
415
+ Cv_material_superconductor: Optional[Union[str, float]] = Field(default=None, description="Material function for specific heat of the superconductor.")
416
+ k_material_stabilizer: Optional[Union[str, float]] = Field(default=None, description="Thermal conductivity of the stabilizer, typically copper.")
417
+ Cv_material_stabilizer: Optional[Union[str, float]] = Field(default=None, description="Material function for specific heat of the stabilizer, typically copper.")
418
+ rho_material_stabilizer: Optional[Union[str, float]] = Field(default=None, description="Material function for resistivity of the stabilizer. Constant resistivity can be given as float.")
419
+ RRR: Optional[Union[float, List[float]]] = Field(default=None, description="Residual resistivity ratio of the stabilizer. If a list of RRR is provided it needs to match in length the number of matrix regions in the geometry (typically 3)")
420
+ T_ref_RRR_high: Optional[float] = Field(default=None, description="Upper reference temperature for RRR measurements.")
421
+ T_ref_RRR_low: Optional[float] = Field(default=None, description="Lower reference temperature for RRR measurements.")
422
+ k_material_silver: Optional[Union[str, float]] = Field(default=None, description="Thermal conductivity of the silver")
423
+ Cv_material_silver: Optional[Union[str, float]] = Field(default=None, description="Material function for specific heat of the silver")
424
+ rho_material_silver: Optional[Union[str, float]] = Field(default=None, description="Material function for resistivity of the silver. Constant resistivity can be given as float.")
425
+ RRR_silver: Optional[Union[float, List[float]]] = Field(default=None, description="Residual resistivity ratio of the silver. If a list of RRR is provided it needs to match in length the number of matrix regions in the geometry (typically 3)")
426
+ T_ref_RRR_high_silver: Optional[float] = Field(default=None, description="Upper reference temperature for RRR measurements for silver.")
427
+ T_ref_RRR_low_silver: Optional[float] = Field(default=None, description="Lower reference temperature for RRR measurements for silver.")
428
+ rho_material_substrate: Optional[Union[str, float]] = Field(default=None, description="Material function for resistivity of the substrate. Constant resistivity can be given as float.")
429
+ k_material_substrate: Optional[Union[str, float]] = Field(default=None, description="Thermal conductivity of the substrate.")
430
+ Cv_material_substrate: Optional[Union[str, float]] = Field(default=None, description="Material function for specific heat of the substrate.")
431
+
432
+ class Homogenized(BaseModel):
433
+ """
434
+ Level 2: Class for homogenized strand parameters, to be used in the Rutherford cable model
435
+ """
436
+ type: Literal["Homogenized"]
437
+
438
+ # Strand diameter (used in the geometry step)
439
+ diameter: Optional[float] = Field(default=None, description="Undeformed round strand diameter. Used in the geometry step if keep_strand_area==true, the strand is deformed while preserving its surface area. Not used otherwise.")
331
440
 
332
441
 
333
442
  # ------------------- Conductors ---------------------------#
@@ -341,10 +450,10 @@ class Conductor(BaseModel):
341
450
  version: Optional[str] = None
342
451
  case: Optional[str] = None
343
452
  state: Optional[str] = None
344
- cable: Union[Rutherford, Mono, Ribbon] = {
453
+ cable: Union[Rutherford, Mono, Ribbon, TSTC] = {
345
454
  "type": "Rutherford"
346
455
  } # TODO: Busbar, Rope, Roebel, CORC, TSTC, CICC
347
- strand: Union[Round, Rectangular] = {"type": "Round"} # TODO: Tape, WIC
348
- Jc_fit: Union[ConstantJc, Bottura, CUDI1, CUDI3, Summers, Bordini, Nb3Sn_HFM, BSCCO_2212_LBNL, Ic_A_NbTi, ProDefined] = {
456
+ strand: Union[Round, Rectangular, CC, Homogenized] = {"type": "Round"} # TODO: Tape, WIC
457
+ Jc_fit: Union[ConstantJc, Bottura, CUDI1, CUDI3, Summers, Bordini, Nb3Sn_HFM, BSCCO_2212_LBNL, Ic_A_NbTi, ProDefined, Succi_fixed, Fujikura] = {
349
458
  "type": "CUDI1"
350
459
  } # TODO: CUDI other numbers? , Roxie?
fiqus/data/DataFiQuS.py CHANGED
@@ -7,8 +7,9 @@ from fiqus.data.DataFiQuSCCT import CCT
7
7
  from fiqus.data.DataFiQuSMultipole import Multipole
8
8
  from fiqus.data.DataFiQuSPancake3D import Pancake3D
9
9
  from fiqus.data.DataFiQuSConductorAC_Strand import CACStrand
10
-
11
-
10
+ from fiqus.data.DataFiQuSHomogenizedConductor import HomogenizedConductor
11
+ from fiqus.data.DataFiQuSConductorAC_Rutherford import CACRutherford
12
+ from fiqus.data.DataFiQuSConductorAC_CC import CACCC
12
13
 
13
14
  class RunFiQuS(BaseModel):
14
15
  """
@@ -144,7 +145,7 @@ class FDM(BaseModel):
144
145
 
145
146
  general: GeneralFiQuS = GeneralFiQuS()
146
147
  run: RunFiQuS = RunFiQuS()
147
- magnet: Union[Multipole, CCT, Pancake3D, CACStrand] = Field(
148
+ magnet: Union[Multipole, CCT, Pancake3D, CACStrand, HomogenizedConductor, CACRutherford, CACCC] = Field(
148
149
  default=Multipole(), discriminator="type"
149
150
  )
150
151
  circuit: Circuit_Class = Circuit_Class()
@@ -0,0 +1,345 @@
1
+
2
+ """DataFiQuSConductorAC_CC.py"""
3
+
4
+ from pydantic import BaseModel, Field, field_validator
5
+ from typing import Literal, Optional, Union, List
6
+
7
+
8
+
9
+
10
+ class CACCCGeometry(BaseModel):
11
+ """
12
+ Level 2: Geometry for CACCC.
13
+ """
14
+ air_radius: Optional[float] = Field(
15
+ default=None,
16
+ description = "Radius of air region."
17
+ )
18
+
19
+
20
+ class CACCCGeneralparameters(BaseModel):
21
+ """
22
+ Level 3: Class for general parameters
23
+ """
24
+ temperature: float = Field(
25
+ default=1.9,
26
+ description = "Temperature (K)."
27
+ )
28
+ noOfMPITasks: Optional[Union[bool, int]] = Field(
29
+ default=False, title = "No. of tasks for MPI parallel run of GetDP",
30
+ description = "If integer, GetDP will be run in parallel using MPI. This is only valid"
31
+ " if MPI is installed on the system and an MPI-enabled GetDP is used."
32
+ " If False, GetDP will be run in serial without invoking mpiexec."
33
+ )
34
+
35
+
36
+
37
+ class CACCCSolveInitialconditions(BaseModel):
38
+ """
39
+ Level 3: Class for initial conditions
40
+ """
41
+ init_type: Optional[Literal['virgin', 'pos_file', 'uniform_field']] = Field(
42
+ default='virgin',
43
+ description = "Type of initialization for the simulation. (i) 'virgin' is the default type, the initial magnetic field is zero,"
44
+ "(ii) 'pos_file' is to initialize from the solution of another solution, given by the solution_to_init_from entry,"
45
+ " and (iii) 'uniform_field' is to initialize at a uniform field, which will be the applied field at the initial time of the simulation."
46
+ " Note that the uniform_field option does not allow any non-zero transport current (initialization from pos_file is needed for this)."
47
+ )
48
+ solution_to_init_from: Optional[Union[int, str]] = Field(
49
+ default=None,
50
+ description = "Name xxx of the solution from which the simulation should be initialized. "
51
+ "The file last_magnetic_field.pos of folder Solution_xxx will be used for the initial solution."
52
+ "It must be in the Geometry_.../Mesh_.../ folder in which the Solution_xxx will be saved.",
53
+ )
54
+
55
+
56
+
57
+ class CACCCSolveSourceparametersSine(BaseModel):
58
+ """
59
+ Level 4: Class for Sine source parameters
60
+ """
61
+ frequency: Optional[float] = Field(
62
+ default=None,
63
+ description = "Frequency of the sine source (Hz)."
64
+ )
65
+ field_amplitude: Optional[float] = Field(
66
+ default=None,
67
+ description = "Amplitude of the sine field (T)."
68
+ )
69
+ current_amplitude: Optional[float] = Field(
70
+ default=None,
71
+ description = "Amplitude of the sine current (A)."
72
+ )
73
+
74
+
75
+
76
+ class CACCCSolveSourceparametersPiecewise(BaseModel):
77
+ """
78
+ Level 4: Class for piecewise (linear) source parameters
79
+ """
80
+ source_csv_file: Optional[str] = Field(
81
+ default=None,
82
+ description = "File name for the from_file source type defining the time evolution of current and field (in-phase)."
83
+ "Multipliers are used for each of them."
84
+ "The file should contain two columns: 'time' (s) and 'value' (field/current (T/A)), with these headers."
85
+ "If this field is set, times, applied_fields_relative and transport_currents_relative are ignored."
86
+ )
87
+ times: Optional[List[float]] = Field(
88
+ default=None,
89
+ description = "Time instants (s) defining the piecewise linear sources."
90
+ "Used only if source_csv_file is not set."
91
+ "Can be scaled by time_multiplier."
92
+ )
93
+ applied_fields_relative: Optional[List[float]] = Field(
94
+ default=None,
95
+ description = "Applied fields relative to multiplier applied_field_multiplier at the time instants 'times'."
96
+ "Used only if source_csv_file is not set."
97
+ )
98
+ transport_currents_relative: Optional[List[float]] = Field(
99
+ default=None,
100
+ description = "Transport currents relative to multiplier transport_current_multiplier at the time instants 'times'."
101
+ "Used only if source_csv_file is not set."
102
+ )
103
+ time_multiplier: Optional[float] = Field(
104
+ default=None,
105
+ description = "Multiplier for the time values in times (scales the time values)."
106
+ "Also used for the time values in the source_csv_file."
107
+ )
108
+ applied_field_multiplier: Optional[float] = Field(
109
+ default=None,
110
+ description = "Multiplier for the applied fields in applied_fields_relative."
111
+ "Also used for the values in the source_csv_file."
112
+ )
113
+ transport_current_multiplier: Optional[float] = Field(
114
+ default=None,
115
+ description = "Multiplier for the transport currents in transport_currents_relative."
116
+ "Also used for the values in the source_csv_file."
117
+ )
118
+
119
+
120
+
121
+ class CACCCSolveSourceparameters(BaseModel):
122
+ """
123
+ Level 3: Class for material properties
124
+ """
125
+ source_type: Literal['sine', 'piecewise'] = Field(
126
+ default='sine',
127
+ description = "Time evolution of applied current and magnetic field. "
128
+ "Supported options are: sine, piecewise."
129
+ )
130
+ sine: CACCCSolveSourceparametersSine = CACCCSolveSourceparametersSine()
131
+ piecewise: CACCCSolveSourceparametersPiecewise = CACCCSolveSourceparametersPiecewise()
132
+ field_angle_with_respect_to_normal_direction: Optional[float] = Field(
133
+ default=None,
134
+ description = "Angle of the source magnetic field with respect to the y-axis (normal to the tape) (degrees)."
135
+ )
136
+
137
+
138
+
139
+ class CACCCSolveNumericalparametersSine(BaseModel):
140
+ """
141
+ Level 4: Numerical parameters corresponding to the sine source
142
+ """
143
+ timesteps_per_period: Optional[float] = Field(
144
+ default=None,
145
+ description = "Initial value for number of time steps (-) per period for the sine source."
146
+ "Determines the initial time step size."
147
+ )
148
+ number_of_periods_to_simulate: Optional[float] = Field(
149
+ default=None,
150
+ description = "Number of periods (-) to simulate for the sine source."
151
+ )
152
+
153
+
154
+
155
+ class CACCCSolveNumericalparametersPiecewise(BaseModel):
156
+ """
157
+ Level 4: Numerical parameters corresponding to the piecewise source
158
+ """
159
+ time_to_simulate: Optional[float] = Field(
160
+ default=None,
161
+ description = "Total time to simulate (s). Used for the piecewise source."
162
+ )
163
+ timesteps_per_time_to_simulate: Optional[float] = Field(
164
+ default=None,
165
+ description = "If variable_max_timestep is False. Number of time steps (-) per period for the piecewise source."
166
+ )
167
+ force_stepping_at_times_piecewise_linear: bool = Field(
168
+ default=False,
169
+ description = "If True, time-stepping will contain exactly the time instants that are in"
170
+ "the times_source_piecewise_linear list (to avoid truncation maximum applied field/current values)."
171
+ )
172
+ variable_max_timestep: bool = Field(
173
+ default=False,
174
+ description = "If False, the maximum time step is kept constant through the simulation. "
175
+ "If True, it varies according to the piecewise definition."
176
+ )
177
+ times_max_timestep_piecewise_linear: Optional[List[float]] = Field(
178
+ default=None,
179
+ description = "Time instants (s) defining the piecewise linear maximum time step."
180
+ )
181
+ max_timestep_piecewise_linear: Optional[List[float]] = Field(
182
+ default=None,
183
+ description = "Maximum time steps (s) at the times_max_timestep_piecewise_linear. "
184
+ "Above the limits, linear extrapolation of the last two values."
185
+ )
186
+
187
+
188
+
189
+ class CACCCSolveNumericalparameters(BaseModel):
190
+ """
191
+ Level 3: Class for numerical parameters
192
+ """
193
+ relative_tolerance: Optional[float] = Field(default=1e-6, description="Tolerance on the relative change of the power indicator for the convergence criterion (1e-6 is usually a safe choice).")
194
+ voltage_per_meter_stopping_criterion: Optional[float] = Field(default=None, description="If a non-zero value is given, the simulation will stop if the transport voltage per meter reaches this value (in absolute value).")
195
+ relaxation_factors: Optional[bool] = Field(default=True, description="Use of relaxation factors to help convergence (automatic selection based on the lowest residual).")
196
+ sine: CACCCSolveNumericalparametersSine = CACCCSolveNumericalparametersSine()
197
+ piecewise: CACCCSolveNumericalparametersPiecewise = CACCCSolveNumericalparametersPiecewise()
198
+
199
+
200
+
201
+ class CACCCSolve(BaseModel):
202
+ """
203
+ Level 2: Solve block for CACCC
204
+ """
205
+ pro_template: Optional[str] = Field(
206
+ default='CAC_CC_template.pro',
207
+ description = "Name of the .pro template file."
208
+ )
209
+ conductor_name: Optional[str] = Field(
210
+ default=None,
211
+ description = "Name of the conductor. Must match a conductor name in "
212
+ "the conductors section of the input YAML-file."
213
+ )
214
+ general_parameters: CACCCGeneralparameters = (
215
+ CACCCGeneralparameters()
216
+ )
217
+ initial_conditions: CACCCSolveInitialconditions = (
218
+ CACCCSolveInitialconditions()
219
+ )
220
+ source_parameters: CACCCSolveSourceparameters = (
221
+ CACCCSolveSourceparameters()
222
+ )
223
+ numerical_parameters: CACCCSolveNumericalparameters = (
224
+ CACCCSolveNumericalparameters()
225
+ )
226
+
227
+
228
+
229
+ class CACCCMesh(BaseModel):
230
+ """
231
+ Level 2: Mesh parameters for CACCC.
232
+ """
233
+ HTS_n_elem_width: Optional[int] = Field(
234
+ default=None,
235
+ description = "Number of elements along HTS width (x-direction)."
236
+ )
237
+ HTS_n_elem_thickness: Optional[int] = Field(
238
+ default=None,
239
+ description = "Number of elements through HTS thickness (y-direction)."
240
+ )
241
+ substrate_elem_scale: Optional[float] = Field(
242
+ default=None,
243
+ description = "Element-count scale factor for substrate layer."
244
+ )
245
+ substrate_side_progression: Optional[float] = Field(
246
+ default=None,
247
+ description = "Progression factor for substrate vertical sides near the HTS side."
248
+ )
249
+ silver_elem_scale: Optional[float] = Field(
250
+ default=None,
251
+ description = "Element-count scale factor for silver layers."
252
+ )
253
+ copper_elem_scale: Optional[float] = Field(
254
+ default=None,
255
+ description = "Element-count scale factor for copper layers."
256
+ )
257
+ air_boundary_mesh_size_ratio: Optional[float] = Field(
258
+ default=None,
259
+ description = "Ratio of air outer-boundary mesh size to the HTS base size."
260
+ )
261
+ scaling_global: Optional[float] = Field(
262
+ default=None,
263
+ description = "Global refinement factor."
264
+ )
265
+ bump_coef: Optional[float] = Field(
266
+ default=None,
267
+ description = "Unified bump coefficient for transfinite horizontal edges. "
268
+ "Used for both HTS and SilverTop when applying 'Bump' distributions. "
269
+ "Values < 1 cluster nodes toward the edges; values > 1 cluster toward the center."
270
+ )
271
+
272
+
273
+
274
+
275
+ class CACCCPostprocPosFiles(BaseModel):
276
+ """
277
+ Level 3: Class for post-pro .pos file requests
278
+ """
279
+ quantities: Optional[List[str]] = Field(
280
+ default=None, description = "List of GetDP postprocessing quantities to write to .pos file. "
281
+ "Examples of valid entry is: phi, h, b, j, jz, power"
282
+ )
283
+ regions: Optional[List[str]] = Field(
284
+ default=None,
285
+ description = "List of GetDP regions to write to .pos file postprocessing for. "
286
+ "Examples of a valid entry is: "
287
+ "Matrix, Filaments, Omega (full domain), OmegaC (conducting domain), OmegaCC (non conducting domain)"
288
+ )
289
+
290
+ @field_validator("quantities", 'regions', mode="before")
291
+ @classmethod
292
+ def convert_none_to_empty_list(cls, v):
293
+ pass
294
+ if v is None:
295
+ return [] # if None default to empty list. Jinja relies on list for looping in the pro template. The default is not a list to be consistent with SDK entries.
296
+ return v
297
+
298
+ model_config = {
299
+ "validate_default": True
300
+ }
301
+
302
+
303
+
304
+ class CWSStrandPostprocCleanup(BaseModel):
305
+ """
306
+ Level 3: Class for cleanup settings
307
+ """
308
+ remove_pre_file: bool = Field(
309
+ default=False,
310
+ description = "Set True to remove the .pre-file after post-processing, to save disk space."
311
+ )
312
+ remove_res_file: bool = Field(
313
+ default=False,
314
+ description = "Set True to remove the .res-file after post-processing, to save disk space."
315
+ )
316
+ remove_msh_file: bool = Field(
317
+ default=False,
318
+ description = "Set True to remove the .msh-file after post-processing, to save disk space."
319
+ )
320
+
321
+
322
+
323
+ class CACCCPostproc(BaseModel):
324
+ """
325
+ Post-processing options for CACCC
326
+ """
327
+ pos_files: CACCCPostprocPosFiles = Field(
328
+ default=CACCCPostprocPosFiles(),
329
+ description = "Entries controlling output of .pos files."
330
+ "If None or empty lists are given, no .pos files are written."
331
+ "Note that not all combinations of quantities and regions make sense."
332
+ )
333
+ cleanup: CWSStrandPostprocCleanup = CWSStrandPostprocCleanup()
334
+
335
+
336
+ class CACCC(BaseModel):
337
+ """
338
+ Level 1: Class for FiQuS CACCC
339
+ """
340
+ type: Literal["CACCC"]
341
+ geometry: CACCCGeometry = CACCCGeometry()
342
+ mesh: CACCCMesh = CACCCMesh()
343
+ solve: CACCCSolve = CACCCSolve()
344
+ postproc: CACCCPostproc = CACCCPostproc()
345
+