Coverage for fiqus/MainFiQuS.py: 70%

152 statements  

« prev     ^ index     » next       coverage.py v6.4.4, created at 2024-05-20 03:24 +0200

1import os 

2import getpass 

3import time 

4import argparse 

5 

6from fiqus.utils.Utils import initialize_logger 

7from fiqus.utils.Utils import FilesAndFolders as Util 

8from fiqus.utils.Utils import CheckForExceptions as Check 

9from fiqus.data import DataFiQuS as dF 

10from fiqus.mains.MainMultipole import MainMultipole 

11from fiqus.mains.MainCCT import MainCCT 

12from fiqus.mains.MainPancake3D import MainPancake3D 

13 

14 

15class MainFiQuS: 

16 def __init__( 

17 self, 

18 input_file_path: str = None, 

19 model_folder: str = None, 

20 verbose: bool = True, 

21 fdm=None, 

22 GetDP_path=None, 

23 ): 

24 """ 

25 Main class for working with FiQuS simulations 

26 :param input_file_path: input file name 

27 :param verbose: if True, more info is printed in the console 

28 """ 

29 self.time_stamp = time.strftime("%Y-%m-%d-%H-%M-%S") 

30 

31 self.start_folder = os.getcwd() 

32 self.wrk_folder = model_folder 

33 

34 # Intialize logger 

35 self.logger = initialize_logger( 

36 verbose=verbose, time_stamp=self.time_stamp, work_folder=self.wrk_folder 

37 ) 

38 

39 self.verbose = verbose 

40 if self.verbose: 

41 Util.print_welcome_graphics() 

42 

43 # Load yaml input file 

44 if not fdm: 

45 self.fdm = Util.read_data_from_yaml(input_file_path, dF.FDM) 

46 else: 

47 self.fdm = fdm 

48 

49 # Check for input errors 

50 Check.check_inputs(self.fdm.run) 

51 

52 # Initialize Main object 

53 if self.fdm.magnet.type == "CCT_straight": 

54 self.main_magnet = MainCCT(fdm=self.fdm, verbose=verbose) 

55 

56 elif self.fdm.magnet.type == "multipole": 

57 # Load settings 

58 self.sdm = Util.read_data_from_yaml( 

59 f"{input_file_path[:-5]}.set", dF.FiQuSSettings 

60 ) 

61 

62 self.main_magnet = MainMultipole( 

63 fdm=self.fdm, 

64 sdm=self.sdm, 

65 rgd_path=f"{input_file_path[:-5]}.geom", 

66 verbose=verbose, 

67 ) 

68 

69 elif self.fdm.magnet.type == "Pancake3D": 

70 self.main_magnet = MainPancake3D(fdm=self.fdm, verbose=verbose) 

71 else: 

72 raise ValueError( 

73 f"FiQuS does not support magnet type: {self.fdm.magnet.type}!" 

74 ) 

75 

76 # Load user paths for executables and additional files 

77 user_name = getpass.getuser() 

78 if verbose: 

79 print(f"FiQuS is running on machine with user name: {user_name}") 

80 if user_name in ["root", "MP-WIN-02$"]: 

81 user_name = "SYSTEM" 

82 path_to_settings_file = os.path.join( 

83 os.path.dirname(os.path.dirname(__file__)), 

84 "tests", 

85 f"settings.{user_name}.yaml", 

86 ) 

87 if verbose: 

88 print(f"FiQuS is using settings file: {path_to_settings_file}") 

89 if GetDP_path: 

90 self.main_magnet.settings = {"GetDP_path": GetDP_path} 

91 self.main_magnet.GetDP_path = GetDP_path 

92 else: 

93 self.main_magnet.settings = Util.read_data_from_yaml( 

94 path_to_settings_file, dict 

95 ) 

96 self.main_magnet.GetDP_path = self.main_magnet.settings["GetDP_path"] 

97 

98 # Save Model/Geometry/Mesh/Solution folder paths 

99 Util.prep_folder(self.wrk_folder) 

100 self.save_folders() 

101 

102 # Build magnet 

103 self.summary = dict.fromkeys( 

104 [ 

105 "SJ", 

106 "SICN", 

107 "SIGE", 

108 "Gamma", 

109 "nodes", 

110 "solution_time", 

111 "overall_error", 

112 "minimum_diff", 

113 "maximum_diff", 

114 ] 

115 ) 

116 self.build_magnet() 

117 

118 def save_folders(self): 

119 def _check_and_generate_path(folder_type: str = None): 

120 if folder_type == "Geometry": 

121 folder = self.wrk_folder 

122 elif folder_type == "Mesh": 

123 folder = self.main_magnet.geom_folder 

124 elif folder_type == "Solution": 

125 folder = self.main_magnet.mesh_folder 

126 else: 

127 raise Exception("Incompatible type.") 

128 

