Coverage for fiqus/getdp_runners/RunGetdpConductorAC_CC.py: 76%
85 statements
« prev ^ index » next coverage.py v7.4.4, created at 2026-01-09 01:49 +0000
« prev ^ index » next coverage.py v7.4.4, created at 2026-01-09 01:49 +0000
1import timeit
2import logging
3from enum import Enum
4import os
5import subprocess
6import re
7import pandas as pd
9import gmsh
10import numpy as np
12#from fiqus.data import RegionsModelFiQuS
13from fiqus.utils.Utils import GmshUtils, FilesAndFolders
14from fiqus.data.RegionsModelFiQuS import RegionsModel
15# import fiqus.data.DataConductorACGeom as geom
17from fiqus.pro_assemblers.ProAssembler import ASS_PRO
19logger = logging.getLogger('FiQuS')
21class 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")
34 self.verbose = verbose
35 self.gu = GmshUtils(self.solution_folder, self.verbose)
36 self.gu.initialize(verbosity_Gmsh=fdm.run.verbosity_Gmsh)
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
42 self.ed = {} # excitation dictionary
44 gmsh.option.setNumber("General.Terminal", verbose)
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)
50 def read_excitation(self, inputs_folder_path):
51 """
52 Function for reading a CSV file for the 'piecewise' excitation case.
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
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"]
74 logger.info(f"Running GetDP with command: {command}")
75 startTime = timeit.default_timer()
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 = []
82 getdpProcess = subprocess.Popen(mpi_prefix + [self.GetDP_path] + [self.pro_file] + command + ["-msh"] + [self.mesh_file], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
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)
105 simulation_time = timeit.default_timer()-startTime
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()