fiqus 2025.2.0__py3-none-any.whl → 2025.10.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 (54) hide show
  1. fiqus/MainFiQuS.py +4 -9
  2. fiqus/data/DataConductor.py +350 -301
  3. fiqus/data/DataFiQuS.py +42 -115
  4. fiqus/data/DataFiQuSCCT.py +150 -150
  5. fiqus/data/DataFiQuSConductor.py +97 -84
  6. fiqus/data/DataFiQuSConductorAC_Strand.py +701 -565
  7. fiqus/data/DataModelCommon.py +439 -0
  8. fiqus/data/DataMultipole.py +0 -13
  9. fiqus/data/DataRoxieParser.py +7 -0
  10. fiqus/data/DataWindingsCCT.py +37 -37
  11. fiqus/data/RegionsModelFiQuS.py +61 -104
  12. fiqus/geom_generators/GeometryCCT.py +904 -905
  13. fiqus/geom_generators/GeometryConductorAC_Strand.py +1863 -1391
  14. fiqus/geom_generators/GeometryMultipole.py +5 -4
  15. fiqus/geom_generators/GeometryPancake3D.py +1 -1
  16. fiqus/getdp_runners/RunGetdpCCT.py +13 -4
  17. fiqus/getdp_runners/RunGetdpConductorAC_Strand.py +341 -201
  18. fiqus/getdp_runners/RunGetdpPancake3D.py +2 -2
  19. fiqus/mains/MainConductorAC_Strand.py +141 -133
  20. fiqus/mains/MainMultipole.py +6 -5
  21. fiqus/mains/MainPancake3D.py +3 -4
  22. fiqus/mesh_generators/MeshCCT.py +209 -209
  23. fiqus/mesh_generators/MeshConductorAC_Strand.py +709 -656
  24. fiqus/mesh_generators/MeshMultipole.py +43 -46
  25. fiqus/parsers/ParserDAT.py +16 -16
  26. fiqus/parsers/ParserGetDPOnSection.py +212 -212
  27. fiqus/parsers/ParserGetDPTimeTable.py +134 -134
  28. fiqus/parsers/ParserMSH.py +53 -53
  29. fiqus/parsers/ParserPOS.py +214 -214
  30. fiqus/parsers/ParserRES.py +142 -142
  31. fiqus/plotters/PlotPythonCCT.py +133 -133
  32. fiqus/plotters/PlotPythonConductorAC.py +1079 -855
  33. fiqus/plotters/PlotPythonMultipole.py +18 -18
  34. fiqus/post_processors/PostProcessCCT.py +444 -440
  35. fiqus/post_processors/PostProcessConductorAC.py +997 -49
  36. fiqus/post_processors/PostProcessMultipole.py +19 -19
  37. fiqus/pre_processors/PreProcessCCT.py +175 -175
  38. fiqus/pro_material_functions/ironBHcurves.pro +246 -246
  39. fiqus/pro_templates/combined/CCT_template.pro +275 -274
  40. fiqus/pro_templates/combined/ConductorAC_template.pro +1474 -1025
  41. fiqus/pro_templates/combined/Multipole_template.pro +5 -5
  42. fiqus/utils/Utils.py +12 -7
  43. {fiqus-2025.2.0.dist-info → fiqus-2025.10.0.dist-info}/METADATA +65 -63
  44. fiqus-2025.10.0.dist-info/RECORD +86 -0
  45. {fiqus-2025.2.0.dist-info → fiqus-2025.10.0.dist-info}/WHEEL +1 -1
  46. tests/test_geometry_generators.py +4 -0
  47. tests/test_mesh_generators.py +5 -0
  48. tests/test_solvers.py +41 -4
  49. tests/utils/fiqus_test_classes.py +15 -6
  50. tests/utils/generate_reference_files_ConductorAC.py +57 -57
  51. tests/utils/helpers.py +97 -97
  52. fiqus-2025.2.0.dist-info/RECORD +0 -85
  53. {fiqus-2025.2.0.dist-info → fiqus-2025.10.0.dist-info}/LICENSE.txt +0 -0
  54. {fiqus-2025.2.0.dist-info → fiqus-2025.10.0.dist-info}/top_level.txt +0 -0
