diff --git a/_unittest/test_28_Maxwell3D.py b/_unittest/test_28_Maxwell3D.py index 692ecacb832..eda5cca58b5 100644 --- a/_unittest/test_28_Maxwell3D.py +++ b/_unittest/test_28_Maxwell3D.py @@ -21,6 +21,9 @@ def setup_class(self): # set a scratch directory and the environment / test data with Scratch(scratch_path) as self.local_scratch: self.aedtapp = Maxwell3d(solution_type="EddyCurrent") + core_loss_file = "PlanarTransformer.aedt" + example_project = os.path.join(local_path, "example_models", core_loss_file) + self.file_path = self.local_scratch.copyfile(example_project) def teardown_class(self): self.aedtapp._desktop.ClearMessages("", "", 3) @@ -225,18 +228,13 @@ def test_30_assign_movement(self): assert bound.props["Velocity"] == "1m_per_sec" def test_31_core_losses(self): - core_loss_file = "PlanarTransformer.aedt" - example_project = os.path.join(local_path, "example_models", core_loss_file) - file_path = self.local_scratch.copyfile(example_project) - m3d1 = Maxwell3d(file_path) + + m3d1 = Maxwell3d(self.file_path) assert m3d1.set_core_losses(["PQ_Core_Bottom", "PQ_Core_Top"]) assert m3d1.set_core_losses(["PQ_Core_Bottom"], False) - self.aedtapp.close_project(m3d1.project_name) + self.aedtapp.close_project(m3d1.project_name, False) def test_32_matrix(self): - core_loss_file = "PlanarTransformer.aedt" - example_project = os.path.join(local_path, "example_models", core_loss_file) - file_path = self.local_scratch.copyfile(example_project) - m3d1 = Maxwell3d(file_path) + m3d1 = Maxwell3d(self.file_path) assert m3d1.assign_matrix("pri", "mymatrix") == "mymatrix" self.aedtapp.close_project(m3d1.project_name, False) diff --git a/doc/source/API/ClientServer.rst b/doc/source/API/ClientServer.rst index 36539ebae2c..636acbd1904 100644 --- a/doc/source/API/ClientServer.rst +++ b/doc/source/API/ClientServer.rst @@ -149,6 +149,6 @@ To bypass current IronPython limits, you can launch PyAEDT on a Linux machine: faces = client.convert_remote_object(box1.faces) -.. image:: Resources/IronPython2Cpython.png +.. image:: /Resources/IronPython2Cpython.png :width: 800 :alt: Electronics Desktop Launched \ No newline at end of file diff --git a/doc/source/Resources/Installation.rst b/doc/source/Resources/Installation.rst index 754e2f80fa2..6d92cb81576 100644 --- a/doc/source/Resources/Installation.rst +++ b/doc/source/Resources/Installation.rst @@ -39,3 +39,25 @@ To use standalone IronPython, run this ``install`` command: .. code:: python ipy64 -X:Frames -m pip install pyaedt + + +Installing Pyaedt from Bat File +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Ansys Electronics Desktop already includes a CPython 3.7 that could be used to run pyaedt. +User can download the following batch file and run in local machine. +The batch file works on Windows and executes the following steps: +1. Create a python virtual environment in your %APPDATA% folder. To do that it uses CPython in your latest version of AEDT installed in your machine. +2. Install Pyaedt. +3. Install Spyder. +4. Install Jupyter Lab. +5. Create a symbolic link from pyaedt installation to Ansys PersonalLib. In this way scripts can be run also within AEDT. +6. Update pyaedt +7. Run the tool you choose (Spyder, Jupyter or simple console). + +Steps from 1 to 5 are executed only first time. Step 6 is executed only running the command with +the following option: + pyaedt_with_IDE.bat -update + +With this approach users can have a complete IDE to write Pyaedt Scripts in Windows with a simple batch file. + +:download:`PyAEDT Environment with IDE ` diff --git a/doc/source/Resources/User_Guide.rst b/doc/source/Resources/User_Guide.rst index 97673b6f018..99c7aecec86 100644 --- a/doc/source/Resources/User_Guide.rst +++ b/doc/source/Resources/User_Guide.rst @@ -283,4 +283,36 @@ As an alternative, the user can upload the script to run to the server and run i remote_script ="path/to/my/remote/pyaedt/script.py" upload(local_script, remote_script, "servername") ansysem = "/path/to/AnsysEMxxx/Linux64" - my_client.root.run_script(remote_script, ansysem_path=ansysem) \ No newline at end of file + my_client.root.run_script(remote_script, ansysem_path=ansysem) + + +CPython on Linux with Client-Server +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To bypass current IronPython limits, you can launch PyAEDT on a Linux machine: + +1. Using pip, install PyAEDT 0.4.23 or later on a Linux machine. +2. Launche CPython and run PyAEDT. + +.. code:: python + + # Launch the latest installed version of PyAEDT in non-graphical mode. + + from pyaedt.common_rpc import launch_ironpython_server + client = launch_ironpython_server(ansysem_path="/path/to/ansys/executable/folder", non_graphical=True, port=18000) + hfss = client.root.hfss() + # put your code here + +3. If the method returns a list or dictionary, use the following method to work around an + issue with CPython handling: + +.. code:: python + + box1 = hfss.modeler.create_box([0,0,0],[1,1,1]) + # convert_remote_object method convert remote ironpython list to local cpython. + faces = client.convert_remote_object(box1.faces) + + +.. image:: ./IronPython2Cpython.png + :width: 800 + :alt: Electronics Desktop Launched \ No newline at end of file diff --git a/doc/source/Resources/pyaedt_with_IDE.bat b/doc/source/Resources/pyaedt_with_IDE.bat new file mode 100644 index 00000000000..cf3a1e7815f --- /dev/null +++ b/doc/source/Resources/pyaedt_with_IDE.bat @@ -0,0 +1,51 @@ +@echo off +if "%ANSYSEM_ROOT221%" =="" ( + if "%ANSYSEM_ROOT212%" =="" ( + if "%ANSYSEM_ROOT211%" =="" ( + echo AEDT 21R1 or greater has to be installed + pause + EXIT /B + ) else ( + set aedt_path=%ANSYSEM_ROOT211% + set aedt_var=ANSYSEM_ROOT211 + echo Found AEDT Version 21R1 + ) + ) else ( + set aedt_path=%ANSYSEM_ROOT212% + set aedt_var=ANSYSEM_ROOT212 + echo Found AEDT Version 21R2 + ) +) else ( + set aedt_path=%ANSYSEM_ROOT221% + set aedt_var=ANSYSEM_ROOT221 + echo Found AEDT Version 22R1 +) + +set /p run=Python or Jupyter?(0=Spyder, 1=Jupyter, 2=Console) +setlocal enableDelayedExpansion +cd "%APPDATA%" +if not exist "%APPDATA%\pyaedt_env_ide\" ( + echo Installing Pyaedt + "%aedt_path%\commonfiles\CPython\3_7\winx64\Release\python\python.exe" -m venv "%APPDATA%\pyaedt_env_ide" + "%APPDATA%\pyaedt_env_ide\Scripts\python.exe" -m pip install --upgrade pip + "%APPDATA%\pyaedt_env_ide\Scripts\pip" install pyaedt + "%APPDATA%\pyaedt_env_ide\Scripts\pip" install jupyterlab + "%APPDATA%\pyaedt_env_ide\Scripts\pip" install spyder + "%APPDATA%\pyaedt_env_ide\Scripts\pip" install ipython -U + call "%APPDATA%\pyaedt_env_ide\Scripts\python" "%APPDATA%\pyaedt_env_ide\Lib\site-packages\pyaedt\misc\aedtlib_personalib_install.py" %aedt_var% +) +if [%1%]==[-update] ( + echo Updating Pyaedt + "%APPDATA%\pyaedt_env_ide\Scripts\pip" install pyaedt -U +) +if %run%==1 ( + echo Launching Jupyter Lab + "%APPDATA%\pyaedt_env_ide\Scripts\jupyter.exe" lab +) else ( if %run%==0 ( + echo Launching Spyder + "%APPDATA%\pyaedt_env_ide\Scripts\spyder.exe" + ) else ( + "%APPDATA%\pyaedt_env_ide\Scripts\ipython.exe" + ) +) + diff --git a/examples/02-HFSS/Flex_CPWG.py b/examples/02-HFSS/Flex_CPWG.py index af76aedac23..93a7bc1d170 100644 --- a/examples/02-HFSS/Flex_CPWG.py +++ b/examples/02-HFSS/Flex_CPWG.py @@ -1,6 +1,6 @@ """ Flex Coplanar Waveguide Example ---------------------/---------- +------------------------------- This example shows how you can use PyAEDT to create a flex cable coplanar waveguide. """ diff --git a/pyaedt/application/Analysis.py b/pyaedt/application/Analysis.py index dcf5def9e63..9293d512b7d 100644 --- a/pyaedt/application/Analysis.py +++ b/pyaedt/application/Analysis.py @@ -1119,6 +1119,15 @@ def create_setup(self, setupname="MySetupAuto", setuptype=None, props={}): setuptype = self.design_solutions.default_setup name = self.generate_unique_setup_name(setupname) setup = Setup(self, setuptype, name) + if self.design_type == "HFSS" and not self.get_excitations_name() and "MaxDeltaS" in setup.props: + new_dict = OrderedDict() + for k, v in setup.props.items(): + if k == "MaxDeltaS": + new_dict["MaxDeltaE"] = 0.01 + else: + new_dict[k] = v + + setup.props = new_dict setup.create() if props: for el in props: diff --git a/pyaedt/application/Design.py b/pyaedt/application/Design.py index 431e0b295e0..3968d3014ae 100644 --- a/pyaedt/application/Design.py +++ b/pyaedt/application/Design.py @@ -35,29 +35,12 @@ from pyaedt.generic.DataHandlers import variation_string_to_dict from pyaedt.modules.Boundary import BoundaryObject from pyaedt.generic.general_methods import generate_unique_name - +from pyaedt.application.design_solutions import model_names, solutions_defaults if sys.version_info.major > 2: import base64 -model_names = { - "Maxwell 2D": "Maxwell2DModel", - "Maxwell 3D": "Maxwell3DModel", - "Twin Builder": "SimplorerCircuit", - "Circuit Design": "NexximCircuit", - "2D Extractor": "2DExtractorModel", - "Q3D Extractor": "Q3DModel", - "HFSS": "HFSSModel", - "Mechanical": "MechanicalModel", - "Icepak": "IcepakModel", - "RMxprtSolution": "RMxprtDesign", - "ModelCreation": "RMxprtDesign", - "HFSS 3D Layout Design": "PlanarEMCircuit", - "EMIT Design": "EMIT Design", -} - - def list_difference(list1, list2): return list(set(list1) - set(list2)) @@ -898,10 +881,7 @@ def default_solution_type(self): Default for the solution type. """ - if self.design_solutions._solution_options[self.design_solutions.solution_types[0]]["name"]: - return self.design_solutions._solution_options[self.design_solutions.solution_types[0]]["name"] - else: - return self.design_solutions.solution_types[0] + return solutions_defaults[self._design_type] @property def odesign(self): @@ -2563,7 +2543,12 @@ def _insert_design(self, design_type, design_name=None, solution_type=None): "RMxprt", unique_design_name, "Model Creation Inner-Rotor Induction Machine", "" ) else: - new_design = self._oproject.InsertDesign(design_type, unique_design_name, self.default_solution_type, "") + if design_type == "HFSS" and self._aedt_version < "2021.2": + new_design = self._oproject.InsertDesign(design_type, unique_design_name, "DrivenModal", "") + else: + new_design = self._oproject.InsertDesign( + design_type, unique_design_name, self.default_solution_type, "" + ) logging.getLogger().info("Added design '%s' of type %s.", unique_design_name, design_type) name = new_design.GetName() if ";" in name: diff --git a/pyaedt/application/design_solutions.py b/pyaedt/application/design_solutions.py index 664bf933b0b..d65b004bb80 100644 --- a/pyaedt/application/design_solutions.py +++ b/pyaedt/application/design_solutions.py @@ -8,7 +8,7 @@ "Circuit Design": "NexximLNA", "2D Extractor": "Open", "Q3D Extractor": "Q3D Extractor", - "HFSS": "Modal", + "HFSS": "HFSS Modal Network", "Icepak": "SteadyState", "RMxprtSolution": "GRM", "ModelCreation": "GRM", @@ -258,14 +258,14 @@ }, "HFSS": { "Modal": { - "name": "DrivenModal", + "name": "HFSS Modal Network", "options": None, "report_type": "Modal Solution Data", "default_setup": 1, "default_adaptive": "LastAdaptive", }, "Terminal": { - "name": "DrivenTerminal", + "name": "HFSS Hybrid Terminal Network", "options": None, "report_type": "Terminal Solution Data", "default_setup": 1, @@ -285,15 +285,22 @@ "default_setup": 1, "default_adaptive": "LastAdaptive", }, - "Transient": { + "Transient Network": { "name": "Transient Network", "options": None, "report_type": "Terminal Solution Data", "default_setup": 3, "default_adaptive": "Transient", }, + "Transient": { + "name": "Transient", + "options": None, + "report_type": "Terminal Solution Data", + "default_setup": 3, + "default_adaptive": "Transient", + }, "Eigenmode": { - "name": None, + "name": "Eigenmode", "options": None, "report_type": "EigenMode Parameters", "default_setup": 2, @@ -466,10 +473,6 @@ def solution_type(self): if self._odesign: try: self._solution_type = self._odesign.GetSolutionType() - if "Modal" in self._solution_type: - self._solution_type = "Modal" - elif "Terminal" in self._solution_type: - self._solution_type = "Terminal" except: self._solution_type = solutions_defaults[self._design_type] elif self._solution_type is None: @@ -483,10 +486,6 @@ def solution_type(self, value): if self._odesign: try: self._solution_type = self._odesign.GetSolutionType() - if "Modal" in self._solution_type: - self._solution_type = "Modal" - elif "Terminal" in self._solution_type: - self._solution_type = "Terminal" except: self._solution_type = solutions_defaults[self._design_type] else: @@ -535,10 +534,79 @@ def __init__(self, odesign, design_type, aedt_version): self._composite = None self._hybrid = None + @property + def solution_type(self): + """Get/Set the Solution Type of the active Design.""" + if self._odesign: + try: + self._solution_type = self._odesign.GetSolutionType() + if "Modal" in self._solution_type: + self._solution_type = "Modal" + elif "Terminal" in self._solution_type: + self._solution_type = "Terminal" + except: + self._solution_type = solutions_defaults[self._design_type] + elif self._solution_type is None: + self._solution_type = solutions_defaults[self._design_type] + return self._solution_type + + @solution_type.setter + @aedt_exception_handler + def solution_type(self, value): + if self._aedt_version < "2021.2": + if not value: + self._solution_type = "DrivenModal" + self._odesign.SetSolutionType(self._solution_type) + elif "Modal" in value: + self._solution_type = "DrivenModal" + self._odesign.SetSolutionType(self._solution_type) + elif "Terminal" in value: + self._solution_type = "DrivenTerminal" + self._odesign.SetSolutionType(self._solution_type) + else: + try: + self._odesign.SetSolutionType(self._solution_options[value]["name"]) + except: + self._odesign.SetSolutionType(self._solution_options[value]["name"], "") + elif value is None: + if self._odesign: + try: + self._solution_type = self._odesign.GetSolutionType() + if "Modal" in self._solution_type: + self._solution_type = "Modal" + elif "Terminal" in self._solution_type: + self._solution_type = "Terminal" + except: + self._solution_type = solutions_defaults[self._design_type] + else: + self._solution_type = solutions_defaults[self._design_type] + elif value and value in self._solution_options and self._solution_options[value]["name"]: + if value == "Transient": + value = "Transient Network" + self._solution_type = "Transient Network" + elif value == "DrivenModal": + value = "Modal" + self._solution_type = "Modal" + elif value == "DrivenTerminal": + value = "Terminal" + self._solution_type = "Terminal" + else: + self._solution_type = value + if self._solution_options[value]["options"]: + self._odesign.SetSolutionType( + self._solution_options[value]["name"], self._solution_options[value]["options"] + ) + else: + try: + self._odesign.SetSolutionType(self._solution_options[value]["name"]) + except: + self._odesign.SetSolutionType(self._solution_options[value]["name"], "") + @property def hybrid(self): """Get/Set Hfss hybrid mode for the active solution.""" - + if self._aedt_version < "2021.2": + return False if self._hybrid is None and self.solution_type is not None: self._hybrid = "Hybrid" in self._solution_options[self.solution_type]["name"] return self._hybrid @@ -546,6 +614,8 @@ def hybrid(self): @hybrid.setter @aedt_exception_handler def hybrid(self, value): + if self._aedt_version < "2021.2": + return if value and "Hybrid" not in self._solution_options[self.solution_type]["name"]: self._solution_options[self.solution_type]["name"] = self._solution_options[self.solution_type][ "name" @@ -560,6 +630,8 @@ def hybrid(self, value): @property def composite(self): """Get/Set Hfss composite mode for the active solution.""" + if self._aedt_version < "2021.2": + return False if self._composite is None and self.solution_type is not None: self._composite = "Composite" in self._solution_options[self.solution_type]["name"] return self._composite @@ -567,6 +639,8 @@ def composite(self): @composite.setter @aedt_exception_handler def composite(self, val): + if self._aedt_version < "2021.2": + return if val: self._solution_options[self.solution_type]["name"] = self._solution_options[self.solution_type][ "name" @@ -593,6 +667,8 @@ def set_auto_open(self, enable=True, boundary_type="Radiation"): ------- bool """ + if self._aedt_version < "2021.2": + return False options = ["NAME:Options", "EnableAutoOpen:=", enable] if enable: options.append("BoundaryType:=") diff --git a/pyaedt/dlls/EDBLib/EdbLib.dll b/pyaedt/dlls/EDBLib/EdbLib.dll index 4432de5fd79..e91f18c415d 100644 Binary files a/pyaedt/dlls/EDBLib/EdbLib.dll and b/pyaedt/dlls/EDBLib/EdbLib.dll differ diff --git a/pyaedt/edb.py b/pyaedt/edb.py index fb93fd65e0c..f25fded510b 100644 --- a/pyaedt/edb.py +++ b/pyaedt/edb.py @@ -190,10 +190,9 @@ def _clean_variables(self): self._db = None self._edb = None self.builder = None - self.edblib = None + self._edblib = None self.edbutils = None self.simSetup = None - self.layout_methods = None self.simsetupdata = None # time.sleep(2) # gc.collect() @@ -257,7 +256,6 @@ def _init_dlls(self): clr.AddReferenceToFile("Ansys.Ansoft.Edb.dll") clr.AddReferenceToFile("Ansys.Ansoft.EdbBuilderUtils.dll") clr.AddReferenceToFile("EdbLib.dll") - clr.AddReferenceToFile("DataModel.dll") clr.AddReferenceToFileAndPath(os.path.join(self.base_path, "Ansys.Ansoft.SimSetupData.dll")) else: if self.student_version: @@ -268,22 +266,37 @@ def _init_dlls(self): clr.AddReference("Ansys.Ansoft.Edb") clr.AddReference("Ansys.Ansoft.EdbBuilderUtils") clr.AddReference("EdbLib") - clr.AddReference("DataModel") clr.AddReference("Ansys.Ansoft.SimSetupData") os.environ["ECAD_TRANSLATORS_INSTALL_DIR"] = self.base_path oaDirectory = os.path.join(self.base_path, "common", "oa") os.environ["ANSYS_OADIR"] = oaDirectory os.environ["PATH"] = "{};{}".format(os.environ["PATH"], self.base_path) edb = __import__("Ansys.Ansoft.Edb") - self.edb = edb.Ansoft.Edb edbbuilder = __import__("Ansys.Ansoft.EdbBuilderUtils") - self.edblib = __import__("EdbLib") + self._edblib = None self.edbutils = edbbuilder.Ansoft.EdbBuilderUtils self.simSetup = __import__("Ansys.Ansoft.SimSetupData") - self.layout_methods = self.edblib.Layout.LayoutMethods self.simsetupdata = self.simSetup.Ansoft.SimSetupData.Data + @property + def edblib(self): + """EdbLib object containing advanced Edb methods not accessible directly from python.""" + if not self._edblib: + if os.name == "posix": + clr.AddReferenceToFile("EdbLib.dll") + clr.AddReferenceToFile("DataModel.dll") + else: + clr.AddReference("EdbLib") + clr.AddReference("DataModel") + self._edblib = __import__("EdbLib") + dllpath = os.path.join(os.path.abspath(os.path.dirname(__file__)), "dlls", "EDBLib") + try: + self._edblib.Layout.LayoutMethods.LoadDataModel(dllpath, self.edbversion) + except: + pass + return self._edblib + @aedt_exception_handler def open_edb(self, init_dlls=False): """Open EDB. @@ -329,10 +342,6 @@ def open_edb(self, init_dlls=False): if self._db and self._active_cell: dllpath = os.path.join(os.path.abspath(os.path.dirname(__file__)), "dlls", "EDBLib") self.logger.info(dllpath) - try: - self.layout_methods.LoadDataModel(dllpath, self.edbversion) - except: - pass self.builder = EdbBuilder(self.edbutils, self._db, self._active_cell) self._init_objects() self.logger.info("Builder Initialized") @@ -376,10 +385,6 @@ def open_edb_inside_aedt(self, init_dlls=False): self._active_cell = list(self._db.TopCircuitCells)[0] dllpath = os.path.join(os.path.abspath(os.path.dirname(__file__)), "dlls", "EDBLib") if self._db and self._active_cell: - try: - self.layout_methods.LoadDataModel(dllpath, self.edbversion) - except: - pass if not os.path.exists(self.edbpath): os.makedirs(self.edbpath) time.sleep(3) @@ -424,10 +429,6 @@ def create_edb(self, init_dlls=False): self._active_cell = self.edb.Cell.Cell.Create(self._db, self.edb.Cell.CellType.CircuitCell, self.cellname) dllpath = os.path.join(os.path.dirname(__file__), "dlls", "EDBLib") if self._db and self._active_cell: - try: - self.layout_methods.LoadDataModel(dllpath, self.edbversion) - except: - pass self.builder = EdbBuilder(self.edbutils, self._db, self._active_cell) self._init_objects() return self.builder @@ -521,7 +522,6 @@ def export_to_ipc2581(self, ipc_path=None, units="millimeter"): result = self.edblib.IPC8521.IPCExporter.ExportIPC2581FromLayout( self.active_layout, self.edbversion, ipc_path, units.lower() ) - # result = self.layout_methods.ExportIPC2581FromBuilder(self.builder, ipc_path, units.lower()) end = time.time() - start if result: self.logger.info("Export IPC 2581 completed in %s sec.", end) @@ -973,10 +973,6 @@ def create_cutout( self.edbpath = output_aedb_path self._active_cell = list(self._db.TopCircuitCells)[0] dllpath = os.path.join(os.path.dirname(__file__), "dlls", "EDBLib") - try: - self.layout_methods.LoadDataModel(dllpath, self.edbversion) - except: - pass self.builder = EdbBuilder(self.edbutils, self._db, self._active_cell) self._init_objects() else: diff --git a/pyaedt/generic/filesystem.py b/pyaedt/generic/filesystem.py index 94adde234a8..f3aa7875c9c 100644 --- a/pyaedt/generic/filesystem.py +++ b/pyaedt/generic/filesystem.py @@ -91,7 +91,7 @@ def copyfile(self, src_file, dst_filename=None): dst_file = os.path.join(self.path, dst_filename) else: dst_file = os.path.join(self.path, os.path.basename(src_file)) - shutil.copyfile(src_file, dst_file) + shutil.copy2(src_file, dst_file) return dst_file def copyfolder(self, src_folder, destfolder): diff --git a/pyaedt/misc/aedtlib_personalib_install.py b/pyaedt/misc/aedtlib_personalib_install.py index 2aaca2e82b2..1eda077df13 100644 --- a/pyaedt/misc/aedtlib_personalib_install.py +++ b/pyaedt/misc/aedtlib_personalib_install.py @@ -23,7 +23,7 @@ "..", ) -d = Desktop("2021.2", True) +d = Desktop(version, True) desktop = sys.modules["__main__"].oDesktop pers1 = os.path.join(desktop.GetPersonalLibDirectory(), "pyaedt") diff --git a/pyaedt/modeler/Object3d.py b/pyaedt/modeler/Object3d.py index 448de733d98..8b5e3037b9d 100644 --- a/pyaedt/modeler/Object3d.py +++ b/pyaedt/modeler/Object3d.py @@ -746,6 +746,29 @@ def bounding_box(self): >>> oEditor.GetModelBoundingBox """ + if self._primitives._app._aedt_version >= "2021.2": + model_obj = self._primitives._app.post.export_model_obj( + obj_list=[self.name], export_path=None, export_as_single_objects=True, air_objects=True + ) + if model_obj: + x = [] + y = [] + z = [] + with open(model_obj[0][0], "r") as f: + lines = f.read().splitlines() + for line in lines: + l = line.split(" ") + if l[0] and l[0] == "v" and len(l) > 3: + x.append(float(l[1])) + y.append(float(l[2])) + z.append(float(l[3])) + bounds = [min(x), min(y), min(z), max(x), max(y), max(z)] + if os.path.exists(model_obj[0][0]): + try: + os.remove(model_obj[0][0]) + except: + pass + return bounds objs_to_unmodel = [ val.name for i, val in self._primitives.objects.items() if val.model and val.name != self.name ] diff --git a/pyaedt/modules/Material.py b/pyaedt/modules/Material.py index 7bab0d54a14..5ab85ab8333 100644 --- a/pyaedt/modules/Material.py +++ b/pyaedt/modules/Material.py @@ -762,7 +762,7 @@ def __init__(self, materials, name, props=None): self.name = name self.coordinate_system = "" if props: - self._props = props + self._props = props.copy() else: self._props = OrderedDict() if "CoordinateSystemType" in self._props: @@ -891,7 +891,7 @@ def __init__(self, materiallib, name, props=None): else: self.physics_type = ["Electromagnetic", "Thermal", "Structural"] self._props["PhysicsTypes"] = OrderedDict({"set": ["Electromagnetic", "Thermal", "Structural"]}) - if "AttachedData" in self._props: + if "AttachedData" in self._props and "MatAppearanceData" in self._props["AttachedData"]: self._material_appearance = [] self._material_appearance.append(self._props["AttachedData"]["MatAppearanceData"]["Red"]) self._material_appearance.append(self._props["AttachedData"]["MatAppearanceData"]["Green"]) diff --git a/pyaedt/modules/PostProcessor.py b/pyaedt/modules/PostProcessor.py index 95721909038..51f62b95dc5 100644 --- a/pyaedt/modules/PostProcessor.py +++ b/pyaedt/modules/PostProcessor.py @@ -2726,7 +2726,7 @@ def export_model_obj(self, obj_list=None, export_path=None, export_as_single_obj else: fname = os.path.join(export_path, "Model_AllObjs_AllMats.obj") self._app.modeler.oeditor.ExportModelMeshToFile(fname, obj_list) - return [fname, "grey", 0.6] + return [[fname, "grey", 0.6]] @aedt_exception_handler def export_mesh_obj(self, setup_name=None, intrinsic_dict={}): diff --git a/pyaedt/modules/SetupTemplates.py b/pyaedt/modules/SetupTemplates.py index 8e2e60ff484..79ee9e95751 100644 --- a/pyaedt/modules/SetupTemplates.py +++ b/pyaedt/modules/SetupTemplates.py @@ -12,7 +12,7 @@ transientelectrostatic = [("SaveField", True), ("Stop", "100s"), ("InitialStep", "0.01s"), ("MaxStep", "5s")] transienthfss = [ ("TimeProfile", "Broadband Pulse"), - ("HfssFrequency", "1GHz"), + ("HfssFrequency", "5GHz"), ("MinFreq", "100MHz"), ("MaxFreq", "1GHz"), ("NumFreqsExtracted", 401),