fiqus 2025.2.0__py3-none-any.whl → 2025.11.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 +24 -28
  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.11.0.dist-info}/METADATA +65 -63
  44. fiqus-2025.11.0.dist-info/RECORD +86 -0
  45. {fiqus-2025.2.0.dist-info → fiqus-2025.11.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.11.0.dist-info}/LICENSE.txt +0 -0
  54. {fiqus-2025.2.0.dist-info → fiqus-2025.11.0.dist-info}/top_level.txt +0 -0
@@ -1,133 +1,141 @@
1
- import os
2
-
3
- from fiqus.geom_generators.GeometryConductorAC_Strand import Geometry
4
- from fiqus.mesh_generators.MeshConductorAC_Strand import Mesh, StrandMesh
5
- from fiqus.getdp_runners.RunGetdpConductorAC_Strand import Solve
6
- from fiqus.post_processors.PostProcessConductorAC import PostProcess
7
- from fiqus.plotters.PlotPythonConductorAC import PlotPython
8
-
9
- class MainConductorAC_Strand:
10
- def __init__(self, fdm, inputs_folder_path='', outputs_folder_path='', verbose=True):
11
- """
12
- Main class for working with simulations for the Conductor AC model.
13
- :param fdm: FiQuS data model
14
- :param inputs_folder_path: full path to folder with input files
15
- :param verbose: if True, more info is printed in the console
16
- """
17
- self.verbose = verbose
18
- self.fdm = fdm
19
- self.inputs_folder_path = inputs_folder_path
20
- self.outputs_folder_path = outputs_folder_path
21
- self.GetDP_path = None
22
- self.geom_folder = None
23
- self.mesh_folder = None
24
- self.solution_folder = None
25
- self.model_file = None
26
- self.model_folder = None
27
-
28
-
29
- def generate_geometry(self, gui=False):
30
- """
31
- Generates the strand geometry.
32
- """
33
- os.chdir(self.geom_folder)
34
- g = Geometry(fdm=self.fdm, inputs_folder_path=self.inputs_folder_path, verbose=self.verbose)
35
- g.generate_strand_geometry(gui)
36
-
37
-
38
- def load_geometry(self, gui: bool = False):
39
- """
40
- Loads the previously generated geometry from the .brep file.
41
- """
42
- os.chdir(self.geom_folder)
43
- g = Geometry(fdm=self.fdm, inputs_folder_path=self.inputs_folder_path, verbose=self.verbose)
44
- g.load_conductor_geometry(gui)
45
- # self.model_file = g.model_file
46
-
47
- def pre_process(self, gui=False):
48
- pass
49
-
50
- def mesh(self, gui: bool = False):
51
- """
52
- Generates the mesh for the strand geometry.
53
- """
54
- os.chdir(self.mesh_folder)
55
-
56
- m = StrandMesh(fdm=self.fdm, verbose=self.verbose)
57
- m.generate_mesh(self.geom_folder)
58
- m.generate_cuts()
59
- m.generate_regions_file()
60
- m.save_mesh(gui)
61
-
62
- return {"test": 0}
63
-
64
- def load_mesh(self, gui=False):
65
- """
66
- Loads the previously generated mesh from the MSH file.
67
- """
68
- os.chdir(self.mesh_folder)
69
- m = Mesh(fdm=self.fdm, verbose=self.verbose)
70
- m.load_mesh(gui)
71
-
72
- # self.model_file = m.mesh_file
73
-
74
- def solve_and_postprocess_getdp(self, gui: bool = False):
75
- """
76
- Assembles the .pro-file from the template, then runs the simulation and the post-processing steps using GetDP.
77
- """
78
- os.chdir(self.solution_folder)
79
-
80
- s = Solve(self.fdm, self.GetDP_path, self.geom_folder, self.mesh_folder, self.verbose)
81
- s.read_excitation(inputs_folder_path=self.inputs_folder_path)
82
- s.get_solution_parameters_from_yaml(inputs_folder_path=self.inputs_folder_path)
83
- s.assemble_pro()
84
- s.run_getdp(solve = True, postOperation = True, gui = gui)
85
- s.cleanup()
86
-
87
- # def pre_process(self):
88
- # os.chdir(self.solution_folder)
89
-
90
- # s = Solve(self.fdm, self.GetDP_path, self.mesh_folder, self.verbose)
91
-
92
- def post_process_getdp(self, gui: bool = False):
93
- """
94
- Runs the post-processing steps trough GetDP.
95
- """
96
- os.chdir(self.solution_folder)
97
-
98
- s = Solve(self.fdm, self.GetDP_path, self.geom_folder, self.mesh_folder, self.verbose)
99
- s.read_excitation(inputs_folder_path=self.inputs_folder_path)
100
- s.assemble_pro()
101
- s.run_getdp(solve = False, postOperation = True, gui = gui)
102
- #
103
- def post_process_python(self, gui: bool = False):
104
- # os.chdir(self.solution_folder)
105
- postProc = PostProcess(self.fdm, self.outputs_folder_path)
106
- postProc.plot_instantaneous_loss()
107
-
108
- return {'test': 0}
109
-
110
- def batch_post_process_python(self, gui: bool = False):
111
- """
112
- Runs batch post-processing steps using Python.
113
- Used for gathering, analysing, comparing and plotting data from multiple simulations.
114
- """
115
- plotter = PlotPython(self.fdm, csv_filename=self.fdm.magnet.postproc.batch_postproc.postProc_csv, lossMap_gridData_folder=None, inputs_folder_path=self.inputs_folder_path, outputs_folder_path=self.outputs_folder_path)
116
-
117
- if self.fdm.magnet.postproc.batch_postproc.loss_map.produce_loss_map:
118
- # plotter.save_lossMap_gridData()
119
- # plotter.save_magnetization()
120
- plotter.create_lossMap()
121
-
122
- if self.fdm.magnet.postproc.batch_postproc.loss_map.cross_section.plot_cross_section:
123
- plotter.plot_lossMap_crossSection()
124
-
125
- if self.fdm.magnet.postproc.batch_postproc.loss_map.cross_section_sweep.animate_cross_section_sweep:
126
- plotter.animate_lossMap_crossSection()
127
-
128
- if self.fdm.magnet.postproc.batch_postproc.plot2d.produce_plot2d:
129
- plotter.plot2d()
130
-
131
-
132
- # def plot_python(self):
133
- # pass
1
+ import os, cProfile
2
+
3
+ from fiqus.geom_generators.GeometryConductorAC_Strand import Geometry
4
+ from fiqus.mesh_generators.MeshConductorAC_Strand import Mesh, StrandMesh
5
+ from fiqus.getdp_runners.RunGetdpConductorAC_Strand import Solve
6
+ from fiqus.post_processors.PostProcessConductorAC import PostProcess, BatchPostProcess
7
+
8
+
9
+ class MainConductorAC_Strand:
10
+ def __init__(self, fdm, inputs_folder_path='', outputs_folder_path='', verbose=True):
11
+ """
12
+ Main class for working with simulations for the Conductor AC model.
13
+ :param fdm: FiQuS data model
14
+ :param inputs_folder_path: full path to folder with input files
15
+ :param verbose: if True, more info is printed in the console
16
+ """
17
+ self.verbose = verbose
18
+ self.fdm = fdm
19
+ self.inputs_folder_path = inputs_folder_path
20
+ self.outputs_folder_path = outputs_folder_path
21
+ self.GetDP_path = None
22
+ self.geom_folder = None
23
+ self.mesh_folder = None
24
+ self.solution_folder = None
25
+ self.model_file = None
26
+ self.model_folder = None
27
+
28
+ def generate_geometry(self, gui=False):
29
+ """
30
+ Generates the strand geometry.
31
+ """
32
+ os.chdir(self.geom_folder)
33
+ g = Geometry(fdm=self.fdm, inputs_folder_path=self.inputs_folder_path, verbose=self.verbose)
34
+ g.generate_strand_geometry(gui)
35
+
36
+ def load_geometry(self, gui: bool = False):
37
+ """
38
+ Loads the previously generated geometry from the .brep file.
39
+ """
40
+ os.chdir(self.geom_folder)
41
+ g = Geometry(fdm=self.fdm, inputs_folder_path=self.inputs_folder_path, verbose=self.verbose)
42
+ g.load_conductor_geometry(gui)
43
+ # self.model_file = g.model_file
44
+
45
+ def pre_process(self, gui=False):
46
+ pass
47
+
48
+ def mesh(self, gui: bool = False):
49
+ """
50
+ Generates the mesh for the strand geometry.
51
+ """
52
+ os.chdir(self.mesh_folder)
53
+
54
+ m = StrandMesh(fdm=self.fdm, verbose=self.verbose)
55
+ m.generate_mesh(self.geom_folder)
56
+ m.generate_cuts()
57
+ m.generate_regions_file()
58
+ m.save_mesh(gui)
59
+
60
+ return {"test": 0}
61
+
62
+ def load_mesh(self, gui=False):
63
+ """
64
+ Loads the previously generated mesh from the MSH file.
65
+ """
66
+ os.chdir(self.mesh_folder)
67
+ m = Mesh(fdm=self.fdm, verbose=self.verbose)
68
+ m.load_mesh(gui)
69
+
70
+ # self.model_file = m.mesh_file
71
+
72
+ def solve_and_postprocess_getdp(self, gui: bool = False):
73
+ """
74
+ Assembles the .pro-file from the template, then runs the simulation and the post-processing steps using GetDP.
75
+ """
76
+ os.chdir(self.solution_folder)
77
+
78
+ s = Solve(self.fdm, self.GetDP_path, self.geom_folder, self.mesh_folder, self.verbose)
79
+ s.read_excitation(inputs_folder_path=self.inputs_folder_path)
80
+ s.get_solution_parameters_from_yaml(inputs_folder_path=self.inputs_folder_path)
81
+ s.assemble_pro()
82
+ s.run_getdp(solve=True, postOperation=True, gui=gui)
83
+ s.cleanup()
84
+
85
+ # def pre_process(self):
86
+ # os.chdir(self.solution_folder)
87
+
88
+ # s = Solve(self.fdm, self.GetDP_path, self.mesh_folder, self.verbose)
89
+
90
+ def post_process_getdp(self, gui: bool = False):
91
+ """
92
+ Runs the post-processing steps trough GetDP.
93
+ """
94
+ os.chdir(self.solution_folder)
95
+
96
+ s = Solve(self.fdm, self.GetDP_path, self.geom_folder, self.mesh_folder, self.verbose)
97
+ s.read_excitation(inputs_folder_path=self.inputs_folder_path)
98
+ s.get_solution_parameters_from_yaml(inputs_folder_path=self.inputs_folder_path)
99
+ s.assemble_pro()
100
+ s.run_getdp(solve=False, postOperation=True, gui=gui)
101
+
102
+ #
103
+ def post_process_python(self, gui: bool = False):
104
+ # os.chdir(self.solution_folder)
105
+ postProc = PostProcess(self.fdm, self.outputs_folder_path)
106
+
107
+ if self.fdm.magnet.postproc.plot_instantaneous_power:
108
+ postProc.instantaneous_loss()
109
+
110
+ if self.fdm.magnet.postproc.plot_flux.show:
111
+ postProc.internal_flux()
112
+
113
+ postProc.plotter.show()
114
+
115
+ return {'test': 0}
116
+
117
+ def batch_post_process_python(self, gui: bool = False):
118
+ """
119
+ Runs batch post-processing steps using Python.
120
+ Used for gathering, analysing, comparing and plotting data from multiple simulations.
121
+ """
122
+ BatchPostProc = BatchPostProcess(self.fdm, lossMap_gridData_folder=None, inputs_folder_path=self.inputs_folder_path, outputs_folder_path=self.outputs_folder_path)
123
+
124
+ if self.fdm.magnet.postproc.batch_postproc.loss_map.produce_loss_map:
125
+ # plotter.save_lossMap_gridData()
126
+ # plotter.save_magnetization()
127
+ BatchPostProc.plotter.create_lossMap()
128
+
129
+ if self.fdm.magnet.postproc.batch_postproc.loss_map.cross_section.plot_cross_section:
130
+ BatchPostProc.plotter.plot_lossMap_crossSection()
131
+
132
+ if self.fdm.magnet.postproc.batch_postproc.loss_map.cross_section_sweep.animate_cross_section_sweep:
133
+ BatchPostProc.plotter.animate_lossMap_crossSection()
134
+
135
+ if self.fdm.magnet.postproc.batch_postproc.plot2d.produce_plot2d:
136
+ BatchPostProc.plotter.plot2d()
137
+
138
+ if self.fdm.magnet.postproc.batch_postproc.rohf_on_grid.fit_rohf or self.fdm.magnet.postproc.batch_postproc.rohf_on_grid.produce_error_map:
139
+ BatchPostProc.rohf_on_grid()
140
+
141
+
@@ -5,6 +5,7 @@ import time
5
5
  from fiqus.utils.Utils import GmshUtils