129 if getattr(self.fdm.run, folder_type.lower()) is None: 

130 # folder_key is not given, so it is computed 

131 folder_key = Util.compute_folder_key( 

132 folder_type=folder_type, 

133 folder=folder, 

134 overwrite=self.fdm.run.overwrite, 

135 ) 

136 else: 

137 # folder_key is given 

138 folder_key = getattr(self.fdm.run, folder_type.lower()) 

139 

140 required_folder = folder_type in required_folders 

141 if self.fdm.run.overwrite and folder_type == ( 

142 required_folders[0] if required_folders else None 

143 ): 

144 Check.check_overwrite_conditions( 

145 folder_type=folder_type, folder=folder, folder_key=folder_key 

146 ) 

147 return Util.get_folder_path( 

148 folder_type=folder_type, 

149 folder=folder, 

150 folder_key=folder_key, 

151 overwrite=self.fdm.run.overwrite, 

152 required_folder=required_folder, 

153 ) 

154 

155 if self.fdm.run.type == "start_from_yaml": 

156 required_folders = ["Geometry", "Mesh", "Solution"] 

157 elif self.fdm.run.type == "geometry_and_mesh": 

158 required_folders = ["Geometry", "Mesh"] 

159 elif self.fdm.run.type == "mesh_and_solve_with_post_process_python": 

160 required_folders = ["Mesh", "Solution"] 

161 elif self.fdm.run.type in ["solve_with_post_process_python", "solve_only"]: 

162 required_folders = ["Solution"] 

163 elif self.fdm.run.type == "geometry_only": 

164 required_folders = ( 

165 [] 

166 if self.fdm.run.geometry and not self.fdm.run.overwrite 

167 else ["Geometry"] 

168 ) 

169 elif self.fdm.run.type == "mesh_only": 

170 required_folders = ( 

171 [] if self.fdm.run.mesh and not self.fdm.run.overwrite else ["Mesh"] 

172 ) 

173 else: # post_process_getdp_only or post_process_python_only or plot_python 

174 required_folders = [] 

175 

176 fdm = self.main_magnet.fdm.magnet 

177 self.main_magnet.geom_folder = _check_and_generate_path(folder_type="Geometry") 

178 if not self.fdm.run.type in ["geometry_only", "plot_python"]: 

179 self.main_magnet.mesh_folder = _check_and_generate_path(folder_type="Mesh") 

180 if not (self.fdm.run.type in ["geometry_only", "mesh_only", "plot_python"]): 

181 self.main_magnet.solution_folder = _check_and_generate_path( 

182 folder_type="Solution" 

183 ) 

184 

185 if self.fdm.run.type in [ 

186 "start_from_yaml", 

187 "geometry_and_mesh", 

188 "geometry_only", 

189 ]: 

190 Util.write_data_to_yaml( 

191 os.path.join(self.main_magnet.geom_folder, "geometry.yaml"), 

192 fdm.geometry.dict(by_alias=True), 

193 ) 

194 if self.fdm.run.type in [ 

195 "start_from_yaml", 

196 "geometry_and_mesh", 

197 "mesh_and_solve_with_post_process_python", 

198 "mesh_only", 

199 ]: 

200 Util.write_data_to_yaml( 

201 os.path.join(self.main_magnet.mesh_folder, "mesh.yaml"), 

202 fdm.mesh.dict(by_alias=True), 

203 ) 

204 if self.fdm.run.type in [ 

205 "start_from_yaml", 

206 "mesh_and_solve_with_post_process_python", 

207 "solve_with_post_process_python", 

208 "solve_only", 

209 "post_process", 

210 ]: 

211 Util.write_data_to_yaml( 

212 os.path.join(self.main_magnet.solution_folder, "solve.yaml"), 

213 fdm.solve.dict(by_alias=True), 

214 ) 

215 if self.fdm.run.type in [ 

216 "start_from_yaml", 

217 "mesh_and_solve_with_post_process_python", 

218 "solve_with_post_process_python", 

219 "post_process_python_only", 

220 "post_process_getdp_only", 

221 "post_process", 

222 ]: 

223 Util.write_data_to_yaml( 

224 os.path.join(self.main_magnet.solution_folder, "postproc.yaml"), 

225 fdm.postproc.dict(by_alias=True), 

226 ) 

227 

228 def build_magnet(self): 

229 if self.fdm.run.type == "start_from_yaml": # needs 3 files (yaml, set, geom) 

230 self.main_magnet.generate_geometry() 

231 self.main_magnet.pre_process() 

232 self.main_magnet.load_geometry() 

233 for key, value in self.main_magnet.mesh().items(): 

234 self.summary[key] = value 

235 self.summary[ 

236 "solution_time" 

237 ] = self.main_magnet.solve_and_postprocess_getdp() 

238 for key, value in self.main_magnet.post_process_python( 

239 gui=self.main_magnet.fdm.run.launch_gui 

240 ).items(): 

