From 40ed676518471a13ebb693f79ea1ad8efd7892bc Mon Sep 17 00:00:00 2001 From: maxcapodi78 Date: Fri, 3 May 2024 11:34:02 +0200 Subject: [PATCH] Added examples to Workflows --- pyaedt/desktop.py | 3 +- pyaedt/generic/general_methods.py | 10 +- pyaedt/modeler/modeler3d.py | 127 +++++++++--------- pyaedt/workflows/hfss3dlayout/export_to_3D.py | 88 ++++++++++++ .../hfss3dlayout/toolkits_catalog.toml | 6 + pyaedt/workflows/project/create_report.py | 39 ++++++ 6 files changed, 201 insertions(+), 72 deletions(-) create mode 100644 pyaedt/workflows/hfss3dlayout/export_to_3D.py create mode 100644 pyaedt/workflows/hfss3dlayout/toolkits_catalog.toml create mode 100644 pyaedt/workflows/project/create_report.py diff --git a/pyaedt/desktop.py b/pyaedt/desktop.py index de7016b62f4..2e5ee69272f 100644 --- a/pyaedt/desktop.py +++ b/pyaedt/desktop.py @@ -1461,7 +1461,8 @@ def _exception(self, ex_value, tb_data): tblist = tb_trace[0].split("\n") self.logger.error(str(ex_value)) for el in tblist: - self.logger.error(el) + if el: + self.logger.error(el) return str(ex_value) diff --git a/pyaedt/generic/general_methods.py b/pyaedt/generic/general_methods.py index 432acb95a12..5dad1863a90 100644 --- a/pyaedt/generic/general_methods.py +++ b/pyaedt/generic/general_methods.py @@ -110,7 +110,6 @@ def _exception(ex_info, func, args, kwargs, message="Type Error"): ] if any(exc in trace for exc in exceptions): continue - # if func.__name__ in trace: for el in trace.split("\n"): _write_mes(el) for trace in tb_trace: @@ -118,14 +117,10 @@ def _exception(ex_info, func, args, kwargs, message="Type Error"): continue tblist = trace.split("\n") for el in tblist: - # if func.__name__ in el: - _write_mes(el) + if el: + _write_mes(el) _write_mes("{} on {}".format(message, func.__name__)) - # try: - # _write_mes(ex_info[1].args[0]) - # except (IndexError, AttributeError): - # pass message_to_print = "" messages = "" @@ -138,7 +133,6 @@ def _exception(ex_info, func, args, kwargs, message="Type Error"): pass if "error" in messages: message_to_print = messages[messages.index("[error]") :] - # _write_mes("{} - {} - {}.".format(ex_info[1], func.__name__, message.upper())) if message_to_print: _write_mes("Last Electronics Desktop Message - " + message_to_print) diff --git a/pyaedt/modeler/modeler3d.py b/pyaedt/modeler/modeler3d.py index 590a94e0420..58d78dbeb05 100644 --- a/pyaedt/modeler/modeler3d.py +++ b/pyaedt/modeler/modeler3d.py @@ -897,7 +897,7 @@ def import_nastran(self, file_path, import_lines=True, lines_thickness=0, import ------- List of :class:`pyaedt.modeler.Object3d.Object3d` """ - nas_to_dict = {"Points": {}, "PointsId": {}, "Triangles": {}, "Lines": {}, "Solids": {}} + nas_to_dict = {"Points": {}, "PointsId": {}, "Triangles": [], "Lines": {}, "Solids": {}} self.logger.reset_timer() self.logger.info("Loading file") @@ -927,22 +927,11 @@ def import_nastran(self, file_path, import_lines=True, lines_thickness=0, import nas_to_dict["PointsId"][grid_id] = grid_id id += 1 else: - if tria_id in nas_to_dict["Triangles"]: - nas_to_dict["Triangles"][tria_id].append( - [ - int(n1), - int(n2), - int(n3), - ] - ) - else: - nas_to_dict["Triangles"][tria_id] = [ - [ - int(n1), - int(n2), - int(n3), - ] - ] + tri = [int(n1), int(n2), int(n3)] + tri.sort() + if tri not in nas_to_dict["Triangles"]: + nas_to_dict["Triangles"].append(tri) + elif line_type in ["GRID*", "CTRIA3*"]: grid_id = int(line[8:24]) if line_type == "CTRIA3*": @@ -955,7 +944,7 @@ def import_nastran(self, file_path, import_lines=True, lines_thickness=0, import n2 = n2[0] + n2[1:].replace("-", "e-") n3 = line[72:88].strip() - if not n3 or n3 == "*": + if not n3 or n3.startswith("*"): lk += 1 n3 = lines[lk][8:24].strip() if "-" in n3[1:]: @@ -965,22 +954,11 @@ def import_nastran(self, file_path, import_lines=True, lines_thickness=0, import nas_to_dict["PointsId"][grid_id] = id id += 1 else: - if tria_id in nas_to_dict["Triangles"]: - nas_to_dict["Triangles"][tria_id].append( - [ - int(n1), - int(n2), - int(n3), - ] - ) - else: - nas_to_dict["Triangles"][tria_id] = [ - [ - int(n1), - int(n2), - int(n3), - ] - ] + tri = [int(n1), int(n2), int(n3)] + tri.sort() + if tri not in nas_to_dict["Triangles"]: + nas_to_dict["Triangles"].append(tri) + elif line_type in ["CPENTA", "CHEXA", "CTETRA"]: obj_id = int(line[16:24]) n1 = int(line[24:32]) @@ -1005,6 +983,30 @@ def import_nastran(self, file_path, import_lines=True, lines_thickness=0, import nas_to_dict["Solids"][obj_id].append(obj_list) else: nas_to_dict["Solids"][obj_id] = [[i for i in obj_list]] + elif line_type in ["CTETRA*"]: + obj_id = int(line[8:24]) + n = [] + + n.append(line[24:40].strip()) + n.append(line[40:56].strip()) + + n.append(line[56:72].strip()) + lk += 1 + n.extend([lines[lk][i : i + 16] for i in range(16, len(lines[lk]), 16)]) + + # if obj_id in nas_to_dict["Solids"]: + # nas_to_dict["Solids"][obj_id].append(obj_list) + # else: + # nas_to_dict["Solids"][obj_id] = [[i for i in obj_list]] + + from itertools import combinations + + for k in list(combinations(n, 3)): + tri = [int(k[0]), int(k[1]), int(k[2])] + tri.sort() + if tri not in nas_to_dict["Triangles"]: + nas_to_dict["Triangles"].append(tri) + elif line_type in ["CROD", "CBEAM"]: obj_id = int(line[16:24]) n1 = int(line[24:32]) @@ -1021,35 +1023,34 @@ def import_nastran(self, file_path, import_lines=True, lines_thickness=0, import self.logger.info("Creating STL file with detected faces") f = open(os.path.join(self._app.working_directory, self._app.design_name + "_test.stl"), "w") f.write("solid PyaedtStl\n") - for triangles in nas_to_dict["Triangles"].values(): - for triangle in triangles: - try: - points = [nas_to_dict["Points"][id] for id in triangle] - except KeyError: - continue - fc = GeometryOperators.get_polygon_centroid(points) - v1 = points[0] - v2 = points[1] - cv1 = GeometryOperators.v_points(fc, v1) - cv2 = GeometryOperators.v_points(fc, v2) - if cv2[0] == cv1[0] == 0.0 and cv2[1] == cv1[1] == 0.0: - n = [0, 0, 1] - elif cv2[0] == cv1[0] == 0.0 and cv2[2] == cv1[2] == 0.0: - n = [0, 1, 0] - elif cv2[1] == cv1[1] == 0.0 and cv2[2] == cv1[2] == 0.0: - n = [1, 0, 0] - else: - n = GeometryOperators.v_cross(cv1, cv2) - - normal = GeometryOperators.normalize_vector(n) - if normal: - f.write(" facet normal {} {} {}\n".format(normal[0], normal[1], normal[2])) - f.write(" outer loop\n") - f.write(" vertex {} {} {}\n".format(points[0][0], points[0][1], points[0][2])) - f.write(" vertex {} {} {}\n".format(points[1][0], points[1][1], points[1][2])) - f.write(" vertex {} {} {}\n".format(points[2][0], points[2][1], points[2][2])) - f.write(" endloop\n") - f.write(" endfacet\n") + for triangle in nas_to_dict["Triangles"]: + try: + points = [nas_to_dict["Points"][id] for id in triangle] + except KeyError: + continue + fc = GeometryOperators.get_polygon_centroid(points) + v1 = points[0] + v2 = points[1] + cv1 = GeometryOperators.v_points(fc, v1) + cv2 = GeometryOperators.v_points(fc, v2) + if cv2[0] == cv1[0] == 0.0 and cv2[1] == cv1[1] == 0.0: + n = [0, 0, 1] + elif cv2[0] == cv1[0] == 0.0 and cv2[2] == cv1[2] == 0.0: + n = [0, 1, 0] + elif cv2[1] == cv1[1] == 0.0 and cv2[2] == cv1[2] == 0.0: + n = [1, 0, 0] + else: + n = GeometryOperators.v_cross(cv1, cv2) + + normal = GeometryOperators.normalize_vector(n) + if normal: + f.write(" facet normal {} {} {}\n".format(normal[0], normal[1], normal[2])) + f.write(" outer loop\n") + f.write(" vertex {} {} {}\n".format(points[0][0], points[0][1], points[0][2])) + f.write(" vertex {} {} {}\n".format(points[1][0], points[1][1], points[1][2])) + f.write(" vertex {} {} {}\n".format(points[2][0], points[2][1], points[2][2])) + f.write(" endloop\n") + f.write(" endfacet\n") f.write("endsolid\n") f.close() diff --git a/pyaedt/workflows/hfss3dlayout/export_to_3D.py b/pyaedt/workflows/hfss3dlayout/export_to_3D.py new file mode 100644 index 00000000000..df1e836f0bd --- /dev/null +++ b/pyaedt/workflows/hfss3dlayout/export_to_3D.py @@ -0,0 +1,88 @@ +import os +from tkinter import Button +from tkinter import Entry +from tkinter import Label +from tkinter import RAISED +from tkinter import StringVar +from tkinter import Tk +from tkinter import mainloop + +from pyaedt import Desktop +from pyaedt import Hfss +from pyaedt import Hfss3dLayout +from pyaedt import Icepak +from pyaedt import Maxwell3d +from pyaedt import Q3d + +master = Tk() +var = StringVar() +label = Label(master, textvariable=var, relief=RAISED) +var.set("1 - Export to HFSS\n2 - Export to Q3D\n3 - Export to Maxwell 3D\n4 - Export to Icepak") +label.pack() +e = Entry(master) +e.pack() + +e.focus_set() +choice = "1" + + +def callback(): + global choice + choice = e.get() # This is the text you may want to use later + master.destroy() + return True + + +b = Button(master, text="OK", width=10, command=callback) +b.pack() + +mainloop() +if choice not in ["1", "2", "3", "4"]: + raise Exception("Wrong input.") +suffixes = {"1": "HFSS", "2": "Q3D", "3": "M3D", "4": "IPK"} + +if "PYAEDT_SCRIPT_PORT" in os.environ and "PYAEDT_SCRIPT_VERSION" in os.environ: + port = os.environ["PYAEDT_SCRIPT_PORT"] + version = os.environ["PYAEDT_SCRIPT_VERSION"] +else: + port = 0 + version = "2024.1" + +with Desktop(new_desktop_session=False, close_on_exit=False, specified_version=version, port=port) as d: + proj = d.active_project() + des = d.active_design() + projname = proj.GetName() + if des.GetDesignType() in ["HFSS 3D Layout Design"]: + desname = des.GetName().split(";")[1] + else: + d.odesktop.AddMessage("", "", 3, "Hfss 3D Layout project is needed.") + d.release_desktop(False, False) + raise Exception("Hfss 3D Layout project is needed.") + h3d = Hfss3dLayout(projectname=projname, designname=desname) + setup = h3d.create_setup() + suffix = suffixes[choice] + + if choice == "2": + setup.export_to_q3d(h3d.project_file[:-5] + f"_{suffix}.aedt", keep_net_name=True) + else: + setup.export_to_hfss(h3d.project_file[:-5] + f"_{suffix}.aedt", keep_net_name=True) + h3d.delete_setup(setup.name) + if choice == "2": + app = Q3d(projectname=h3d.project_file[:-5] + f"_{suffix}.aedt") + else: + app = Hfss(projectname=h3d.project_file[:-5] + f"_{suffix}.aedt") + app2 = None + if choice == "3": + app2 = Maxwell3d(projectname=app.project_name) + elif choice == "4": + app2 = Icepak(projectname=app.project_name) + if app2: + app2.copy_solid_bodies_from( + app, + no_vacuum=False, + no_pec=False, + include_sheets=True, + ) + app2.delete_design(app.design_name) + app2.save_project() + d.logger.info("Project generated correctly.") diff --git a/pyaedt/workflows/hfss3dlayout/toolkits_catalog.toml b/pyaedt/workflows/hfss3dlayout/toolkits_catalog.toml new file mode 100644 index 00000000000..1149935ea8c --- /dev/null +++ b/pyaedt/workflows/hfss3dlayout/toolkits_catalog.toml @@ -0,0 +1,6 @@ +[Export3D] +name = "Export to 3D" +script = "export_to_3D.py" +icon = "images/large/cad3d.png" +template = "Run_PyAEDT_Script" +pip = "" diff --git a/pyaedt/workflows/project/create_report.py b/pyaedt/workflows/project/create_report.py new file mode 100644 index 00000000000..55a0ad348cd --- /dev/null +++ b/pyaedt/workflows/project/create_report.py @@ -0,0 +1,39 @@ +# Generate pdf report +# ~~~~~~~~~~~~~~~~~~~ +# Generate a pdf report with output of simultion. +import os + +from pyaedt import Desktop +from pyaedt import get_pyaedt_app +from pyaedt.generic.pdf import AnsysReport + +if "PYAEDT_SCRIPT_PORT" in os.environ and "PYAEDT_SCRIPT_VERSION" in os.environ: + port = os.environ["PYAEDT_SCRIPT_PORT"] + version = os.environ["PYAEDT_SCRIPT_VERSION"] +else: + port = 0 + version = "2024.1" + +with Desktop(new_desktop_session=False, close_on_exit=False, specified_version=version, port=port) as d: + + proj = d.active_project() + des = d.active_design() + projname = proj.GetName() + desname = des.GetName() + if des.GetDesignType() in ["HFSS 3D Layout Design", "Circuit Design"]: + desname = None + app = get_pyaedt_app(projname, desname) + + report = AnsysReport(version=d.aedt_version_id, design_name=app.design_name, project_name=app.project_name) + report.create() + report.add_section() + report.add_chapter(f"{app.solution_type} Results") + report.add_sub_chapter("Plots") + report.add_text("This section contains all reports results.") + for plot in app.post.plots: + app.post.export_report_to_jpg(app.working_directory, plot.plot_name) + report.add_image(os.path.join(app.working_directory, plot.plot_name + ".jpg"), plot.plot_name) + report.add_page_break() + report.add_toc() + out = report.save_pdf(app.working_directory, "AEDT_Results.pdf") + d.odesktop.AddMessage("", "", 0, f"Report Generated. {out}")