6
6
  from fiqus.utils.Utils import FilesAndFolders as Util
7
7
  from fiqus.data import DataFiQuS as dF
8
+ from fiqus.data.DataRoxieParser import FiQuSGeometry
8
9
  from fiqus.geom_generators.GeometryMultipole import Geometry
9
10
  from fiqus.mesh_generators.MeshMultipole import Mesh
10
11
  from fiqus.getdp_runners.RunGetdpMultipole import RunGetdpMultipole
@@ -35,7 +36,7 @@ class MainMultipole:
35
36
  fdm.magnet.geometry.electromagnetics.symmetry = 'x'
36
37
  return fdm
37
38
  def generate_geometry(self, gui: bool = False):
38
- geom = Util.read_data_from_yaml(self.rgd, dF.FiQuSGeometry)
39
+ geom = Util.read_data_from_yaml(self.rgd, FiQuSGeometry)
39
40
  fdm = self.force_symmetry() if 'solenoid' in geom.Roxie_Data.coil.coils[1].type else self.fdm # todo: this should be handled by pydantic
40
41
  if self.fdm.magnet.geometry.plot_preview:
41
42
  plotter = PlotPythonMultipole(geom, self.fdm)
@@ -91,7 +92,7 @@ class MainMultipole:
91
92
 