241 self.summary[key] = value 

242 elif self.fdm.run.type == "geometry_only": 

243 if len(os.listdir(self.main_magnet.geom_folder)) == 1: 

244 self.main_magnet.generate_geometry() # needs 3 files (yaml, set, geom) 

245 self.main_magnet.pre_process(gui=self.main_magnet.fdm.run.launch_gui) 

246 else: 

247 self.main_magnet.load_geometry( 

248 gui=self.main_magnet.fdm.run.launch_gui 

249 ) # needs 2 files (yaml, brep) 

250 elif self.fdm.run.type == "geometry_and_mesh": 

251 self.main_magnet.generate_geometry() 

252 self.main_magnet.pre_process() 

253 self.main_magnet.load_geometry() 

254 for key, value in self.main_magnet.mesh().items(): 

255 self.summary[key] = value 

256 elif ( 

257 self.fdm.run.type == "mesh_and_solve_with_post_process_python" 

258 ): # needs 5 files (yaml, strs/map2d, set, brep, aux) 

259 self.main_magnet.load_geometry() 

260 for key, value in self.main_magnet.mesh().items(): 

261 self.summary[key] = value 

262 self.summary[ 

263 "solution_time" 

264 ] = self.main_magnet.solve_and_postprocess_getdp() 

265 for key, value in self.main_magnet.post_process_python( 

266 gui=self.main_magnet.fdm.run.launch_gui 

267 ).items(): 

268 self.summary[key] = value 

269 elif self.fdm.run.type == "mesh_only": 

270 if len(os.listdir(self.main_magnet.mesh_folder)) == 1: 

271 self.main_magnet.load_geometry() # needs 3 files (yaml, brep, aux) 

272 for key, value in self.main_magnet.mesh( 

273 gui=self.main_magnet.fdm.run.launch_gui 

274 ).items(): 

275 self.summary[key] = value 

276 else: 

277 self.main_magnet.load_mesh( 

278 gui=self.main_magnet.fdm.run.launch_gui 

279 ) # needs 2 files (yaml, msh) 

280 elif ( 

281 self.fdm.run.type == "solve_with_post_process_python" 

282 ): # needs 5 files (yaml, strs/map2d, set, msh, reg) 

283 self.summary[ 

284 "solution_time" 

285 ] = self.main_magnet.solve_and_postprocess_getdp() 

286 for key, value in self.main_magnet.post_process_python( 

287 gui=self.main_magnet.fdm.run.launch_gui 

288 ).items(): 

289 self.summary[key] = value 

290 elif ( 

291 self.fdm.run.type == "solve_only" 

292 ): # needs 5 files (yaml, strs/map2d, set, msh, reg) 

293 self.summary[ 

294 "solution_time" 

295 ] = self.main_magnet.solve_and_postprocess_getdp( 

296 gui=self.main_magnet.fdm.run.launch_gui 

297 ) 

298 elif self.fdm.run.type == "post_process_getdp_only": 

299 self.main_magnet.post_process_getdp(gui=self.main_magnet.fdm.run.launch_gui) 

300 elif self.fdm.run.type == "post_process_python_only": 

301 for key, value in self.main_magnet.post_process_python( 

302 gui=self.main_magnet.fdm.run.launch_gui 

303 ).items(): 

304 self.summary[key] = value 

305 elif self.fdm.run.type == "post_process": 

306 self.main_magnet.post_process_getdp(gui=self.main_magnet.fdm.run.launch_gui) 

307 for key, value in self.main_magnet.post_process_python( 

308 gui=self.main_magnet.fdm.run.launch_gui 

309 ).items(): 

310 self.summary[key] = value 

311 elif self.fdm.run.type == "plot_python": 

312 self.main_magnet.plot_python() 

313 os.chdir(self.start_folder) 

314 

315 

316if __name__ == "__main__": 

317 parser = argparse.ArgumentParser( 

318 prog="FiQuS", 

319 description="Finite Elements Quench Simulator", 

320 epilog="steam-team@cern.ch", 

321 ) 

322 parser.add_argument( 

323 "--in", 

324 dest="full_path_input", 

325 type=str, 

326 help="Full path to FiQuS input yaml file", 

327 ) 

328 parser.add_argument( 

329 "--out", dest="output_path", type=str, help="Full path to FiQuS output folder" 

330 ) 

331 parser.add_argument( 

332 "--getdp", dest="GetDP_path", type=str, help="Full path to GetDP executable" 

333 ) 

334 args = parser.parse_args() 

335 # print(args.full_path_input) 

336 # print(args.output_path) 

337 # print(args.GetDP_path) 

338 MainFiQuS( 

339 input_file_path=args.full_path_input, 

340 model_folder=args.output_path, 

341 GetDP_path=args.GetDP_path, 

342 ) 

343 print("FiQuS run completed")