fiqus 2025.12.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.
- fiqus/MainFiQuS.py +3 -0
- fiqus/data/DataConductor.py +104 -3
- fiqus/data/DataFiQuS.py +2 -1
- fiqus/data/DataFiQuSConductorAC_CC.py +345 -0
- fiqus/data/DataFiQuSConductorAC_Strand.py +3 -3
- fiqus/geom_generators/GeometryConductorAC_CC.py +1906 -0
- fiqus/getdp_runners/RunGetdpConductorAC_CC.py +123 -0
- fiqus/mains/MainConductorAC_CC.py +148 -0
- fiqus/mesh_generators/MeshConductorAC_CC.py +1305 -0
- fiqus/post_processors/PostProcessAC_CC.py +65 -0
- fiqus/pro_templates/combined/CAC_CC_template.pro +542 -0
- {fiqus-2025.12.0.dist-info → fiqus-2026.1.0.dist-info}/METADATA +4 -8
- {fiqus-2025.12.0.dist-info → fiqus-2026.1.0.dist-info}/RECORD +21 -14
- tests/test_geometry_generators.py +20 -0
- tests/test_mesh_generators.py +38 -0
- tests/test_solvers.py +37 -0
- /fiqus/pro_templates/combined/{ConductorACRutherford_template.pro → CAC_Rutherford_template.pro} +0 -0
- /fiqus/pro_templates/combined/{ConductorAC_template.pro → CAC_Strand_template.pro} +0 -0
- {fiqus-2025.12.0.dist-info → fiqus-2026.1.0.dist-info}/LICENSE.txt +0 -0
- {fiqus-2025.12.0.dist-info → fiqus-2026.1.0.dist-info}/WHEEL +0 -0
- {fiqus-2025.12.0.dist-info → fiqus-2026.1.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import timeit
|
|
2
|
+
import logging
|
|
3
|
+
from enum import Enum
|
|
4
|
+
import os
|
|
5
|
+
import subprocess
|
|
6
|
+
import re
|
|
7
|
+
import pandas as pd
|
|
8
|
+
|
|
9
|
+
import gmsh
|
|
10
|
+
import numpy as np
|
|
11
|
+
|
|
12
|
+
#from fiqus.data import RegionsModelFiQuS
|
|
13
|
+
from fiqus.utils.Utils import GmshUtils, FilesAndFolders
|
|
14
|
+
from fiqus.data.RegionsModelFiQuS import RegionsModel
|
|
15
|
+
# import fiqus.data.DataConductorACGeom as geom
|
|
16
|
+
|
|
17
|
+
from fiqus.pro_assemblers.ProAssembler import ASS_PRO
|
|
18
|
+
|
|
19
|
+
logger = logging.getLogger('FiQuS')
|
|
20
|
+
|
|
21
|
+
class Solve:
|
|
22
|
+
def __init__(self, fdm, GetDP_path, geometry_folder, mesh_folder, verbose=True):
|
|
23
|
+
self.fdm = fdm
|
|
24
|
+
self.cacdm = fdm.magnet
|
|
25
|
+
self.GetDP_path = GetDP_path
|
|
26
|
+
self.solution_folder = os.path.join(os.getcwd())
|
|
27
|
+
self.magnet_name = fdm.general.magnet_name
|
|
28
|
+
self.geometry_folder = geometry_folder
|
|
29
|
+
self.mesh_folder = mesh_folder
|
|
30
|
+
self.mesh_file = os.path.join(self.mesh_folder, f"{self.magnet_name}.msh")
|
|
31
|
+
self.pro_file = os.path.join(self.solution_folder, f"{self.magnet_name}.pro")
|
|
32
|
+
self.regions_file = os.path.join(mesh_folder, f"{self.magnet_name}.regions")
|
|
33
|
+
|
|
34
|
+
self.verbose = verbose
|
|
35
|
+
self.gu = GmshUtils(self.solution_folder, self.verbose)
|
|
36
|
+
self.gu.initialize(verbosity_Gmsh=fdm.run.verbosity_Gmsh)
|
|
37
|
+
|
|
38
|
+
self.ass_pro = ASS_PRO(os.path.join(self.solution_folder, self.magnet_name))
|
|
39
|
+
self.regions_model = FilesAndFolders.read_data_from_yaml(self.regions_file, RegionsModel)
|
|
40
|
+
self.material_properties_model = None
|
|
41
|
+
|
|
42
|
+
self.ed = {} # excitation dictionary
|
|
43
|
+
|
|
44
|
+
gmsh.option.setNumber("General.Terminal", verbose)
|
|
45
|
+
|
|
46
|
+
def assemble_pro(self):
|
|
47
|
+
logger.info("Assembling .pro file")
|
|
48
|
+
self.ass_pro.assemble_combined_pro(template = self.cacdm.solve.pro_template, rm = self.regions_model, dm = self.fdm, ed=self.ed, mp=self.material_properties_model)
|
|
49
|
+
|
|
50
|
+
def read_excitation(self, inputs_folder_path):
|
|
51
|
+
"""
|
|
52
|
+
Function for reading a CSV file for the 'piecewise' excitation case.
|
|
53
|
+
|
|
54
|
+
:param inputs_folder_path: The full path to the folder with input files.
|
|
55
|
+
:type inputs_folder_path: str
|
|
56
|
+
"""
|
|
57
|
+
if self.cacdm.solve.source_parameters.source_type == 'piecewise' and self.cacdm.solve.source_parameters.piecewise.source_csv_file:
|
|
58
|
+
input_file = os.path.join(inputs_folder_path, self.cacdm.solve.source_parameters.piecewise.source_csv_file)
|
|
59
|
+
logger.info(f'Using excitation from file: {input_file}')
|
|
60
|
+
df = pd.read_csv(input_file, delimiter=',', engine='python')
|
|
61
|
+
excitation_time = df['time'].to_numpy(dtype='float').tolist()
|
|
62
|
+
self.ed['time'] = excitation_time
|
|
63
|
+
excitation_b = df['b'].to_numpy(dtype='float').tolist()
|
|
64
|
+
self.ed['b'] = excitation_b
|
|
65
|
+
excitation_I = df['I'].to_numpy(dtype='float').tolist()
|
|
66
|
+
self.ed['I'] = excitation_I
|
|
67
|
+
|
|
68
|
+
def run_getdp(self, solve = True, postOperation = True, gui = False):
|
|
69
|
+
command = ["-v2", "-verbose", "3"]
|
|
70
|
+
if solve:
|
|
71
|
+
command += ["-solve", "MagDyn", "-mat_mumps_icntl_14","100"] # icntl for mumps just by precaution
|
|
72
|
+
command += ["-pos", "MagDyn"]
|
|
73
|
+
|
|
74
|
+
logger.info(f"Running GetDP with command: {command}")
|
|
75
|
+
startTime = timeit.default_timer()
|
|
76
|
+
|
|
77
|
+
if self.cacdm.solve.general_parameters.noOfMPITasks:
|
|
78
|
+
mpi_prefix = ["mpiexec", "-np", str(self.cacdm.solve.general_parameters.noOfMPITasks)]
|
|
79
|
+
else:
|
|
80
|
+
mpi_prefix = []
|
|
81
|
+
|
|
82
|
+
getdpProcess = subprocess.Popen(mpi_prefix + [self.GetDP_path] + [self.pro_file] + command + ["-msh"] + [self.mesh_file], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
|
83
|
+
|
|
84
|
+
with getdpProcess.stdout:
|
|
85
|
+
for line in iter(getdpProcess.stdout.readline, b""):
|
|
86
|
+
line = line.decode("utf-8").rstrip()
|
|
87
|
+
line = line.split("\r")[-1]
|
|
88
|
+
if not "Test" in line:
|
|
89
|
+
if line.startswith("Info"):
|
|
90
|
+
parsedLine = re.sub(r"Info\s+:\s+", "", line)
|
|
91
|
+
logger.info(parsedLine)
|
|
92
|
+
elif line.startswith("Warning"):
|
|
93
|
+
parsedLine = re.sub(r"Warning\s+:\s+", "", line)
|
|
94
|
+
logger.warning(parsedLine)
|
|
95
|
+
elif line.startswith("Error"):
|
|
96
|
+
parsedLine = re.sub(r"Error\s+:\s+", "", line)
|
|
97
|
+
logger.error(parsedLine)
|
|
98
|
+
logger.error("Solving CAC failed.")
|
|
99
|
+
# raise Exception(parsedLine)
|
|
100
|
+
elif re.match("##", line):
|
|
101
|
+
logger.critical(line)
|
|
102
|
+
else:
|
|
103
|
+
logger.info(line)
|
|
104
|
+
|
|
105
|
+
simulation_time = timeit.default_timer()-startTime
|
|
106
|
+
|
|
107
|
+
if gui and ((postOperation and not solve) or (solve and postOperation)): # and self.cacdm.postproc.generate_pos_files
|
|
108
|
+
# gmsh.option.setNumber("Geometry.Volumes", 1)
|
|
109
|
+
# gmsh.option.setNumber("Geometry.Surfaces", 1)
|
|
110
|
+
# gmsh.option.setNumber("Geometry.Curves", 1)
|
|
111
|
+
# gmsh.option.setNumber("Geometry.Points", 0)
|
|
112
|
+
posFiles = [
|
|
113
|
+
fileName
|
|
114
|
+
for fileName in os.listdir(self.solution_folder)
|
|
115
|
+
if fileName.endswith(".pos")
|
|
116
|
+
]
|
|
117
|
+
for posFile in posFiles:
|
|
118
|
+
gmsh.open(os.path.join(self.solution_folder, posFile))
|
|
119
|
+
self.gu.launch_interactive_GUI()
|
|
120
|
+
else:
|
|
121
|
+
if gmsh.isInitialized():
|
|
122
|
+
gmsh.clear()
|
|
123
|
+
gmsh.finalize()
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
|
|
2
|
+
"""MainConductorAC_CC.py:"""
|
|
3
|
+
|
|
4
|
+
import os
|
|
5
|
+
import sys
|
|
6
|
+
|
|
7
|
+
from fiqus.geom_generators.GeometryConductorAC_CC import Generate_geometry
|
|
8
|
+
from fiqus.mesh_generators.MeshConductorAC_CC import Mesh
|
|
9
|
+
from fiqus.getdp_runners.RunGetdpConductorAC_CC import Solve
|
|
10
|
+
from fiqus.post_processors.PostProcessAC_CC import Post_Process
|
|
11
|
+
|
|
12
|
+
if len(sys.argv) == 3:
|
|
13
|
+
sys.path.insert(0, os.path.join(os.getcwd(), 'steam-fiqus-dev'))
|
|
14
|
+
from fiqus.data.DataFiQuS import FDM
|
|
15
|
+
|
|
16
|
+
class MainConductorAC_CC:
|
|
17
|
+
def __init__(self, fdm, inputs_folder_path='', verbose=True):
|
|
18
|
+
"""
|
|
19
|
+
Main class for working with simulations for CAC_CC type magnets
|
|
20
|
+
:param fdm: FiQuS data model
|
|
21
|
+
:type fdm: FDM
|
|
22
|
+
:param inputs_folder_path: full path to folder with input files, i.e. conductor and STEP files
|
|
23
|
+
:type inputs_folder_path: str
|
|
24
|
+
:param verbose: if True, more info is printed in the console
|
|
25
|
+
:type verbose: bool
|
|
26
|
+
:return: nothing, only saves files on disk
|
|
27
|
+
:rtype: none
|
|
28
|
+
"""
|
|
29
|
+
self.verbose = verbose
|
|
30
|
+
self.fdm = fdm
|
|
31
|
+
self.inputs_folder_path = inputs_folder_path
|
|
32
|
+
self.GetDP_path = None
|
|
33
|
+
self.geom_folder = None
|
|
34
|
+
self.mesh_folder = None
|
|
35
|
+
self.solution_folder = None
|
|
36
|
+
self.model_file = None
|
|
37
|
+
self.model_folder = None
|
|
38
|
+
|
|
39
|
+
def generate_geometry(self, gui=False):
|
|
40
|
+
"""
|
|
41
|
+
Main method for loading the geometry of CAC_CC models
|
|
42
|
+
:param gui: if true, graphical user interface (gui) of Gmsh is opened at the end
|
|
43
|
+
:type gui: bool
|
|
44
|
+
:return: nothing, only saves files on disk
|
|
45
|
+
:rtype: none
|
|
46
|
+
"""
|
|
47
|
+
os.chdir(self.geom_folder)
|
|
48
|
+
gg = Generate_geometry(fdm=self.fdm, inputs_folder_path=self.inputs_folder_path, verbose=self.verbose)
|
|
49
|
+
gg.generate_HTS_layer()
|
|
50
|
+
gg.generate_silver_top_layer()
|
|
51
|
+
gg.generate_substrate_layer()
|
|
52
|
+
gg.generate_copper_top_layer()
|
|
53
|
+
gg.generate_silver_bottom_layer()
|
|
54
|
+
gg.generate_copper_bottom_layer()
|
|
55
|
+
gg.generate_copper_left_layer()
|
|
56
|
+
gg.generate_copper_right_layer()
|
|
57
|
+
gg.generate_air_region()
|
|
58
|
+
gg.finalize_and_write()
|
|
59
|
+
|
|
60
|
+
def load_geometry(self, gui=False):
|
|
61
|
+
"""
|
|
62
|
+
Main method for loading the geometry of CAC_CC models
|
|
63
|
+
"""
|
|
64
|
+
os.chdir(self.geom_folder)
|
|
65
|
+
gg = Generate_geometry(fdm=self.fdm, inputs_folder_path=self.inputs_folder_path, verbose=self.verbose)
|
|
66
|
+
self.geometry = gg
|
|
67
|
+
gg.load_geometry(gui=gui)
|
|
68
|
+
|
|
69
|
+
def pre_process(self, gui=False):
|
|
70
|
+
"""
|
|
71
|
+
Main method for preprocessing of CAC_CC models
|
|
72
|
+
:param gui: if true, graphical user interface (gui) of Gmsh is opened at the end
|
|
73
|
+
:type gui: bool
|
|
74
|
+
:return: nothing, only saves files on disk
|
|
75
|
+
:rtype: none
|
|
76
|
+
"""
|
|
77
|
+
os.chdir(self.geom_folder)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def mesh(self, gui=False):
|
|
81
|
+
"""
|
|
82
|
+
Main method for building the mesh of CAC_CC models
|
|
83
|
+
:param gui: if true, graphical user interface (gui) of Gmsh is opened at the end
|
|
84
|
+
:type gui: bool
|
|
85
|
+
:return: dictionary with mesh quality stats
|
|
86
|
+
:rtype: dict
|
|
87
|
+
"""
|
|
88
|
+
os.chdir(self.mesh_folder)
|
|
89
|
+
m = Mesh(self.fdm)
|
|
90
|
+
m.generate_mesh(self.geom_folder)
|
|
91
|
+
return {"gamma": 0}
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def load_mesh(self, gui=False):
|
|
95
|
+
"""
|
|
96
|
+
Main method for loading the mesh of CAC_CC models
|
|
97
|
+
:param gui: if true, graphical user interface (gui) of Gmsh is opened at the end
|
|
98
|
+
:type gui: bool
|
|
99
|
+
:return: Nothing, only saves files on disk
|
|
100
|
+
:rtype: none
|
|
101
|
+
"""
|
|
102
|
+
os.chdir(self.mesh_folder)
|
|
103
|
+
|
|
104
|
+
def solve_and_postprocess_getdp(self, gui: bool = False):
|
|
105
|
+
"""
|
|
106
|
+
Assembles the .pro-file from the template, then runs the simulation and the post-processing steps using GetDP.
|
|
107
|
+
"""
|
|
108
|
+
os.chdir(self.solution_folder)
|
|
109
|
+
|
|
110
|
+
s = Solve(self.fdm, self.GetDP_path, self.geom_folder, self.mesh_folder, self.verbose)
|
|
111
|
+
s.read_excitation(inputs_folder_path=self.inputs_folder_path)
|
|
112
|
+
s.assemble_pro()
|
|
113
|
+
s.run_getdp(solve = True, postOperation = True, gui = gui)
|
|
114
|
+
|
|
115
|
+
def post_process_getdp(self, gui: bool = False):
|
|
116
|
+
"""
|
|
117
|
+
Runs the post-processing steps trough GetDP.
|
|
118
|
+
"""
|
|
119
|
+
os.chdir(self.solution_folder)
|
|
120
|
+
|
|
121
|
+
s = Solve(self.fdm, self.GetDP_path, self.geom_folder, self.mesh_folder, self.verbose)
|
|
122
|
+
s.read_excitation(inputs_folder_path=self.inputs_folder_path)
|
|
123
|
+
s.assemble_pro()
|
|
124
|
+
s.run_getdp(solve = False, postOperation = True, gui = gui)
|
|
125
|
+
|
|
126
|
+
def post_process_python(self, gui=False):
|
|
127
|
+
"""
|
|
128
|
+
Main method for postprocessing using python (without solving) of CAC_CC models
|
|
129
|
+
:param gui: if true, graphical user interface (gui) of Gmsh is opened at the end
|
|
130
|
+
:type gui: bool
|
|
131
|
+
:return: Nothing, only saves files on disk
|
|
132
|
+
:rtype: none
|
|
133
|
+
"""
|
|
134
|
+
os.chdir(self.solution_folder)
|
|
135
|
+
p=Post_Process(self.fdm, verbose=self.verbose)
|
|
136
|
+
p.cleanup()
|
|
137
|
+
return {'overall_error': 0}
|
|
138
|
+
|
|
139
|
+
def plot_python(self, gui=False):
|
|
140
|
+
"""
|
|
141
|
+
Main method for making python plots related to CAC_CC models
|
|
142
|
+
:param gui: if true, graphical user interface (gui) of Gmsh is opened at the end
|
|
143
|
+
:type gui: bool
|
|
144
|
+
:return: Nothing, only saves files on disk
|
|
145
|
+
:rtype: none
|
|
146
|
+
"""
|
|
147
|
+
os.chdir(self.solution_folder)
|
|
148
|
+
|