92
93
  def mesh(self, gui: bool = False):
93
94
  mm = Mesh(data=self.fdm, mesh_folder=self.mesh_folder, verbose=self.verbose)
94
- geom = Util.read_data_from_yaml(self.rgd, dF.FiQuSGeometry)
95
+ geom = Util.read_data_from_yaml(self.rgd, FiQuSGeometry)
95
96
  fdm = self.force_symmetry() if 'solenoid' in geom.Roxie_Data.coil.coils[1].type else self.fdm
96
97
  geometry_settings = {'EM': fdm.magnet.geometry.electromagnetics, 'TH': self.fdm.magnet.geometry.thermal}
97
98
  mesh_settings = {'EM': fdm.magnet.mesh.electromagnetics, 'TH': fdm.magnet.mesh.thermal}
@@ -108,7 +109,7 @@ class MainMultipole:
108
109
  mm.defineMesh(geometry_settings[physics_solved], mesh_settings[physics_solved], physics_solved)
109
110
  mm.createPhysicalGroups(geometry_settings[physics_solved])
110
111
  mm.updateAuxiliaryFile(physics_solved)
111
- if geometry_settings[physics_solved].dict().get('use_TSA', False):
112
+ if geometry_settings[physics_solved].model_dump().get('use_TSA', False):
112
113
  mm.rearrangeThinShellsData()