@@ -1,565 +1,701 @@
1
- from pydantic import BaseModel, Field
2
- from typing import List, Literal, Optional
3
-
4
-
5
- # ============= GEOMETRY ============= #
6
- # -- Input/Output settings -- #
7
- class CACStrandIOsettingsLoad(BaseModel):
8
- """
9
- Level 3: Class for Input/Output settings for the cable geometry
10
- """
11
-
12
- load_from_yaml: Optional[bool] = Field(
13
- default=False,
14
- description="True to load the geometry from a YAML file, false to generate the geometry.",
15
- )
16
- filename: Optional[str] = Field(
17
- default=None,
18
- description="Name of the YAML file from which to load the geometry.",
19
- )
20
-
21
- class CACStrandIOsettingsSave(BaseModel):
22
- """
23
- Level 3: Class for Input/Output settings for the cable geometry
24
- """
25
-
26
- save_to_yaml: Optional[bool] = Field(
27
- default=False,
28
- description="True to save the geometry to a YAML-file, false to not save the geometry.",
29
- )
30
- filename: Optional[str] = Field(
31
- default=None,
32
- description="Name of the output geometry YAML file.",
33
- )
34
-
35
- class CACStrandGeometryIOsettings(BaseModel):
36
- """
37
- Level 2: Class for Input/Output settings for the cable geometry
38
- """
39
-
40
- load: CACStrandIOsettingsLoad = (
41
- CACStrandIOsettingsLoad()
42
- )
43
- save: CACStrandIOsettingsSave = (
44
- CACStrandIOsettingsSave()
45
- )
46
-
47
- # -- Strand geometry parameters -- #
48
- class CACStrandGeometry(BaseModel):
49
- """
50
- Level 2: Class for strand geometry parameters
51
- """
52
- io_settings: CACStrandGeometryIOsettings = CACStrandGeometryIOsettings()
53
- hexagonal_filaments: Optional[bool] = Field(
54
- default=None,
55
- description="Field for specifying the shape of the filaments. True for hexagonal, False for circular.",
56
- )
57
- filament_circular_distribution: Optional[bool] = Field(
58
- default=None,
59
- description="Field for specifying the geometrical distribution of the filaments. Set True to distribute the filaments in a circular pattern and False to distribute them in a hexagonal pattern."
60
- )
61
- air_radius: Optional[float] = Field(
62
- default=None, description="Radius of the circular numerical air region (m)."
63
- )
64
-
65
-
66
- # ============= MESH ============= #
67
- # -- Filament mesh settings -- #
68
- class CACStrandMeshFilaments(BaseModel):
69
- """
70
- Level 3: Class for FiQuS ConductorAC
71
- """
72
-
73
- boundary_mesh_size_ratio: Optional[float] = Field(
74
- default=None,
75
- description="Mesh size at filament boundaries, relative to the radius of the filaments. E.g. 0.1 means that the mesh size is 0.1 times the filament radius.",
76
- )
77
- center_mesh_size_ratio: Optional[float] = Field(
78
- default=None,
79
- description="Mesh size at filament center, relative to the radius of the filaments. E.g. 0.1 means that the mesh size is 0.1 times the filament radius.",
80
- )
81
- amplitude_dependent_scaling: Optional[bool] = Field(
82
- default=False,
83
- description="Amplitude dependent scaling uses the field amplitude to approximate the field penetration distance in the filaments to alter the filament mesh. If the field penetration distance is low (i.e. for low field amplitudes) this feature increases mesh density in the region where the field is expected to penetrate, and decreases the mesh resolution in the region where the field does not penetrate.",
84
- )
85
- field_penetration_depth_scaling_factor: Optional[float] = Field(
86
- default=None,
87
- description="Scaling factor for the estimate of the field penetration depth, used for amplitude dependent scaling. ",
88
- )
89
- desired_elements_in_field_penetration_region: Optional[float] = Field(
90
- default=None,
91
- description="Desired number of elements in the field penetration region. This parameter is used for amplitude dependent scaling, and determines the number of elements in the region where the field is expected to penetrate.",
92
- )
93
-
94
- # -- Matrix mesh settings -- #
95
- class CACStrandMeshMatrix(BaseModel):
96
- """
97
- Level 3: Class for FiQuS ConductorAC
98
- """
99
-
100
- mesh_size_matrix_ratio_inner: Optional[float] = Field(
101
- default=None,
102
- description="Mesh size at the matrix center, relative to the filament radius.",
103
- )
104
- mesh_size_matrix_ratio_middle: Optional[float] = Field(
105
- default=None,
106
- description="Mesh size at the matrix middle partition, relative to the filament radius.",
107
- )
108
- mesh_size_matrix_ratio_outer: Optional[float] = Field(
109
- default=None,
110
- description="Mesh size at the matrix outer boundary, relative to the filament radius.",
111
- )
112
- interpolation_distance_from_filaments_ratio: Optional[float] = Field(
113
- default=None,
114
- description="The mesh size is interpolated from the filament boundaries into the matrix, over a given distance. This parameter determines the distance over which the mesh size is interpolated.",
115
- )
116
- rate_dependent_scaling_matrix: Optional[bool] = Field(
117
- default=False,
118
- description="Rate dependent scaling uses the expected skin depth in the matrix to determine the matrix mesh. If the skin depth is low (i.e. for high frequencies) this feature increases mesh density in the region where the current is expected to flow, while decreasing the mesh resolution in the region where the current is not expected to flow.",
119
- )
120
- skindepth_scaling_factor: Optional[float] = Field(
121
- default=None,
122
- description="Scaling factor for the estimate of the skin depth, used for rate dependent scaling.",
123
- )
124
- desired_elements_in_skindepth: Optional[float] = Field(
125
- default=None, description="Desired number of elements in the skin depth region. This parameter is used for rate dependent scaling, and determines the number of elements in the region where the current is expected to flow."
126
- )
127
-
128
- # -- Air mesh settings -- #
129
- class CACStrandMeshAir(BaseModel):
130
- """
131
- Level 3: Class for FiQuS ConductorAC
132
- """
133
-
134
- max_mesh_size_ratio: Optional[float] = Field(
135
- default=None,
136
- description="Mesh size at the outer boundary of the air region, relative to the filament radius. E.g. 10 means that the mesh size is 10 times the filament radius.",
137
- )
138
-
139
- # -- Strand mesh settings -- #
140
- class CACStrandMesh(BaseModel):
141
- """
142
- Level 2: Class for FiQuS ConductorAC
143
- """
144
-
145
- scaling_global: Optional[float] = Field(
146
- default=1, description="Global scaling factor for mesh size."
147
- )
148
- filaments: CACStrandMeshFilaments = CACStrandMeshFilaments()
149
- matrix: CACStrandMeshMatrix = CACStrandMeshMatrix()
150
- air: CACStrandMeshAir = CACStrandMeshAir()
151
-
152
-
153
- # ============= SOLVE ============= #
154
- # -- General parameters -- #
155
- class CACStrandSolveGeneralparameters(BaseModel):
156
- """
157
- Level 3: Class for general parameters
158
- """
159
- temperature: float = Field(default=1.9, description="Temperature (K) of the strand.")
160
- superconductor_linear: Optional[bool] = Field(default=False, description="For debugging: replace LTS by normal conductor.")
161
-
162
-
163
- # -- Initial conditions -- #
164
- class CACStrandSolveInitialconditions(BaseModel):
165
- """
166
- Level 3: Class for initial conditions
167
- """
168
-
169
- init_from_pos_file: bool = Field(
170
- default=False, description="This field is used to initialize the solution from a non-zero field solution stored in a .pos file."
171
- )
172
- pos_file_to_init_from: Optional[str] = Field(
173
- default=None,
174
- description="Name of .pos file for magnetic field (A/m) from which the solution should be initialized."
175
- " Should be in the Geometry_xxx/Mesh_xxx/ folder in which the Solution_xxx will be saved.",
176
- )
177
-
178
-
179
- # -- Source parameters -- #
180
- class CACStrandSolveSourceparametersSineSuperimposedDC(BaseModel):
181
- """
182
- Level 5: Class for superimposed DC field or current parameters for the sine source
183
- """
184
- field_magnitude: Optional[float] = Field(default=0.0, description="DC field magnitude (T) (direction along y-axis). Solution must be initialized with a non-zero field solution stored in a .pos file if non-zero DC field is used.")
185
- current_magnitude: Optional[float] = Field(default=0.0, description="DC current magnitude (A). Solution must be initialized with a non-zero field solution stored in a .pos file if non-zero DC current is used.")
186
-
187
- class CACStrandSolveSourceparametersSine(BaseModel):
188
- """
189
- Level 4: Class for Sine source parameters
190
- """
191
- frequency: Optional[float] = Field(default=None, description="Frequency of the sine source (Hz).")
192
- field_amplitude: Optional[float] = Field(default=None, description="Amplitude of the sine field (T).")
193
- current_amplitude: Optional[float] = Field(default=None, description="Amplitude of the sine current (A).")
194
- field_angle: Optional[float] = Field(default=90, description="Angle of the sine field direction, with respect to the x-axis (degrees).")
195
- superimposed_DC: CACStrandSolveSourceparametersSineSuperimposedDC = CACStrandSolveSourceparametersSineSuperimposedDC()
196
-
197
- class CACStrandSolveSourceparametersPiecewise(BaseModel):
198
- """
199
- Level 4: Class for piecewise (linear) source parameters
200
- """
201
- source_csv_file: Optional[str] = Field(default=None, description="File name for the from_file source type defining the time evolution of current and field (in-phase). Multipliers are used for each of them. The file should contain two columns: 'time' (s) and 'value' (field/current (T/A)), with these headers. If this field is set, times, applied_fields_relative and transport_currents_relative are ignored.")
202
- times: Optional[List[float]] = Field(default=None, description="Time instants (s) defining the piecewise linear sources. Used only if source_csv_file is not set. Can be scaled by time_multiplier.")
203
- applied_fields_relative: Optional[List[float]] = Field(default=None, description="Applied fields relative to multiplier applied_field_multiplier at the time instants 'times'. Used only if source_csv_file is not set.")
204
- transport_currents_relative: Optional[List[float]] = Field(default=None, description="Transport currents relative to multiplier transport_current_multiplier at the time instants 'times'. Used only if source_csv_file is not set.")
205
- time_multiplier: Optional[float] = Field(default=None, description="Multiplier for the time values in times (scales the time values). Also used for the time values in the source_csv_file.")
206
- applied_field_multiplier: Optional[float] = Field(default=None, description="Multiplier for the applied fields in applied_fields_relative. Also used for the values in the source_csv_file.")
207
- transport_current_multiplier: Optional[float] = Field(default=None, description="Multiplier for the transport currents in transport_currents_relative. Also used for the values in the source_csv_file.")
208
-
209
- class CACStrandSolveSourceparameters(BaseModel):
210
- """
211
- Level 3: Class for material properties
212
- """
213
-
214
- source_type: Literal['sine', 'piecewise'] = Field(
215
- default='sine',
216
- description="Time evolution of applied current and magnetic field. Supported options are: sine, sine_with_DC, piecewise_linear, from_list.",
217
- )
218
- boundary_condition_type: str = Field(
219
- default="Natural",
220
- description="Boundary condition type. Supported options are: Natural, Essential. Do not use essential boundary condition with induced currents.",
221
- )
222
- sine: CACStrandSolveSourceparametersSine = CACStrandSolveSourceparametersSine()
223
- piecewise: CACStrandSolveSourceparametersPiecewise = CACStrandSolveSourceparametersPiecewise()
224
-
225
-
226
- # -- Numerical parameters -- #
227
- class CACStrandSolveNumericalparametersSine(BaseModel):
228
- """
229
- Level 4: Numerical parameters corresponding to the sine source
230
- """
231
- timesteps_per_period: Optional[float] = Field(default=None, description="Initial value for number of time steps (-) per period for the sine source. Determines the initial time step size.")
232
- number_of_periods_to_simulate: Optional[float] = Field(default=None, description="Number of periods (-) to simulate for the sine source.")
233
-
234
- class CACStrandSolveNumericalparametersPiecewise(BaseModel):
235
- """
236
- Level 4: Numerical parameters corresponding to the piecewise source
237
- """
238
- time_to_simulate: Optional[float] = Field(default=None, description="Total time to simulate (s). Used for the piecewise source.")
239
- timesteps_per_time_to_simulate: Optional[float] = Field(default=None, description="If variable_max_timestep is False. Number of time steps (-) per period for the piecewise source.")
240
- force_stepping_at_times_piecewise_linear: bool = Field(default=False, description="If True, time-stepping will contain exactly the time instants that are in the times_source_piecewise_linear list (to avoid truncation maximum applied field/current values).")
241
-
242
- variable_max_timestep: bool = Field(default=False, description="If False, the maximum time step is kept constant through the simulation. If True, it varies according to the piecewise definition.")
243
- times_max_timestep_piecewise_linear: Optional[List[float]] = Field(default=None, description="Time instants (s) defining the piecewise linear maximum time step.")
244
- max_timestep_piecewise_linear: Optional[List[float]] = Field(default=None, description="Maximum time steps (s) at the times_max_timestep_piecewise_linear. Above the limits, linear extrapolation of the last two values.")
245
-
246
- class CACStrandSolveNumericalparameters(BaseModel):
247
- """
248
- Level 3: Class for numerical parameters
249
- """
250
-
251
- sine: CACStrandSolveNumericalparametersSine = CACStrandSolveNumericalparametersSine()
252
- piecewise: CACStrandSolveNumericalparametersPiecewise = CACStrandSolveNumericalparametersPiecewise()
253
-
254
-
255
- # -- Formulation parameters -- #
256
- class CACStrandSolveFormulationparameters(BaseModel):
257
- """
258
- Level 3: Class for finite element formulation parameters
259
- """
260
-
261
- formulation: Literal['voltage_based'] = Field(
262
- default='voltage_based',
263
- description="Currently, only possible option is voltage_based."
264
- )
265
- dynamic_correction: Optional[bool] = Field(
266
- default=True,
267
- description="In the voltage_based case, do we activate the dynamic correction?",
268
- )
269
- compute_temperature: Optional[bool] = Field(
270
- default=False, description="Do we compute the temperature?"
271
- )
272
-
273
- two_ell_periodicity : Optional[bool] = Field(
274
- default=True, description="True to integrate over twice the shortest periodicity length, False to integrate over the shortest periodicity length. "
275
- )
276
-
277
-
278
- class CACStrandSolve(BaseModel):
279
- """
280
- Level 2: Class for FiQuS ConductorAC Strand solver settings
281
- """
282
- pro_template: Optional[Literal['ConductorAC_template.pro']] = Field(
283
- default='ConductorAC_template.pro',
284
- description="Name of the .pro template file."
285
- )
286
- conductor_name: Optional[str] = Field(
287
- default=None, description="Name of the conductor. Must match a conductor name in the conductors section of the input YAML-file."
288
- )
289
- formulation_parameters: CACStrandSolveFormulationparameters = (
290
- CACStrandSolveFormulationparameters()
291
- )
292
- general_parameters: CACStrandSolveGeneralparameters = (
293
- CACStrandSolveGeneralparameters()
294
- )
295
- # material_properties: CACStrandSolveMaterialproperties = (
296
- # CACStrandSolveMaterialproperties()
297
- # )
298
- initial_conditions: CACStrandSolveInitialconditions = (
299
- CACStrandSolveInitialconditions()
300
- )
301
- source_parameters: CACStrandSolveSourceparameters = (
302
- CACStrandSolveSourceparameters()
303
- )
304
- numerical_parameters: CACStrandSolveNumericalparameters = (
305
- CACStrandSolveNumericalparameters()
306
- )
307
-
308
-
309
- # ============= POSTPROC ============= #
310
- class CACStrandPostprocBatchpostprocLossMapCrossSection(BaseModel):
311
- """
312
- Level 5: Class with settings for plotting a cross-section of the loss map.
313
- """
314
- plot_cross_section: bool = Field(
315
- default=False, description="Set True to plot a cross-section of the loss map."
316
- )
317
- save_plot: bool = Field(default=False, description="Set True to save the plot.")
318
- filename: str = Field(default="cross_section", description="Name of the plot file.")
319
- axis_to_cut: str = Field(
320
- default="x", description="Axis to cut for the cross-section."
321
- )
322
- cut_value: float = Field(
323
- default=0, description="Value of the axis to cut for the cross-section."
324
- )
325
-
326
- ylabel: str = Field(default="Loss", description="Label of the y-axis.")
327
- title: Optional[str] = Field(
328
- default=None,
329
- description="Title of the plot. The placeholder <<cut_value>> can be used to indicate the value of the cut axis.",
330
- )
331
-
332
-
333
- class CACStrandPostprocBatchpostprocLossMapCrossSectionSweep(BaseModel):
334
- """
335
- Level 5: Class with settings for animating a cross-section sweep of the loss map along one axis.
336
- """
337
- animate_cross_section_sweep: bool = Field(
338
- default=False,
339
- description="Set True to animate a cross-section sweep of the loss map along one axis.",
340
- )
341
- save_plot: bool = Field(
342
- default=False, description="Set True to save the animation."
343
- )
344
- filename: str = Field(
345
- default="crossSectionSweep", description="Name of the animation file."
346
- )
347
- axis_to_sweep: str = Field(
348
- default="x", description="Axis to sweep for the animation."
349
- )
350
- ylabel: str = Field(default="Loss", description="Label of the y-axis.")
351
- title: Optional[str] = Field(
352
- default=None,
353
- description="Title of the plot. Use <<sweep_value>> to indicate the value of the sweep axis.",
354
- )
355
-
356
-
357
- class CACStrandPostprocBatchpostprocLossMap(BaseModel):
358
- """
359
- Level 4: Class with settings for generating loss maps
360
- """
361
- produce_loss_map: bool = Field(
362
- default=False, description="Set True to produce a loss map."
363
- )
364
- save_plot: bool = Field(default=False, description="Set True to save the plot.")
365
- filename: str = Field(default="loss_map", description="Name of the plot file.")
366
- x_val: Optional[str] = Field(
367
- default=None, description="Parameter to be plotted on the x-axis. This field corresponds to a parameter in the input YAML-file. E.g. 'solve.source_parameters.sine.frequency' will plot the loss map for different frequencies."
368
- )
369
- y_val: Optional[str] = Field(
370
- default=None, description="Parameter to be plotted on the y-axis. This field corresponds to a parameter in the input YAML-file. E.g. 'solve.source_parameters.sine.field_amplitude' will plot the loss map for different applied field amplitudes."
371
- )
372
- x_steps: int = Field(default=20, description="Number of steps on the x-axis.")
373
- y_steps: int = Field(default=20, description="Number of steps on the y-axis.")
374
- loss_type: Literal['TotalLoss', 'FilamentLoss', 'CouplingLoss', 'EddyLoss'] = Field(
375
- default='TotalLoss',
376
- description="Type of loss to be plotted. Supported options are: TotalLoss, FilamentLoss, CouplingLoss, EddyLoss."
377
- )
378
- x_log: bool = Field(
379
- default=True, description="Set True to plot x-axis in log-scale."
380
- )
381
- y_log: bool = Field(
382
- default=True, description="Set True to plot y-axis in log-scale."
383
- )
384
- loss_log: bool = Field(
385
- default=True, description="Set True to plot loss in log-scale."
386
- )
387
- x_norm: float = Field(default=1, description="Normalization factor for x-axis.")
388
- y_norm: float = Field(default=1, description="Normalization factor for y-axis.")
389
- loss_norm: float = Field(default=1, description="Normalization factor for the AC-loss.")
390
- show_datapoints: bool = Field(
391
- default=True, description="Set True to show markers for all the datapoints in the loss map."
392
- )
393
-
394
- title: Optional[str] = Field(default=None, description="Title for the plot.")
395
- xlabel: Optional[str] = Field(default=None, description="Label for the x-axis.")
396
- ylabel: Optional[str] = Field(default=None, description="Label for the y-axis.")
397
-
398
- # lossType_dominance_contour: CACStrandPostprocBatchpostprocLossMapDominanceCountour = (
399
- # CACStrandPostprocBatchpostprocLossMapDominanceCountour()
400
- # )
401
-
402
- show_loss_type_dominance_contour: bool = Field(
403
- default=False,
404
- description="Set True to plot a contour curve separating regions where different loss types dominate. ",
405
- )
406
-
407
- cross_section: CACStrandPostprocBatchpostprocLossMapCrossSection = (
408
- CACStrandPostprocBatchpostprocLossMapCrossSection()
409
- )
410
- cross_section_sweep: CACStrandPostprocBatchpostprocLossMapCrossSectionSweep = (
411
- CACStrandPostprocBatchpostprocLossMapCrossSectionSweep()
412
- )
413
-
414
-
415
- class CACStrandPostprocBatchpostprocPlot2d(BaseModel):
416
- """
417
- Level 4: Class for 2D plot settings
418
- """
419
- produce_plot2d: bool = Field(
420
- default=False, description="Set True to produce a 2D plot."
421
- )
422
- combined_plot: bool = Field(
423
- default=False,
424
- description="Set True to produce a combined plot for all simulations. If False, a separate plot is produced for each simulation.",
425
- )
426
- save_plot: bool = Field(default=False, description="Set True to save the plot.")
427
- filename: str = Field(default="plot2d", description="Name of the plot file.")
428
- x_val: Optional[str] = Field(
429
- default=None, description="Value to be plotted on the x-axis. Parameters in the input YAML-file and class-variables from the plotter 'SimulationData' class can be accessed trough the notation << . >>. E.g. '<<solve.source_parameters.sine.frequency>>' will create a 2D plot with frequency on the x-axis. '<<time>>' will create a plot with time on the x-axis."
430
- )
431
- y_vals: Optional[List[str]] = Field(
432
- default=None, description=" List of values to be plotted on the y-axis. Parameters in the input YAML-file and class-variables from the plotter 'SimulationData' class can be accessed trough the notation << . >>. E.g. total AC-loss per cycle can be accessed as ['<<total_power_per_cycle['TotalLoss_dyn']>>']."
433
- )
434
- labels: Optional[List[str]] = Field(
435
- default=None,
436
- description="List of labels for the plot. Each label corresponding to a value in y_val.",
437
- )
438
- linestyle: Optional[str] = Field(
439
- default=None, description="Linestyle for the plot."
440
- )
441
-
442
- title: Optional[str] = Field(default=None, description="Title for the plot.")
443
- xlabel: Optional[str] = Field(default=None, description="Label for the x-axis.")
444
- ylabel: Optional[str] = Field(default=None, description="Label for the y-axis.")
445
- x_log: bool = Field(default=False, description="Set True to plot x-axis in log-scale.")
446
- y_log: bool = Field(default=False, description="Set True to plot y-axis in log-scale.")
447
- legend: bool = Field(default=True, description="Set True to show legend.")
448
-
449
-
450
- class CACStrandPostprocBatchpostprocFilter(BaseModel):
451
- """
452
- Level 4: Field for filtering simulations based on simulation parameters for batch post-processing
453
- """
454
- apply_filter: bool = Field(
455
- default=False,
456
- description="Set True to filter simulations by parameters from the input YAML-file.",
457
- )
458
- filter_criterion: Optional[str] = Field(
459
- default=None,
460
- description="Criterion used to filter simulations based on simulation parameters. For example will '<<solve.source_parameters.sine.frequency>> > 100' disregard simulations done with frequencies lower than 100Hz.",
461
- )
462
-
463
-
464
- class CACStrandPostprocBatchpostprocSort(BaseModel):
465
- """
466
- Level 4: Field for sorting simulations based on simulation parameters for batch post-processing
467
- """
468
- apply_sort: bool = Field(default=False, description="Set True to sort simulations.")
469
- sort_key: Optional[str] = Field(
470
- default=None,
471
- description="Criterion used to sort simulations based on simulation parameters. For example will 'sd.total_power_per_cycle['TotalLoss'] sort simulations based on the total loss.",
472
- )
473
-
474
-
475
- class CACStrandPostprocBatchpostproc(BaseModel):
476
- """
477
- Level 3: Class for batch post-processing settings
478
- """
479
- postProc_csv: Optional[str] = Field(
480
- default=None,
481
- description="Name of the .csv file for post-processing (without file extension). This file specifies the simulations to be post-processed. The file is structured into three columns, specifying the folder names to access the simulation results: 'input.run.geometry', 'input.run.mesh' and 'input.run.solve'. Each row corresponds to a simulation to be post-processed.",
482
- )
483
- output_folder: Optional[str] = Field(
484
- default=None,
485
- description="Batch post-processing creates a folder with the given name in the output directory, where all the plots are saved.",
486
- )
487
- filter: CACStrandPostprocBatchpostprocFilter = CACStrandPostprocBatchpostprocFilter()
488
- sort: CACStrandPostprocBatchpostprocSort = CACStrandPostprocBatchpostprocSort()
489
- loss_map: CACStrandPostprocBatchpostprocLossMap = CACStrandPostprocBatchpostprocLossMap()
490
- plot2d: CACStrandPostprocBatchpostprocPlot2d = CACStrandPostprocBatchpostprocPlot2d()
491
-
492
-
493
- class CACStrandPostprocPlotInstPower(BaseModel):
494
- """
495
- Level 3: Class with settings for generating plots of instantaneous power
496
- """
497
- show: bool = Field(default=False, description="Creates a plot for the calculated instantaneous AC loss (W/m) as a function of time (s).")
498
- title: str = Field(default="Instantaneous Power", description="Title for the plot.")
499
- save: bool = Field(default=False, description="Set True to save the plot.")
500
- save_file_name: str = Field(
501
- default="instantaneous_power", description="Name of the plot file."
502
- )
503
-
504
-
505
- class CACStrandPostprocCleanup(BaseModel):
506
- """
507
- Level 3: Class for cleanup settings
508
- """
509
- remove_pre_file: bool = Field(
510
- default=False,
511
- description="Set True to remove the .pre-file after post-processing, to save disk space.",
512
- )
513
- remove_res_file: bool = Field(
514
- default=False,
515
- description="Set True to remove the .res-file after post-processing, to save disk space.",
516
- )
517
- remove_msh_file: bool = Field(
518
- default=False,
519
- description="Set True to remove the .msh-file after post-processing, to save disk space.",
520
- )
521
-
522
-
523
- class CACStrandPostproc(BaseModel):
524
- """
525
- Level 2: Class for FiQuS ConductorAC
526
- """
527
-
528
- generate_pos_files: bool = Field(
529
- default=True,
530
- description="Set True to generate .pos-files during post-processing",
531
- )
532
- plot_instantaneous_power: CACStrandPostprocPlotInstPower = (
533
- CACStrandPostprocPlotInstPower()
534
- )
535
- compute_current_per_filament: bool = Field(
536
- default=False,
537
- description="Computes current in every filament, with decomposition into magnetization and transport current.",
538
- )
539
- save_last_current_density: Optional[str] = Field(
540
- default=None,
541
- description="Saves the last current density field solution (out-of-plane) in the file given as a string."
542
- " The '.pos' extension will be appended to it. Nothing is done if None."
543
- " This can be for using the current density as an initial condition (but not implemented yet).",
544
- )
545
- save_last_magnetic_field: Optional[str] = Field(
546
- default=None,
547
- description="Saves the last magnetic field solution (in-plane) in the file given as a string."
548
- " The '.pos' extension will be appended to it. Nothing is done if None."
549
- " This is for using the magnetic field as an initial condition for another resolution.",
550
- )
551
- cleanup: CACStrandPostprocCleanup = CACStrandPostprocCleanup()
552
- batch_postproc: CACStrandPostprocBatchpostproc = CACStrandPostprocBatchpostproc()
553
-
554
- # ============= BASE ============= #
555
- class CACStrand(BaseModel):
556
- """
557
- Level 1: Class for FiQuS ConductorAC
558
- """
559
-
560
- type: Literal["CACStrand"]
561
- geometry: CACStrandGeometry = CACStrandGeometry()
562
- mesh: CACStrandMesh = CACStrandMesh()
563
- solve: CACStrandSolve = CACStrandSolve()
564
- postproc: CACStrandPostproc = CACStrandPostproc()
565
-
1
+ from pydantic import BaseModel, Field, field_validator
2
+ from typing import List, Literal, Optional, Union
3
+
4
+
5
+ # ============= GEOMETRY ============= #
6
+ # -- Input/Output settings -- #
7
+ class CACStrandIOsettingsLoad(BaseModel):
8
+ """
9
+ Level 3: Class for Input/Output settings for the cable geometry
10
+ """
11
+
12
+ load_from_yaml: Optional[bool] = Field(
13
+ default=False,
14
+ description="True to load the geometry from a YAML file, false to generate the geometry.",
15
+ )
16
+ filename: Optional[str] = Field(
17
+ default=None,
18
+ description="Name of the YAML file from which to load the geometry.",
19
+ )
20
+
21
+ class CACStrandIOsettingsSave(BaseModel):
22
+ """
23
+ Level 3: Class for Input/Output settings for the cable geometry
24
+ """
25
+
26
+ save_to_yaml: Optional[bool] = Field(
27
+ default=False,
28
+ description="True to save the geometry to a YAML-file, false to not save the geometry.",
29
+ )
30
+ filename: Optional[str] = Field(
31
+ default=None,
32
+ description="Name of the output geometry YAML file.",
33
+ )
34
+
35
+ class CACStrandGeometryIOsettings(BaseModel):
36
+ """
37
+ Level 2: Class for Input/Output settings for the cable geometry
38
+ """
39
+
40
+ load: CACStrandIOsettingsLoad = (
41
+ CACStrandIOsettingsLoad()
42
+ )
43
+ save: CACStrandIOsettingsSave = (
44
+ CACStrandIOsettingsSave()
45
+ )
46
+
47
+ # -- Strand geometry parameters -- #
48
+ class CACStrandGeometry(BaseModel):
49
+ """
50
+ Level 2: Class for strand geometry parameters
51
+ """
52
+ io_settings: CACStrandGeometryIOsettings = CACStrandGeometryIOsettings()
53
+ hexagonal_filaments: Optional[bool] = Field(
54
+ default=None,
55
+ description="Field for specifying the shape of the filaments. True for hexagonal, False for circular.",
56
+ )
57
+ hexagonal_holes: Optional[bool] = Field(
58
+ default=None,
59
+ description="Field for specifying the shape of the filament holes. True for hexagonal, False for circular.",
60
+ )
61
+ filament_circular_distribution: Optional[bool] = Field(
62
+ default=None,
63
+ description="Field for specifying the geometrical distribution of the filaments. Set True to distribute the filaments in a circular pattern and False to distribute them in a hexagonal pattern."
64
+ )
65
+ air_radius: Optional[float] = Field(
66
+ default=None, description="Radius of the circular numerical air region (m)."
67
+ )
68
+ type: Literal['strand_only', 'periodic_square', 'coil'] = Field(
69
+ default='strand_only',
70
+ description="Type of model geometry which will be generated. Supported options are: strand_only, periodic_square"
71
+ "strand_only models the strand in an circular air domain (natural boundary condition)"
72
+ "periodic_square models the strand in an square air domain (periodic boundary condition)"
73
+ "coil models a single coil winding in open space (uses hybrid boundary conditions)"
74
+ )
75
+ coil_radius: Optional[float] = Field(
76
+ default=None, description="used in geometry type 'coil' to determine the distance from strand center to mirroring plane (m). Should always be bigger than strand radius."
77
+ )
78
+ rotate_angle: Optional[float] = Field(
79
+ default=None, description="Rotates strand geometry by specified angle in deg counterclockwise around the z axis and x=0 and y=0"
80
+ )
81
+ # ============= MESH ============= #
82
+ # -- Filament mesh settings -- #
83
+ class CACStrandMeshFilaments(BaseModel):
84
+ """
85
+ Level 3: Class for FiQuS ConductorAC
86
+ """
87
+
88
+ boundary_mesh_size_ratio: Optional[float] = Field(
89
+ default=None,
90
+ description="Mesh size at filament boundaries, relative to the radius of the filaments. E.g. 0.1 means that the mesh size is 0.1 times the filament radius.",
91
+ )
92
+ center_mesh_size_ratio: Optional[float] = Field(
93
+ default=None,
94
+ description="Mesh size at filament center, relative to the radius of the filaments. E.g. 0.1 means that the mesh size is 0.1 times the filament radius.",
95
+ )
96
+ amplitude_dependent_scaling: Optional[bool] = Field(
97
+ default=False,
98
+ description="Amplitude dependent scaling uses the field amplitude to approximate the field penetration distance in the filaments to alter the filament mesh. If the field penetration distance is low (i.e. for low field amplitudes) this feature increases mesh density in the region where the field is expected to penetrate, and decreases the mesh resolution in the region where the field does not penetrate.",
99
+ )
100
+ field_penetration_depth_scaling_factor: Optional[float] = Field(
101
+ default=None,
102
+ description="Scaling factor for the estimate of the field penetration depth, used for amplitude dependent scaling. ",
103
+ )
104
+ desired_elements_in_field_penetration_region: Optional[float] = Field(
105
+ default=None,
106
+ description="Desired number of elements in the field penetration region. This parameter is used for amplitude dependent scaling, and determines the number of elements in the region where the field is expected to penetrate.",
107
+ )
108
+
109
+ # -- Matrix mesh settings -- #
110
+ class CACStrandMeshMatrix(BaseModel):
111
+ """
112
+ Level 3: Class for FiQuS ConductorAC
113
+ """
114
+
115
+ mesh_size_matrix_ratio_inner: Optional[float] = Field(
116
+ default=None,
117
+ description="Mesh size at the matrix center, relative to the filament radius.",
118
+ )
119
+ mesh_size_matrix_ratio_middle: Optional[float] = Field(
120
+ default=None,
121
+ description="Mesh size at the matrix middle partition, relative to the filament radius.",
122
+ )
123
+ mesh_size_matrix_ratio_outer: Optional[float] = Field(
124
+ default=None,
125
+ description="Mesh size at the matrix outer boundary, relative to the filament radius.",
126
+ )
127
+ interpolation_distance_from_filaments_ratio: Optional[float] = Field(
128
+ default=None,
129
+ description="The mesh size is interpolated from the filament boundaries into the matrix, over a given distance. This parameter determines the distance over which the mesh size is interpolated.",
130
+ )
131
+ rate_dependent_scaling_matrix: Optional[bool] = Field(
132
+ default=False,
133
+ description="Rate dependent scaling uses the expected skin depth in the matrix to determine the matrix mesh. If the skin depth is low (i.e. for high frequencies) this feature increases mesh density in the region where the current is expected to flow, while decreasing the mesh resolution in the region where the current is not expected to flow.",
134
+ )
135
+ skindepth_scaling_factor: Optional[float] = Field(
136
+ default=None,
137
+ description="Scaling factor for the estimate of the skin depth, used for rate dependent scaling.",
138
+ )
139
+ desired_elements_in_skindepth: Optional[float] = Field(
140
+ default=None, description="Desired number of elements in the skin depth region. This parameter is used for rate dependent scaling, and determines the number of elements in the region where the current is expected to flow."
141
+ )
142
+ force_center_symmetry: Optional[bool] = Field(
143
+ default=False, description="This option can be set in strands without center filament to enforce a cross of symmetric nodes in the center of the strand mesh - used within Glock thesis."
144
+ )
145
+
146
+ # -- Air mesh settings -- #
147
+ class CACStrandMeshAir(BaseModel):
148
+ """
149
+ Level 3: Class for FiQuS ConductorAC
150
+ """
151
+
152
+ max_mesh_size_ratio: Optional[float] = Field(
153
+ default=None,
154
+ description="Mesh size at the outer boundary of the air region, relative to the filament radius. E.g. 10 means that the mesh size is 10 times the filament radius.",
155
+ )
156
+
157
+ # -- Strand mesh settings -- #
158
+ class CACStrandMesh(BaseModel):
159
+ """
160
+ Level 2: Class for FiQuS ConductorAC
161
+ """
162
+
163
+ scaling_global: Optional[float] = Field(
164
+ default=1, description="Global scaling factor for mesh size."
165
+ )
166
+ filaments: CACStrandMeshFilaments = CACStrandMeshFilaments()
167
+ matrix: CACStrandMeshMatrix = CACStrandMeshMatrix()
168
+ air: CACStrandMeshAir = CACStrandMeshAir()
169
+
170
+
171
+ # ============= SOLVE ============= #
172
+ # -- General parameters -- #
173
+ class CACStrandSolveGeneralparameters(BaseModel):
174
+ """
175
+ Level 3: Class for general parameters
176
+ """
177
+ temperature: float = Field(default=1.9, description="Temperature (K) of the strand.")
178
+ superconductor_linear: Optional[bool] = Field(default=False, description="For debugging: replace LTS by normal conductor.")
179
+
180
+ noOfMPITasks: Optional[Union[bool, int]] = Field(
181
+ default=False,
182
+ title="No. of tasks for MPI parallel run of GetDP",
183
+ description=(
184
+ "If integer, GetDP will be run in parallel using MPI. This is only valid"
185
+ " if MPI is installed on the system and an MPI-enabled GetDP is used."
186
+ " If False, GetDP will be run in serial without invoking mpiexec."
187
+ ),
188
+ )
189
+
190
+ # -- Initial conditions -- #
191
+ class CACStrandSolveInitialconditions(BaseModel):
192
+ """
193
+ Level 3: Class for initial conditions
194
+ """
195
+
196
+ init_type: Optional[Literal['virgin', 'pos_file', 'uniform_field']] = Field(
197
+ default='virgin',
198
+ description="Type of initialization for the simulation. (i) 'virgin' is the default type, the initial magnetic field is zero,"
199
+ " (ii) 'pos_file' is to initialize from the solution of another solution, given by the solution_to_init_from entry,"
200
+ " and (iii) 'uniform_field' is to initialize at a uniform field, which will be the applied field at the initial time of the simulation."
201
+ " Note that the uniform_field option does not allow any non-zero transport current."
202
+ )
203
+ solution_to_init_from: Optional[Union[int, str]] = Field(
204
+ default=None,
205
+ description="Name xxx of the solution from which the simulation should be initialized. The file last_magnetic_field.pos of folder Solution_xxx will be used for the initial solution."
206
+ " It must be in the Geometry_xxx/Mesh_xxx/ folder in which the Solution_xxx will be saved.",
207
+ )
208
+
209
+
210
+ # -- Source parameters -- #
211
+ class CACStrandSolveSourceparametersSineSuperimposedDC(BaseModel):
212
+ """
213
+ Level 5: Class for superimposed DC field or current parameters for the sine source
214
+ """
215
+ field_magnitude: Optional[float] = Field(default=0.0, description="DC field magnitude (T), in the same direction as the AC applied field. Solution must be initialized with a non-zero field solution, either stored in a .pos file, or a uniform field, if non-zero DC field is used.")
216
+ current_magnitude: Optional[float] = Field(default=0.0, description="DC current magnitude (A). Solution must be initialized with a non-zero field solution stored in a .pos file if non-zero DC current is used.")
217
+
218
+ class CACStrandSolveSourceparametersSine(BaseModel):
219
+ """
220
+ Level 4: Class for Sine source parameters
221
+ """
222
+ frequency: Optional[float] = Field(default=None, description="Frequency of the sine source (Hz).")
223
+ field_amplitude: Optional[float] = Field(default=None, description="Amplitude of the sine field (T).")
224
+ current_amplitude: Optional[float] = Field(default=None, description="Amplitude of the sine current (A).")
225
+ superimposed_DC: CACStrandSolveSourceparametersSineSuperimposedDC = CACStrandSolveSourceparametersSineSuperimposedDC()
226
+
227
+ class CACStrandSolveSourceparametersRotating(BaseModel):
228
+ """
229
+ Level 4: Class for Rotating magnetic source field parameters
230
+ """
231
+ frequency: Optional[float] = Field(default=None, description="Frequency of field rotation around z-axis")
232
+ field_magnitude: Optional[float] = Field(default=None, description="constant Magnitude of the rotating field (T).")
233
+
234
+
235
+ class CACStrandSolveSourceparametersPiecewise(BaseModel):
236
+ """
237
+ Level 4: Class for piecewise (linear) source parameters
238
+ """
239
+ source_csv_file: Optional[str] = Field(default=None, description="File name for the from_file source type defining the time evolution of current and field (in-phase)."
240
+ " Multipliers are used for each of them. The file should contain two columns: 'time' (s) and 'value' (field/current (T/A)), with these headers."
241
+ " If this field is set, times, applied_fields_relative and transport_currents_relative are ignored.")
242
+ times: Optional[List[float]] = Field(default=None, description="Time instants (s) defining the piecewise linear sources. Used only if source_csv_file is not set. Can be scaled by time_multiplier.")
243
+ applied_fields_relative: Optional[List[float]] = Field(default=None, description="Applied fields relative to multiplier applied_field_multiplier at the time instants 'times'. Used only if source_csv_file is not set.")
244
+ transport_currents_relative: Optional[List[float]] = Field(default=None, description="Transport currents relative to multiplier transport_current_multiplier at the time instants 'times'. Used only if source_csv_file is not set.")
245
+ time_multiplier: Optional[float] = Field(default=None, description="Multiplier for the time values in times (scales the time values). Also used for the time values in the source_csv_file.")
246
+ applied_field_multiplier: Optional[float] = Field(default=None, description="Multiplier for the applied fields in applied_fields_relative. Also used for the values in the source_csv_file.")
247
+ transport_current_multiplier: Optional[float] = Field(default=None, description="Multiplier for the transport currents in transport_currents_relative. Also used for the values in the source_csv_file.")
248
+
249
+ class CACStrandSolveSourceparameters(BaseModel):
250
+ """
251
+ Level 3: Class for material properties
252
+ """
253
+
254
+ source_type: Literal['sine', 'piecewise', 'rotating'] = Field(
255
+ default='sine',
256
+ description="Time evolution of applied current and magnetic field. Supported options are: sine, sine_with_DC, piecewise_linear, from_list, rotating.",
257
+ )
258
+ sine: CACStrandSolveSourceparametersSine = CACStrandSolveSourceparametersSine()
259
+ piecewise: CACStrandSolveSourceparametersPiecewise = CACStrandSolveSourceparametersPiecewise()
260
+ rotating: CACStrandSolveSourceparametersRotating = CACStrandSolveSourceparametersRotating()
261
+ field_angle: Optional[float] = Field(default=90, description="Angle of the source magnetic field, with respect to the x-axis (degrees).")
262
+
263
+
264
+ # -- Numerical parameters -- #
265
+ class CACStrandSolveNumericalparametersSine(BaseModel):
266
+ """
267
+ Level 4: Numerical parameters corresponding to the sine source
268
+ """
269
+ timesteps_per_period: Optional[float] = Field(default=None, description="Initial value for number of time steps (-) per period for the sine source. Determines the initial time step size.")
270
+ number_of_periods_to_simulate: Optional[float] = Field(default=None, description="Number of periods (-) to simulate for the sine source.")
271
+
272
+ class CACStrandSolveNumericalparametersRotating(BaseModel):
273
+ """
274
+ Level 4: Numerical parameters corresponding to the sine source
275
+ """
276
+ timesteps_per_period: Optional[float] = Field(default=None, description="Initial value for number of time steps (-) per period for source rotation. Determines the initial time step size.")
277
+ number_of_periods_to_simulate: Optional[float] = Field(default=None, description="Number of periods (-) to simulate for the source rotation.")
278
+
279
+ class CACStrandSolveNumericalparametersPiecewise(BaseModel):
280
+ """
281
+ Level 4: Numerical parameters corresponding to the piecewise source
282
+ """
283
+ time_to_simulate: Optional[float] = Field(default=None, description="Total time to simulate (s). Used for the piecewise source.")
284
+ timesteps_per_time_to_simulate: Optional[float] = Field(default=None, description="If variable_max_timestep is False. Number of time steps (-) per period for the piecewise source.")
285
+ force_stepping_at_times_piecewise_linear: bool = Field(default=False, description="If True, time-stepping will contain exactly the time instants that are in the times_source_piecewise_linear list (to avoid truncation maximum applied field/current values).")
286
+
287
+ variable_max_timestep: bool = Field(default=False, description="If False, the maximum time step is kept constant through the simulation. If True, it varies according to the piecewise definition.")
288
+ times_max_timestep_piecewise_linear: Optional[List[float]] = Field(default=None, description="Time instants (s) defining the piecewise linear maximum time step.")
289
+ max_timestep_piecewise_linear: Optional[List[float]] = Field(default=None, description="Maximum time steps (s) at the times_max_timestep_piecewise_linear. Above the limits, linear extrapolation of the last two values.")
290
+
291
+ class CACStrandSolveNumericalparameters(BaseModel):
292
+ """
293
+ Level 3: Class for numerical parameters
294
+ """
295
+ sine: CACStrandSolveNumericalparametersSine = CACStrandSolveNumericalparametersSine()
296
+ piecewise: CACStrandSolveNumericalparametersPiecewise = CACStrandSolveNumericalparametersPiecewise()
297
+ rotating: CACStrandSolveNumericalparametersRotating = CACStrandSolveNumericalparametersRotating()
298
+
299
+
300
+ # -- Formulation parameters -- #
301
+ class CACStrandSolveFormulationparameters(BaseModel):
302
+ """
303
+ Level 3: Class for finite element formulation parameters
304
+ """
305
+ formulation: Literal['CATI', 'AI_uncoupled'] = Field(
306
+ default='CATI',
307
+ description="Which formulation? CATI is the default and usual choice (was named voltage_based before -> to be changed from now on) to model hysteresis/coupling/eddy currents with the CATI method."
308
+ " AI_uncoupled is a conventional 2D formulation with axial currents modelling UNCOUPLED filaments (and eddy currents in matrix)."
309
+ )
310
+ dynamic_correction: Optional[bool] = Field(
311
+ default=True,
312
+ description="With the CATI method, do we activate the dynamic correction?",
313
+ )
314
+ compute_temperature: Optional[bool] = Field(
315
+ default=False, description="Do we compute the temperature?"
316
+ )
317
+ two_ell_periodicity : Optional[bool] = Field(
318
+ default=True, description="With CATI method: True to integrate over twice the shortest periodicity length (recommended), False to integrate over the shortest periodicity length (not recommended)."
319
+ )
320
+
321
+ class CACStrandSolveDiffusionBarriers(BaseModel):
322
+ enable: Optional[bool] = Field(
323
+ default=False, description="Set True to enable diffusion barriers."
324
+ )
325
+
326
+ load_data_from_yaml: Optional[bool] = Field(
327
+ default=False, description="Set True to load the diffusion barrier data from the input YAML-file. Otherwise, the thickness and resistivity specified in this file are used."
328
+ )
329
+
330
+ resistivity: Optional[float] = Field(
331
+ default=1e-6, description="Resistivity of the diffusion barriers (Ohm*m)."
332
+ )
333
+ thickness: Optional[float] = Field(
334
+ default=1e-6, description="Thickness of the diffusion barriers (m)."
335
+ )
336
+
337
+ class CACStrandSolve(BaseModel):
338
+ """
339
+ Level 2: Class for FiQuS ConductorAC Strand solver settings
340
+ """
341
+ pro_template: Optional[Literal['ConductorAC_template.pro']] = Field(
342
+ default='ConductorAC_template.pro',
343
+ description="Name of the .pro template file."
344
+ )
345
+ conductor_name: Optional[str] = Field(
346
+ default=None, description="Name of the conductor. Must match a conductor name in the conductors section of the input YAML-file."
347
+ )
348
+ formulation_parameters: CACStrandSolveFormulationparameters = (
349
+ CACStrandSolveFormulationparameters()
350
+ )
351
+ general_parameters: CACStrandSolveGeneralparameters = (
352
+ CACStrandSolveGeneralparameters()
353
+ )
354
+ initial_conditions: CACStrandSolveInitialconditions = (
355
+ CACStrandSolveInitialconditions()
356
+ )
357
+ diffusion_barriers: CACStrandSolveDiffusionBarriers = (
358
+ CACStrandSolveDiffusionBarriers()
359
+ )
360
+ global_diffusion_barrier: CACStrandSolveDiffusionBarriers = Field(
361
+ default=CACStrandSolveDiffusionBarriers(), description="Additional diffusion barrier around all filaments together (global)."
362
+ "This is created on a line between two strand matrix regions."
363
+ "One around the filaments and the other for the external ring."
364
+ )
365
+ source_parameters: CACStrandSolveSourceparameters = (
366
+ CACStrandSolveSourceparameters()
367
+ )
368
+ numerical_parameters: CACStrandSolveNumericalparameters = (
369
+ CACStrandSolveNumericalparameters()
370
+ )
371
+
372
+
373
+ # ============= POSTPROC ============= #
374
+ class CACStrandPostprocBatchpostprocLossMapCrossSection(BaseModel):
375
+ """
376
+ Level 5: Class with settings for plotting a cross-section of the loss map.
377
+ """
378
+ plot_cross_section: bool = Field(
379
+ default=False, description="Set True to plot a cross-section of the loss map."
380
+ )
381
+ save_plot: bool = Field(default=False, description="Set True to save the plot.")
382
+ filename: str = Field(default="cross_section", description="Name of the plot file.")
383
+ axis_to_cut: str = Field(
384
+ default="x", description="Axis to cut for the cross-section."
385
+ )
386
+ cut_value: float = Field(
387
+ default=0, description="Value of the axis to cut for the cross-section."
388
+ )
389
+
390
+ ylabel: str = Field(default="Loss", description="Label of the y-axis.")
391
+ title: Optional[str] = Field(
392
+ default=None,
393
+ description="Title of the plot. The placeholder <<cut_value>> can be used to indicate the value of the cut axis.",
394
+ )
395
+
396
+
397
+ class CACStrandPostprocBatchpostprocLossMapCrossSectionSweep(BaseModel):
398
+ """
399
+ Level 5: Class with settings for animating a cross-section sweep of the loss map along one axis.
400
+ """
401
+ animate_cross_section_sweep: bool = Field(
402
+ default=False,
403
+ description="Set True to animate a cross-section sweep of the loss map along one axis.",
404
+ )
405
+ save_plot: bool = Field(
406
+ default=False, description="Set True to save the animation."
407
+ )
408
+ filename: str = Field(
409
+ default="crossSectionSweep", description="Name of the animation file."
410
+ )
411
+ axis_to_sweep: str = Field(
412
+ default="x", description="Axis to sweep for the animation."
413
+ )
414
+ ylabel: str = Field(default="Loss", description="Label of the y-axis.")
415
+ title: Optional[str] = Field(
416
+ default=None,
417
+ description="Title of the plot. Use <<sweep_value>> to indicate the value of the sweep axis.",
418
+ )
419
+
420
+ class CACStrandPostprocBatchpostprocROHFgrid(BaseModel):
421
+ """
422
+ Level 4: Class with settings to perform actions on a ROHF model based on a grid of simulations.
423
+ """
424
+ produce_error_map: bool = Field(
425
+ default=False, description="Set True to produce a error map of the definced error_type. If the fit_rohf option is enabled it will compute the map for the new ROHF model ignoring everything in the fluxmodel.csv."
426
+ )
427
+ interpolate_error_map: bool = Field(default=False, description="Interpolate colormap linear between the computed values (graphical purposes)")
428
+ error_type: str = Field(default="pc_loss", description="realtive error metric displayed by the map. Options: pc_loss, flux, dyn_loss")
429
+
430
+ fit_rohf: bool = Field(default=False, description="Fit a ROHF model on the simulation grid given in the simulation.csv")
431
+ fit_rohf_N: Optional[int] = Field(
432
+ default=7,
433
+ description="Number of ROHF cells to use for the fit. Default is 7.",
434
+ )
435
+ fit_rohf_tausweep_IIC: Optional[float] = Field(
436
+ default=1.0,
437
+ description="I/Ic ratio used to fit the ratedependence parameters (taus)."
438
+ )
439
+
440
+ class CACStrandPostprocBatchpostprocLossMap(BaseModel):
441
+ """
442
+ Level 4: Class with settings for generating loss maps
443
+ """
444
+ produce_loss_map: bool = Field(
445
+ default=False, description="Set True to produce a loss map."
446
+ )
447
+ save_plot: bool = Field(default=False, description="Set True to save the plot.")
448
+ filename: str = Field(default="loss_map", description="Name of the plot file.")
449
+ x_val: Optional[str] = Field(
450
+ default=None, description="Parameter to be plotted on the x-axis. This field corresponds to a parameter in the input YAML-file. E.g. 'solve.source_parameters.sine.frequency' will plot the loss map for different frequencies."
451
+ )
452
+ y_val: Optional[str] = Field(
453
+ default=None, description="Parameter to be plotted on the y-axis. This field corresponds to a parameter in the input YAML-file. E.g. 'solve.source_parameters.sine.field_amplitude' will plot the loss map for different applied field amplitudes."
454
+ )
455
+ x_steps: int = Field(default=20, description="Number of steps on the x-axis.")
456
+ y_steps: int = Field(default=20, description="Number of steps on the y-axis.")
457
+ loss_type: Literal['TotalLoss', 'FilamentLoss', 'CouplingLoss', 'EddyLoss'] = Field(
458
+ default='TotalLoss',
459
+ description="Type of loss to be plotted. Supported options are: TotalLoss, FilamentLoss, CouplingLoss, EddyLoss."
460
+ )
461
+ x_log: bool = Field(
462
+ default=True, description="Set True to plot x-axis in log-scale."
463
+ )
464
+ y_log: bool = Field(
465
+ default=True, description="Set True to plot y-axis in log-scale."
466
+ )
467
+ loss_log: bool = Field(
468
+ default=True, description="Set True to plot loss in log-scale."
469
+ )
470
+ x_norm: float = Field(default=1, description="Normalization factor for x-axis.")
471
+ y_norm: float = Field(default=1, description="Normalization factor for y-axis.")
472
+ loss_norm: float = Field(default=1, description="Normalization factor for the AC-loss.")
473
+ show_datapoints: bool = Field(
474
+ default=True, description="Set True to show markers for all the datapoints in the loss map."
475
+ )
476
+
477
+ title: Optional[str] = Field(default=None, description="Title for the plot.")
478
+ xlabel: Optional[str] = Field(default=None, description="Label for the x-axis.")
479
+ ylabel: Optional[str] = Field(default=None, description="Label for the y-axis.")
480
+
481
+ # lossType_dominance_contour: CACStrandPostprocBatchpostprocLossMapDominanceCountour = (
482
+ # CACStrandPostprocBatchpostprocLossMapDominanceCountour()
483
+ # )
484
+
485
+ show_loss_type_dominance_contour: bool = Field(
486
+ default=False,
487
+ description="Set True to plot a contour curve separating regions where different loss types dominate. ",
488
+ )
489
+
490
+ cross_section: CACStrandPostprocBatchpostprocLossMapCrossSection = (
491
+ CACStrandPostprocBatchpostprocLossMapCrossSection()
492
+ )
493
+ cross_section_sweep: CACStrandPostprocBatchpostprocLossMapCrossSectionSweep = (
494
+ CACStrandPostprocBatchpostprocLossMapCrossSectionSweep()
495
+ )
496
+
497
+
498
+ class CACStrandPostprocBatchpostprocPlot2d(BaseModel):
499
+ """
500
+ Level 4: Class for 2D plot settings
501
+ """
502
+ produce_plot2d: bool = Field(
503
+ default=False, description="Set True to produce a 2D plot."
504
+ )
505
+ combined_plot: bool = Field(
506
+ default=False,
507
+ description="Set True to produce a combined plot for all simulations. If False, a separate plot is produced for each simulation.",
508
+ )
509
+ save_pgfdata: bool = Field(
510
+ default=False,
511
+ description="Set True to export the plot data in pgfplot readable .txt format stored in output_folder. Currently only supports combined plots.",
512
+ )
513
+ save_plot: bool = Field(default=False, description="Set True to save the plot.")
514
+ filename: str = Field(default="plot2d", description="Name of the plot file.")
515
+ x_val: Optional[str] = Field(
516
+ default=None, description="Value to be plotted on the x-axis. Parameters in the input YAML-file and class-variables from the plotter 'SimulationData' class can be accessed trough dot notation 'simulation.' E.g. 'simulation.f' will create a 2D plot with sine source frequency on the x-axis. 'simulation.time' will create a plot with time on the x-axis."
517
+ )
518
+ y_vals: Optional[List[str]] = Field(
519
+ default=None, description=" List of values to be plotted on the y-axis. Parameters in the input YAML-file and class-variables from the plotter 'SimulationData' class can be accessed trough dot notation 'simulation.' E.g. total AC-loss per cycle can be accessed as ['simulation.total_power_per_cycle['TotalLoss_dyn']']."
520
+ )
521
+ y_val_fluxmodel: Optional[str] = Field(
522
+ default=None, description=" Attribute of the 'ROHFmodel' class which is plotted on the y-axis. Access via dot notation with 'fluxmodel.' and 'simulation.' E.g. ROHF computed flux - 'fluxmodel.compute(I=simulation.I_transport,time=simulation.time)[0]'"
523
+ )
524
+ reference_vals: Optional[List[str]] = Field(default=None, description="reference values as set of two list [xvals, yvals] which will be plotted in the combined plot (For reference curves)")
525
+ reference_label: Optional[str] = Field(default=None, description="label text for the reference data in the plot legend")
526
+ labels: Optional[List[str]] = Field(
527
+ default=None,
528
+ description="List of labels for the plot. Each label corresponding to a value in y_val.",
529
+ )
530
+ linestyle: Optional[str] = Field(
531
+ default=None, description="Linestyle for the plot."
532
+ )
533
+
534
+ title: Optional[str] = Field(default=None, description="Title for the plot.")
535
+ xlabel: Optional[str] = Field(default=None, description="Label for the x-axis.")
536
+ ylabel: Optional[str] = Field(default=None, description="Label for the y-axis.")
537
+ x_log: bool = Field(default=False, description="Set True to plot x-axis in log-scale.")
538
+ y_log: bool = Field(default=False, description="Set True to plot y-axis in log-scale.")
539
+ legend: bool = Field(default=True, description="Set True to show legend.")
540
+
541
+
542
+ class CACStrandPostprocBatchpostprocFilter(BaseModel):
543
+ """
544
+ Level 4: Field for filtering simulations based on simulation parameters for batch post-processing
545
+ """
546
+ apply_filter: bool = Field(
547
+ default=False,
548
+ description="Set True to filter simulations by parameters from the input YAML-file.",
549
+ )
550
+ filter_criterion: Optional[str] = Field(
551
+ default=None,
552
+ description="Criterion used to filter simulations based on simulation parameters. For example will '<<solve.source_parameters.sine.frequency>> > 100' disregard simulations done with frequencies lower than 100Hz.",
553
+ )
554
+
555
+
556
+ class CACStrandPostprocBatchpostprocSort(BaseModel):
557
+ """
558
+ Level 4: Field for sorting simulations based on simulation parameters for batch post-processing
559
+ """
560
+ apply_sort: bool = Field(default=False, description="Set True to sort simulations.")
561
+ sort_key: Optional[str] = Field(
562
+ default=None,
563
+ description="Criterion used to sort simulations based on simulation parameters. For example will 'sd.total_power_per_cycle['TotalLoss'] sort simulations based on the total loss.",
564
+ )
565
+
566
+
567
+ class CACStrandPostprocBatchpostproc(BaseModel):
568
+ """
569
+ Level 3: Class for batch post-processing settings
570
+ """
571
+ simulations_csv: Optional[str] = Field(
572
+ default=None,
573
+ description="Name of the .csv file for post-processing (without file extension). This file specifies the simulations to be post-processed. The file is structured into three columns, specifying the folder names to access the simulation results: 'input.run.geometry', 'input.run.mesh' and 'input.run.solve'. Each row corresponds to a simulation to be post-processed.",
574
+ )
575
+ fluxmodels_csv: Optional[str] = Field(
576
+ default=None,
577
+ description="Name of the .csv file for post-processing (without file extension). This file specifies the fluxmodels to be post-processed. The file is structured into three columns, specifying the folder names to access the simulation results: 'input.run.geometry', 'input.run.mesh' and 'input.run.solve'. Each row corresponds to a simulation to be post-processed.",
578
+ )
579
+ filter: CACStrandPostprocBatchpostprocFilter = CACStrandPostprocBatchpostprocFilter()
580
+ sort: CACStrandPostprocBatchpostprocSort = CACStrandPostprocBatchpostprocSort()
581
+ loss_map: CACStrandPostprocBatchpostprocLossMap = CACStrandPostprocBatchpostprocLossMap()
582
+ rohf_on_grid: CACStrandPostprocBatchpostprocROHFgrid = CACStrandPostprocBatchpostprocROHFgrid()
583
+ plot2d: CACStrandPostprocBatchpostprocPlot2d = CACStrandPostprocBatchpostprocPlot2d()
584
+
585
+ class CACStrandPostprocPlotFlux(BaseModel):
586
+ """
587
+ Level 3: Class with settings flux related plots and the related - reduced order hysteretic flux (ROHF) model.
588
+ The ROHF model can either be initialized from a predefined parameter file or freshly fitted on the solution with a given number_of_cells and kappa_spacing_type (will not be rate dependent).
589
+ """
590
+ show: Optional[bool] = Field(
591
+ default=False,
592
+ description="Enable flux related plots.",
593
+ )
594
+ rohf: Optional[bool] = Field(
595
+ default=False,
596
+ description="Enable ROHF model.",
597
+ )
598
+
599
+ rohf_file: Optional[str] = Field(
600
+ default=None,
601
+ description="Name of a .txt file in the geometry folder containing tau, kappa and alpha values. The file has to be structured into three columns (separated by whitespaces) with the preliminary header-row 'taus kappas alphas'. Each row corresponds to one cell of the multicell ROHF model.",
602
+ )
603
+ rohf_N: Optional[int] = Field(
604
+ default=None,
605
+ description="Total number of cells (N) for the ROHF model. If a parameter_file_name is given this option will be disregarded in favour of the parameterfile definitions.",
606
+ )
607
+ rohf_kappa_spacing: Optional[str] = Field(
608
+ default=None,
609
+ description="Spacing strategy for the N kappa values of the ROHF model. Options: 'linear', 'log', 'invlog' if left blank it will set the kappa interval based on a error minimization. If a parameter_file_name is given this option will be disregarded in favour of the parameterfile definitions.",
610
+ )
611
+
612
+
613
+ class CACStrandPostprocPlotInstPower(BaseModel):
614
+ """
615
+ Level 3: Class with settings for generating plots of instantaneous power
616
+ """
617
+ show: bool = Field(default=False, description="Creates a plot for the calculated instantaneous AC loss (W/m) as a function of time (s).")
618
+ title: str = Field(default="Instantaneous Power", description="Title for the plot.")
619
+ save: bool = Field(default=False, description="Set True to save the plot.")
620
+ save_file_name: str = Field(
621
+ default="instantaneous_power", description="Name of the plot file."
622
+ )
623
+
624
+
625
+ class CACStrandPostprocCleanup(BaseModel):
626
+ """
627
+ Level 3: Class for cleanup settings
628
+ """
629
+ remove_pre_file: bool = Field(
630
+ default=False,
631
+ description="Set True to remove the .pre-file after post-processing, to save disk space.",
632
+ )
633
+ remove_res_file: bool = Field(
634
+ default=False,
635
+ description="Set True to remove the .res-file after post-processing, to save disk space.",
636
+ )
637
+ remove_msh_file: bool = Field(
638
+ default=False,
639
+ description="Set True to remove the .msh-file after post-processing, to save disk space.",
640
+ )
641
+
642
+ class CACStrandPostprocPosFiles(BaseModel):
643
+ """
644
+ Level 3: Class for cleanup settings
645
+ """
646
+ quantities: Optional[List[str]] = Field(
647
+ default=None, description="List of GetDP postprocessing quantity to write to .pos file. Examples of valid entry is: phi, h, b, b_reaction, j, jz, jc, power_filaments, power_matrix, sigma_matrix, j_plane, v_plane, hsVal"
648
+ )
649
+ regions: Optional[List[str]] = Field(
650
+ default=None, description="List of GetDP region to to write to .pos file postprocessing for. Examples of valid entry is: Matrix, Filaments, Omega (full domain), OmegaC (conducting domain), OmegaCC (non conducting domain)"
651
+ )
652
+
653
+ @field_validator("quantities", 'regions', mode="before")
654
+ @classmethod
655
+ def convert_none_to_empty_list(cls, v):
656
+ pass
657
+ if v is None:
658
+ 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.
659
+ return v
660
+
661
+ model_config = {
662
+ "validate_default": True
663
+ }
664
+
665
+ class CACStrandPostproc(BaseModel):
666
+ """
667
+ Level 2: Class for FiQuS ConductorAC
668
+ """
669
+ pos_files: CACStrandPostprocPosFiles = Field(
670
+ default=CACStrandPostprocPosFiles(),
671
+ description="Entries controlling output of .pos files. If None or empty lists are given, no .pos files are written. Note that not all combinations of quantities and regions make sense.",
672
+ )
673
+ compute_current_per_filament: bool = Field(
674
+ default=False,
675
+ description="Computes current in every filament, with decomposition into magnetization and transport current.",
676
+ )
677
+ output_folder: Optional[str] = Field(
678
+ default='Results',
679
+ description="Batch post-processing creates a folder with the given name in the output directory, where all the plots are saved.",
680
+ )
681
+ generate_report: Optional[bool] = Field(
682
+ default=False,
683
+ description="Generates a PDF report including all postprocessing graphs. File is saved in the output_folder."
684
+ )
685
+ cleanup: CACStrandPostprocCleanup = CACStrandPostprocCleanup()
686
+ plot_flux: CACStrandPostprocPlotFlux = CACStrandPostprocPlotFlux()
687
+ plot_instantaneous_power: CACStrandPostprocPlotInstPower = CACStrandPostprocPlotInstPower()
688
+ batch_postproc: CACStrandPostprocBatchpostproc = CACStrandPostprocBatchpostproc()
689
+
690
+ # ============= BASE ============= #
691
+ class CACStrand(BaseModel):
692
+ """
693
+ Level 1: Class for FiQuS ConductorAC
694
+ """
695
+
696
+ type: Literal["CACStrand"]
697
+ geometry: CACStrandGeometry = CACStrandGeometry()
698
+ mesh: CACStrandMesh = CACStrandMesh()
699
+ solve: CACStrandSolve = CACStrandSolve()
700
+ postproc: CACStrandPostproc = CACStrandPostproc()
701
+