113
114
  mm.assignRegionsTags(geometry_settings[physics_solved], mesh_settings[physics_solved])
114
115
  mm.saveRegionFile(physics_solved)
@@ -116,7 +117,7 @@ class MainMultipole:
116
117
  mm.generateMesh()
117
118
  mm.checkMeshQuality()
118
119
  mm.saveMeshFile(physics_solved)
119
- if geometry_settings[physics_solved].dict().get('use_TSA', False):
120
+ if geometry_settings[physics_solved].model_dump().get('use_TSA', False):
120
121
  mm.saveClosestNeighboursList()
121
122
  if self.fdm.magnet.mesh.thermal.isothermal_conductors: mm.selectMeshNodes(elements='conductors')
122
123
  if self.fdm.magnet.geometry.thermal.with_wedges and self.fdm.magnet.mesh.thermal.isothermal_wedges: mm.selectMeshNodes(elements='wedges')
@@ -169,7 +170,7 @@ class MainMultipole:
169
170
  pp.loadStrandPositions(run_type)
170
171
  pp.loadAuxiliaryFile(run_type)
171
172
  if pp_settings[run_type].plot_all != 'False': pp.loadHalfTurnCornerPositions()
172
- if pp_settings[run_type].dict().get('take_average_conductor_temperature', False): pp.loadRegionFile()
173
+ if pp_settings[run_type].model_dump().get('take_average_conductor_temperature', False): pp.loadRegionFile()
173
174
  pp.postProcess(pp_settings[run_type])
174
175
  if run_type == 'EM' and self.fdm.magnet.geometry.electromagnetics.symmetry != 'none': pp.completeMap2d()
175
176
  pp.clear()
@@ -111,7 +111,6 @@ from fiqus.mesh_generators.MeshPancake3D import Mesh
111
111
  from fiqus.getdp_runners.RunGetdpPancake3D import Solve
112
112
  from fiqus.post_processors.PostProcessPancake3D import Postprocess
113
113
  from fiqus.data.DataFiQuS import FDM
114
- from fiqus.data.DataFiQuS import PowerSupply
115
114
 
116
115
 
117
116
  class MainPancake3D:
@@ -409,13 +408,13 @@ class MainPancake3D:
409
408
  0.1 + estimated_time_constant * 8 + 0.001
410
409
  )
411
410
  new_solve_object_for_inductance_and_time_constant["winding"] = (
412
- copy_fdm.magnet.solve.winding.dict()
411
+ copy_fdm.magnet.solve.winding.model_dump()
413
412
  )
414
413
  new_solve_object_for_inductance_and_time_constant["contactLayer"] = (
415
- copy_fdm.magnet.solve.contactLayer.dict()
414
+ copy_fdm.magnet.solve.contactLayer.model_dump()
416
415
  )
417
416
  new_solve_object_for_inductance_and_time_constant["terminals"] = (
418
- copy_fdm.magnet.solve.terminals.dict()
417
+ copy_fdm.magnet.solve.terminals.model_dump()
419
418
  )
420
419
  solve_object = Pancake3DSolve(
421
420
  **new_solve_object_for_inductance_and_time_constant