diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 66133ced6e0..d36d7ebaad3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,7 +13,7 @@ exclude: | repos: - repo: https://github.com/psf/black - rev: 24.4.0 # IF VERSION CHANGES --> MODIFY "blacken-docs" MANUALLY AS WELL!! + rev: 24.4.2 # IF VERSION CHANGES --> MODIFY "blacken-docs" MANUALLY AS WELL!! hooks: - id: black args: @@ -56,7 +56,7 @@ repos: rev: 1.16.0 hooks: - id: blacken-docs - additional_dependencies: [black==24.4.0] + additional_dependencies: [black==24.4.2] # This validates our pre-commit.ci configuration - repo: https://github.com/pre-commit-ci/pre-commit-ci-config diff --git a/_unittest/test_08_Primitives3D.py b/_unittest/test_08_Primitives3D.py index 753c8ee8684..605d28a632b 100644 --- a/_unittest/test_08_Primitives3D.py +++ b/_unittest/test_08_Primitives3D.py @@ -1764,7 +1764,7 @@ def test_83_cover_face(self): o1 = self.aedtapp.modeler.create_circle(cs_plane=0, position=[0, 0, 0], radius=10) assert self.aedtapp.modeler.cover_faces(o1) - def test_84_replace_3dcomponent(self): + def test_84_replace_3d_component(self): self.aedtapp["test_variable"] = "20mm" box1 = self.aedtapp.modeler.create_box([0, 0, 0], [10, "test_variable", 30]) box2 = self.aedtapp.modeler.create_box([0, 0, 0], ["test_variable", 100, 30]) @@ -1782,7 +1782,8 @@ def test_84_replace_3dcomponent(self): assert len(self.aedtapp.modeler.user_defined_components) == 2 @pytest.mark.skipif(config["desktopVersion"] < "2023.1", reason="Method available in beta from 2023.1") - def test_85_insert_layoutcomponent(self): + @pytest.mark.skipif(is_linux, reason="EDB object is not loaded") + def test_85_insert_layout_component(self): self.aedtapp.insert_design("LayoutComponent") self.aedtapp.solution_type = "Modal" assert not self.aedtapp.modeler.insert_layout_component( diff --git a/_unittest/test_09_Primitives2D.py b/_unittest/test_09_Primitives2D.py index 4cd695c39d1..1f5965accdd 100644 --- a/_unittest/test_09_Primitives2D.py +++ b/_unittest/test_09_Primitives2D.py @@ -74,10 +74,14 @@ def test_06_create_region(self): if self.aedtapp.modeler["Region"]: self.aedtapp.modeler.delete("Region") assert "Region" not in self.aedtapp.modeler.object_names - assert self.aedtapp.modeler.create_region([20, "50", "100mm", 20], False) + assert self.aedtapp.modeler.create_region([20, "50", "100mm", 20], "Absolute Offset") self.aedtapp.modeler["Region"].delete() - region = self.aedtapp.modeler.create_region("100", True) + region = self.aedtapp.modeler.create_region("100", "Percentage Offset") region.delete() + # test backward compatibility + region = self.aedtapp.modeler.create_region(pad_percent=[100, 10, 5, 2], pad_type=True) + region.delete() + # region = self.aedtapp.modeler.create_region([100, 100, 100, 100]) assert region.solve_inside assert region.model diff --git a/_unittest/test_21_Circuit.py b/_unittest/test_21_Circuit.py index fb1b923d90d..2fdce69845e 100644 --- a/_unittest/test_21_Circuit.py +++ b/_unittest/test_21_Circuit.py @@ -50,7 +50,6 @@ def examples(local_scratch): return netlist_file1, netlist_file2, touchstone_file, touchstone_file2 -@pytest.mark.skipif(is_linux, reason="Multiple tests are not passing in Linux with AEDT 2024R1") class TestClass: @pytest.fixture(autouse=True) def init(self, aedtapp, circuitprj, local_scratch, examples): @@ -207,10 +206,9 @@ def test_17_create_setup(self): ] assert LNA_setup.update() - @pytest.mark.skipif(is_linux, reason="To be investigated on linux.") def test_18_export_touchstone(self): assert self.aedtapp.analyze("Dom_LNA") - time.sleep(30) + time.sleep(2) solution_name = "Dom_LNA" sweep_name = None file_name = os.path.join(self.local_scratch.path, "new.s2p") @@ -220,7 +218,7 @@ def test_18_export_touchstone(self): assert self.aedtapp.setup_names[0] == solution_name assert self.aedtapp.export_touchstone(solution_name, sweep_name) - def test_19A_create_sweeps(self): + def test_19a_create_sweeps(self): setup_name = "Sweep_LNA" LNA_setup = self.aedtapp.create_setup(setup_name) LNA_setup.add_sweep_step("Freq", 1, 2, 0.01, "GHz", override_existing_sweep=True) @@ -233,7 +231,7 @@ def test_19A_create_sweeps(self): assert LNA_setup.props["SweepDefinition"][1]["Variable"] == "Temp" assert LNA_setup.props["SweepDefinition"][1]["Data"] == "DEC 20cel 100cel 81" - def test_19B_create_EyE_setups(self): + def test_19b_create_eye_setups(self): setup_name = "Dom_Verify" assert self.aedtapp.create_setup(setup_name, "NexximVerifEye") setup_name = "Dom_Quick" @@ -241,8 +239,13 @@ def test_19B_create_EyE_setups(self): setup_name = "Dom_AMI" assert self.aedtapp.create_setup(setup_name, "NexximAMI") - def test_20_create_AMI_plots(self, add_app): + @pytest.mark.skipif( + is_linux and config["desktopVersion"] == "2024.1", + reason="Project with multiple circuit designs is not working.", + ) + def test_20a_create_ami_plots(self, add_app): ami_design = add_app(ami_project, design_name="Models Init Only", application=Circuit, subfolder=test_subfolder) + report_name = "MyReport" assert ( ami_design.post.create_ami_initial_response_plot( @@ -277,7 +280,7 @@ def test_20_create_AMI_plots(self, add_app): ) @pytest.mark.skipif(config["desktopVersion"] > "2021.2", reason="Skipped on versions higher than 2021.2") - def test_20B_create_AMI_plots(self): + def test_20b_create_ami_plots(self): assert ( self.aedtapp.post.create_statistical_eye_plot( "Dom_Verify", @@ -415,12 +418,20 @@ def test_31_duplicate(self): # pragma: no cover def test_32_push_down(self): self.aedtapp.insert_design("Circuit_Design_Push_Down") subcircuit_1 = self.aedtapp.modeler.schematic.create_subcircuit(location=[0.0, 0.0]) - active_project_name_1 = self.aedtapp.oproject.GetActiveDesign().GetName() + active_project = self.aedtapp.oproject.GetActiveDesign() + if is_linux and config["desktopVersion"] == "2024.1": + time.sleep(1) + self.aedtapp._desktop.CloseAllWindows() + active_project_name_1 = active_project.GetName() self.aedtapp.pop_up() subcircuit_2 = self.aedtapp.modeler.schematic.create_subcircuit( location=[0.0, 0.0], nested_subcircuit_id=subcircuit_1.component_info["RefDes"] ) - active_project_name_3 = self.aedtapp.oproject.GetActiveDesign().GetName() + active_project = self.aedtapp.oproject.GetActiveDesign() + if is_linux and config["desktopVersion"] == "2024.1": + time.sleep(1) + self.aedtapp._desktop.CloseAllWindows() + active_project_name_3 = active_project.GetName() assert active_project_name_1 == active_project_name_3 assert subcircuit_2.component_info["RefDes"] == "U2" assert self.aedtapp.push_down(subcircuit_1) @@ -428,10 +439,18 @@ def test_32_push_down(self): def test_33_pop_up(self): self.aedtapp.insert_design("Circuit_Design_Pop_Up") assert self.aedtapp.pop_up() - active_project_name_1 = self.aedtapp.oproject.GetActiveDesign().GetName() + active_project = self.aedtapp.oproject.GetActiveDesign() + if is_linux and config["desktopVersion"] == "2024.1": + time.sleep(1) + self.aedtapp._desktop.CloseAllWindows() + active_project_name_1 = active_project.GetName() self.aedtapp.modeler.schematic.create_subcircuit(location=[0.0, 0.0]) assert self.aedtapp.pop_up() - active_project_name_2 = self.aedtapp.oproject.GetActiveDesign().GetName() + active_project = self.aedtapp.oproject.GetActiveDesign() + if is_linux and config["desktopVersion"] == "2024.1": + time.sleep(1) + self.aedtapp._desktop.CloseAllWindows() + active_project_name_2 = active_project.GetName() assert active_project_name_1 == active_project_name_2 def test_34_activate_variables(self): @@ -481,14 +500,15 @@ def test_38_browse_log_file(self): self.aedtapp.modeler.components.create_interface_port("net_10", (0.01, 0)) lna = self.aedtapp.create_setup("mylna", self.aedtapp.SETUPS.NexximLNA) lna.props["SweepDefinition"]["Data"] = "LINC 0Hz 1GHz 101" - assert not self.aedtapp.browse_log_file() self.aedtapp.analyze() + time.sleep(2) assert self.aedtapp.browse_log_file() - self.aedtapp.save_project() - assert self.aedtapp.browse_log_file() - assert not self.aedtapp.browse_log_file(os.path.join(self.aedtapp.working_directory, "logfiles")) - assert self.aedtapp.browse_log_file(self.aedtapp.working_directory) + if not is_linux: + self.aedtapp.save_project() + assert self.aedtapp.browse_log_file() + assert not self.aedtapp.browse_log_file(os.path.join(self.aedtapp.working_directory, "logfiles")) + assert self.aedtapp.browse_log_file(self.aedtapp.working_directory) def test_39_export_results_circuit(self): exported_files = self.aedtapp.export_results() @@ -691,9 +711,10 @@ def test_41_assign_excitations(self, add_app): assert "PortTest" in c.excitations c.excitation_objects["PortTest"].delete() assert len(c.excitation_objects) == 0 - self.aedtapp.save_project() - c = add_app(application=Circuit, design_name="sources") - assert c.sources + if not is_linux: + self.aedtapp.save_project() + c = add_app(application=Circuit, design_name="sources") + assert c.sources def test_41_set_variable(self): self.aedtapp.variable_manager.set_variable("var_test", expression="123") @@ -772,6 +793,7 @@ def test_43_create_and_change_prop_text(self): assert self.aedtapp.modeler.create_text("text test", "1000mil", "-2000mil") @pytest.mark.skipif(config["NonGraphical"], reason="Change property doesn't work in non-graphical mode.") + @pytest.mark.skipif(is_linux and config["desktopVersion"] == "2024.1", reason="Schematic has to be closed.") def test_44_change_text_property(self): self.aedtapp.set_active_design("text") text_id = self.aedtapp.oeditor.GetAllGraphics()[0].split("@")[1] @@ -785,6 +807,7 @@ def test_44_change_text_property(self): assert not self.aedtapp.modeler.change_text_property(text_id, "Invalid", {}) @pytest.mark.skipif(config["NonGraphical"], reason="Change property doesn't work in non-graphical mode.") + @pytest.mark.skipif(is_linux and config["desktopVersion"] == "2024.1", reason="Schematic has to be closed.") def test_45_create_circuit_from_multizone_layout(self, add_edb): edb = add_edb(project_name="multi_zone_project") common_reference_net = "gnd" @@ -799,7 +822,6 @@ def test_45_create_circuit_from_multizone_layout(self, add_edb): assert self.aedtapp.remove_all_unused_definitions() def test_46_create_vpwl(self): - # default inputs myres = self.aedtapp.modeler.schematic.create_voltage_pwl(name="V1") assert myres.refdes != "" @@ -834,6 +856,9 @@ def test_47_automatic_lna(self): ) assert status + @pytest.mark.skipif( + config["NonGraphical"] and is_linux, reason="Method is not working in Linux and non-graphical mode." + ) def test_48_automatic_tdr(self): touchstone_file = os.path.join(local_path, "example_models", test_subfolder, touchstone_custom) @@ -850,6 +875,7 @@ def test_48_automatic_tdr(self): ) assert result + @pytest.mark.skipif(config["NonGraphical"] and is_linux, reason="Method not working in Linux and Non graphical.") def test_49_automatic_ami(self): touchstone_file = os.path.join(local_path, "example_models", test_subfolder, touchstone_custom) ami_file = os.path.join(local_path, "example_models", test_subfolder, "pcieg5_32gt.ibs") diff --git a/_unittest/test_22_Circuit_DynamicLink.py b/_unittest/test_22_Circuit_DynamicLink.py index 006542b7cb4..f1864fa6ee0 100644 --- a/_unittest/test_22_Circuit_DynamicLink.py +++ b/_unittest/test_22_Circuit_DynamicLink.py @@ -8,7 +8,7 @@ from pyaedt import Q2d from pyaedt import Q3d from pyaedt import is_ironpython -from pyaedt.generic.general_methods import is_linux +from pyaedt import is_linux test_subfloder = "T22" test_project_name = "Dynamic_Link" @@ -81,10 +81,10 @@ def test_02_add_subcircuits_3dlayout(self): assert hfss3Dlayout_comp.id == 86 assert hfss3Dlayout_comp - @pytest.mark.skipif(is_ironpython or is_linux, reason="Skipped because Desktop is crashing") + @pytest.mark.skipif(is_ironpython, reason="Skipped because Desktop is crashing") + @pytest.mark.skipif(config["NonGraphical"] and is_linux, reason="Method not working in Linux and Non graphical.") def test_03_add_subcircuits_hfss_link(self, add_app): pin_names = self.aedtapp.get_source_pin_names(src_design_name, src_project_name, self.src_project_file, 2) - assert len(pin_names) == 4 assert "usb_P_pcb" in pin_names hfss = add_app(project_name=self.src_project_file, design_name="uUSB", just_open=True) @@ -92,23 +92,27 @@ def test_03_add_subcircuits_hfss_link(self, add_app): assert hfss_comp.id == 87 assert hfss_comp.composed_name == "CompInst@uUSB;87;3" - @pytest.mark.skipif(is_ironpython or is_linux, reason="Skipped because Desktop is crashing") + @pytest.mark.skipif(is_ironpython, reason="Skipped because Desktop is crashing") + @pytest.mark.skipif(config["NonGraphical"] and is_linux, reason="Method not working in Linux and Non graphical") def test_04_refresh_dynamic_link(self): assert self.aedtapp.modeler.schematic.refresh_dynamic_link("uUSB") - @pytest.mark.skipif(is_ironpython or is_linux, reason="Skipped because Desktop is crashing") + @pytest.mark.skipif(is_ironpython, reason="Skipped because Desktop is crashing") + @pytest.mark.skipif(config["NonGraphical"] and is_linux, reason="Method not working in Linux and Non graphical") def test_05_set_sim_option_on_hfss_subcircuit(self): hfss_comp = "CompInst@uUSB;87;3" assert self.aedtapp.modeler.schematic.set_sim_option_on_hfss_subcircuit(hfss_comp) assert self.aedtapp.modeler.schematic.set_sim_option_on_hfss_subcircuit(hfss_comp, option="interpolate") assert not self.aedtapp.modeler.schematic.set_sim_option_on_hfss_subcircuit(hfss_comp, option="not_good") - @pytest.mark.skipif(is_linux or is_ironpython, reason="Skipped because Desktop is crashing") + @pytest.mark.skipif(is_ironpython, reason="Skipped because AEDT is crashing.") + @pytest.mark.skipif(config["NonGraphical"] and is_linux, reason="Method not working in Linux and Non graphical") def test_06_set_sim_solution_on_hfss_subcircuit(self): hfss_comp = "CompInst@uUSB;87;3" assert self.aedtapp.modeler.schematic.set_sim_solution_on_hfss_subcircuit(hfss_comp) - @pytest.mark.skipif(is_ironpython or is_linux, reason="Skipped because Desktop is crashing") + @pytest.mark.skipif(is_ironpython, reason="Skipped because Desktop is crashing") + @pytest.mark.skipif(config["NonGraphical"] and is_linux, reason="Method not working in Linux and Non graphical") def test_07_create_page_port_and_interface_port(self): hfss_comp_id = 87 hfss3Dlayout_comp_id = 86 @@ -180,7 +184,8 @@ def test_07_create_page_port_and_interface_port(self): assert "Port_remove" not in self.aedtapp.excitations - @pytest.mark.skipif(is_ironpython or is_linux, reason="Skipped because Desktop is crashing") + @pytest.mark.skipif(is_ironpython, reason="Skipped because Desktop is crashing") + @pytest.mark.skipif(config["NonGraphical"] and is_linux, reason="Method not working in Linux and Non graphical") def test_08_assign_excitations(self): filepath = os.path.join(local_path, "example_models", test_subfloder, "frequency_dependent_source.fds") ports_list = ["Excitation_1", "Excitation_2"] @@ -205,7 +210,8 @@ def test_09_setup(self): LNA_setup.props["SweepDefinition"]["Data"] = " ".join(sweep_list) assert LNA_setup.update() - @pytest.mark.skipif(is_ironpython or is_linux, reason="Skipped because Desktop is crashing") + @pytest.mark.skipif(is_ironpython, reason="Skipped because Desktop is crashing") + @pytest.mark.skipif(config["NonGraphical"] and is_linux, reason="Method not working in Linux and Non graphical") def test_10_q2d_link(self, add_app): self.aedtapp.insert_design("test_link") q2d = add_app(application=Q2d, project_name=self.q3d, just_open=True) @@ -215,7 +221,8 @@ def test_10_q2d_link(self, add_app): assert c1.parameters["Length"] == "25mm" assert c1.parameters["r1"] == "0.3mm" - @pytest.mark.skipif(is_ironpython or is_linux, reason="Skipped because Desktop is crashing") + @pytest.mark.skipif(is_ironpython, reason="Skipped because Desktop is crashing") + @pytest.mark.skipif(config["NonGraphical"] and is_linux, reason="Method not working in Linux and Non graphical") def test_10_q3d_link(self, add_app): q3d = add_app(application=Q3d, project_name=self.q3d, just_open=True) @@ -225,7 +232,8 @@ def test_10_q3d_link(self, add_app): assert q3d_comp assert len(q3d_comp.pins) == 4 - @pytest.mark.skipif(is_ironpython or is_linux, reason="Skipped because Desktop is crashing") + @pytest.mark.skipif(is_ironpython, reason="Skipped because Desktop is crashing") + @pytest.mark.skipif(config["NonGraphical"] and is_linux, reason="Method not working in Linux and Non graphical") def test_10_hfss_link(self, add_app): hfss = add_app(project_name=self.q3d, just_open=True) @@ -237,7 +245,8 @@ def test_10_hfss_link(self, add_app): hfss2, solution_name="Setup2 : Sweep", tline_port="1" ) - @pytest.mark.skipif(is_ironpython or is_linux, reason="Skipped because Desktop is crashing") + @pytest.mark.skipif(is_ironpython, reason="Skipped because Desktop is crashing") + @pytest.mark.skipif(config["NonGraphical"] and is_linux, reason="Method not working in Linux and Non graphical") def test_11_siwave_link(self): model = os.path.join(local_path, "example_models", test_subfloder, "Galileo_um.siw") model_out = self.local_scratch.copyfile(model) @@ -248,7 +257,7 @@ def test_11_siwave_link(self): assert siw_comp assert len(siw_comp.pins) == 2 - @pytest.mark.skipif(config.get("skip_circuits", False) or is_linux, reason="Skipped because Desktop is crashing") + @pytest.mark.skipif(config.get("skip_circuits", False), reason="Skipped because Desktop is crashing") def test_12_create_interface_port(self): page_port = self.aedtapp.modeler.components.create_page_port(name="Port12", location=[0, -0.50]) interface_port = self.aedtapp.modeler.components.create_interface_port(name="Port12", location=[0.3, -0.50]) diff --git a/_unittest/test_28_Maxwell3D.py b/_unittest/test_28_Maxwell3D.py index 92f87bc5cab..d60dbd56748 100644 --- a/_unittest/test_28_Maxwell3D.py +++ b/_unittest/test_28_Maxwell3D.py @@ -869,7 +869,10 @@ def test_53_assign_layout_force(self, layout_comp): nets_layers = {"1V0": "Bottom Solder"} assert layout_comp.assign_layout_force(nets_layers, "LC1_1") - @pytest.mark.skipif(desktop_version < "2023.2", reason="Method available in beta from 2023.2") + @pytest.mark.skipif( + desktop_version < "2023.2" or is_linux, reason="Method is available in beta in 2023.2 and later." + ) + @pytest.mark.skipif(is_linux, reason="EDB object is not loaded.") def test_54_enable_harmonic_force_layout(self, layout_comp): comp = layout_comp.modeler.user_defined_components["LC1_1"] layers = list(comp.layout_component.layers.keys()) diff --git a/_unittest/test_41_3dlayout_modeler.py b/_unittest/test_41_3dlayout_modeler.py index 0b6add565e9..d2022e9578d 100644 --- a/_unittest/test_41_3dlayout_modeler.py +++ b/_unittest/test_41_3dlayout_modeler.py @@ -492,10 +492,10 @@ def test_18d_delete_setup(self): self.aedtapp.delete_setup(setup_name) assert setuptd.name not in self.aedtapp.existing_analysis_setups - def test_19A_validate(self): + def test_19a_validate(self): assert self.aedtapp.validate_full_design() - def test_19D_export_to_hfss(self): + def test_19d_export_to_hfss(self): self.aedtapp.save_project() filename = "export_to_hfss_test" filename2 = "export_to_hfss_test2" @@ -503,9 +503,11 @@ def test_19D_export_to_hfss(self): file_fullname2 = os.path.join(self.local_scratch.path, filename2) setup = self.aedtapp.get_setup(self.aedtapp.existing_analysis_setups[0]) assert setup.export_to_hfss(output_file=file_fullname) - assert setup.export_to_hfss(output_file=file_fullname2, keep_net_name=True) + if not is_linux: + # TODO: EDB failing in Linux + assert setup.export_to_hfss(output_file=file_fullname2, keep_net_name=True) - def test_19E_export_to_q3d(self): + def test_19e_export_to_q3d(self): filename = "export_to_q3d_test" file_fullname = os.path.join(self.local_scratch.path, filename) setup = self.aedtapp.get_setup(self.aedtapp.existing_analysis_setups[0]) @@ -652,6 +654,7 @@ def test_41_test_create_polygon(self): @pytest.mark.skipif(not config["use_grpc"], reason="Not running in COM mode") @pytest.mark.skipif(config["desktopVersion"] < "2023.2", reason="Working only from 2023 R2") + @pytest.mark.skipif(is_linux, reason="PyEDB is failing in Linux.") def test_42_post_processing(self, add_app): test_post1 = add_app(project_name=test_post, application=Maxwell3d, subfolder=test_subfolder) assert test_post1.post.create_fieldplot_layers( @@ -705,6 +708,7 @@ def test_42_post_processing(self, add_app): self.aedtapp.close_project(test_post2.project_name) @pytest.mark.skipif(config["desktopVersion"] < "2023.2", reason="Working only from 2023 R2") + @pytest.mark.skipif(is_linux, reason="PyEDB failing in Linux") def test_42_post_processing_3d_layout(self, add_app): test = add_app( project_name="test_post_3d_layout_solved_23R2", application=Hfss3dLayout, subfolder=test_subfolder @@ -820,6 +824,7 @@ def test_96_change_nets_visibility(self, add_app): assert not hfss3d.modeler.change_net_visibility(visible="") assert not hfss3d.modeler.change_net_visibility(visible=0) + @pytest.mark.skipif(is_linux, reason="PyEDB failing in Linux") def test_96_2_report_design(self): report = AnsysReport() report.create() diff --git a/_unittest_solvers/test_00_analyze.py b/_unittest_solvers/test_00_analyze.py index 12c8e7476c5..62137d5b2fe 100644 --- a/_unittest_solvers/test_00_analyze.py +++ b/_unittest_solvers/test_00_analyze.py @@ -506,7 +506,6 @@ def test_09b_compute_com(self, local_scratch): ) assert com_0 and com_1 - @pytest.mark.skipif(is_linux, reason="SPISIM in Linux is missing some DLLs") def test_09c_compute_com(self, local_scratch): com_example_file_folder = Path(local_path) / "example_models" / test_subfolder / "com_unit_test_sparam" thru_s4p = local_scratch.copyfile(com_example_file_folder / "SerDes_Demo_02_Thru.s4p") diff --git a/_unittest_solvers/test_26_emit.py b/_unittest_solvers/test_26_emit.py index 91cfc2b9fff..adabbac4cc8 100644 --- a/_unittest_solvers/test_26_emit.py +++ b/_unittest_solvers/test_26_emit.py @@ -7,6 +7,7 @@ import pytest from pyaedt import Emit +from pyaedt import generate_unique_project_name from pyaedt.emit_core.emit_constants import EmiCategoryFilter from pyaedt.emit_core.emit_constants import InterfererType from pyaedt.emit_core.emit_constants import ResultType @@ -373,7 +374,7 @@ def test_07_antenna_component(self, add_app): reason="Skipped on versions earlier than 2023.2", ) def test_08_revision_generation(self, add_app): - self.aedtapp = add_app(application=Emit) + self.aedtapp = add_app(application=Emit, project_name=generate_unique_project_name()) assert len(self.aedtapp.results.revisions) == 0 # place components and generate the appropriate number of revisions rad1 = self.aedtapp.modeler.components.create_component("UE - Handheld") @@ -443,7 +444,7 @@ def test_08_revision_generation(self, add_app): reason="Skipped on versions earlier than 2023.2", ) def test_09_manual_revision_access_test_getters(self, add_app): - self.aedtapp = add_app(application=Emit) + self.aedtapp = add_app(application=Emit, project_name=generate_unique_project_name()) rad1 = self.aedtapp.modeler.components.create_component("UE - Handheld") ant1 = self.aedtapp.modeler.components.create_component("Antenna") rad2 = self.aedtapp.modeler.components.create_component("Bluetooth") @@ -512,7 +513,7 @@ def test_09_manual_revision_access_test_getters(self, add_app): reason="Skipped on versions earlier than 2023.2", ) def test_10_radio_band_getters(self, add_app): - self.aedtapp = add_app(application=Emit) + self.aedtapp = add_app(application=Emit, project_name=generate_unique_project_name()) rad1, ant1 = self.aedtapp.modeler.components.create_radio_antenna("New Radio") rad2, ant2 = self.aedtapp.modeler.components.create_radio_antenna("Bluetooth Low Energy (LE)") rad3, ant3 = self.aedtapp.modeler.components.create_radio_antenna("WiFi - 802.11-2012") @@ -729,7 +730,7 @@ def test_14_version(self, add_app): reason="Skipped on versions earlier than 2023.2", ) def test_15_basic_run(self, add_app): - self.aedtapp = add_app(application=Emit) + self.aedtapp = add_app(application=Emit, project_name=generate_unique_project_name()) assert len(self.aedtapp.results.revisions) == 0 # place components and generate the appropriate number of revisions rad1 = self.aedtapp.modeler.components.create_component("UE - Handheld") @@ -811,7 +812,7 @@ def test_15_basic_run(self, add_app): reason="Skipped on versions earlier than 2024.1", ) def test_16_optimal_n_to_1_feature(self, add_app): - self.aedtapp = add_app(application=Emit) + self.aedtapp = add_app(application=Emit, project_name=generate_unique_project_name()) # place components and generate the appropriate number of revisions rad1 = self.aedtapp.modeler.components.create_component("Bluetooth") ant1 = self.aedtapp.modeler.components.create_component("Antenna") @@ -867,7 +868,7 @@ def test_16_optimal_n_to_1_feature(self, add_app): reason="Skipped on versions earlier than 2023.2", ) def test_17_availability_1_to_1(self, add_app): - self.aedtapp = add_app(application=Emit) + self.aedtapp = add_app(application=Emit, project_name=generate_unique_project_name()) # place components and generate the appropriate number of revisions rad1 = self.aedtapp.modeler.components.create_component("MD400C") ant1 = self.aedtapp.modeler.components.create_component("Antenna") diff --git a/pyaedt/application/AnalysisNexxim.py b/pyaedt/application/AnalysisNexxim.py index 02271d31321..28d416f5b31 100644 --- a/pyaedt/application/AnalysisNexxim.py +++ b/pyaedt/application/AnalysisNexxim.py @@ -122,7 +122,7 @@ def push_down(self, component_name): else: out_name = component_name try: - self.oproject.SetActiveDesign(out_name) + self.desktop_class.active_design(self.oproject, out_name, self.design_type) self.__init__(projectname=self.project_name, designname=out_name) except Exception: # pragma: no cover return False @@ -139,7 +139,7 @@ def pop_up(self): """ try: parent_name = self.odesign.GetName().split(";")[1].split("/")[0] - self.oproject.SetActiveDesign(parent_name) + self.desktop_class.active_design(self.oproject, parent_name, self.design_type) self.__init__(projectname=self.project_name, designname=parent_name) except Exception: return False diff --git a/pyaedt/application/Design.py b/pyaedt/application/Design.py index d342707ea54..ca8c0cd859e 100644 --- a/pyaedt/application/Design.py +++ b/pyaedt/application/Design.py @@ -1019,7 +1019,7 @@ def _find_design(self): if not self._check_design_consistency(): count_consistent_designs = 0 for des in self.design_list: - self._odesign = self._oproject.SetActiveDesign(des) + self._odesign = self.desktop_class.active_design(self.oproject, des, self.design_type) if self._check_design_consistency(): count_consistent_designs += 1 activedes = des @@ -1062,7 +1062,7 @@ def odesign(self, des_name): else: activedes, warning_msg = self._find_design() if activedes: - self._odesign = self.oproject.SetActiveDesign(activedes) + self._odesign = self.desktop_class.active_design(self.oproject, activedes, self.design_type) self.logger.info(warning_msg) self.design_solutions._odesign = self.odesign @@ -1095,7 +1095,7 @@ def oproject(self): @oproject.setter def oproject(self, proj_name=None): if not proj_name: - self._oproject = self.odesktop.GetActiveProject() + self._oproject = self.desktop_class.active_project() if self._oproject: self.logger.info( "No project is defined. Project {} exists and has been read.".format(self._oproject.GetName()) @@ -1103,7 +1103,7 @@ def oproject(self, proj_name=None): else: prj_list = self.odesktop.GetProjectList() if prj_list and proj_name in list(prj_list): - self._oproject = self.odesktop.SetActiveProject(proj_name) + self._oproject = self.desktop_class.active_project(proj_name) self._add_handler() self.logger.info("Project %s set to active.", proj_name) elif os.path.exists(proj_name) or ( @@ -1114,7 +1114,7 @@ def oproject(self, proj_name=None): path = os.path.dirname(proj_name) self.odesktop.RestoreProjectArchive(proj_name, os.path.join(path, name), True, True) time.sleep(0.5) - self._oproject = self.odesktop.GetActiveProject() + self._oproject = self.desktop_class.active_project() self._add_handler() self.logger.info( "Archive {} has been restored to project {}".format(proj_name, self._oproject.GetName()) @@ -1126,7 +1126,7 @@ def oproject(self, proj_name=None): project = proj_name[:-5] + ".aedt" if os.path.exists(project) and self.check_if_project_is_loaded(project): pname = self.check_if_project_is_loaded(project) - self._oproject = self.odesktop.SetActiveProject(pname) + self._oproject = self.desktop_class.active_project(pname) self._add_handler() self.logger.info("Project %s set to active.", pname) elif os.path.exists(project): @@ -1143,7 +1143,7 @@ def oproject(self, proj_name=None): oTool.ImportEDB(proj_name) else: oTool.ImportEDB(os.path.join(proj_name, "edb.def")) - self._oproject = self.odesktop.GetActiveProject() + self._oproject = self.desktop_class.active_project() self._oproject.Save() self._add_handler() self.logger.info( @@ -1151,13 +1151,16 @@ def oproject(self, proj_name=None): ) elif self.check_if_project_is_loaded(proj_name): pname = self.check_if_project_is_loaded(proj_name) - self._oproject = self.odesktop.SetActiveProject(pname) + self._oproject = self.desktop_class.active_project(pname) self._add_handler() self.logger.info("Project %s set to active.", pname) else: if is_project_locked(proj_name): raise RuntimeError("Project is locked. Close or remove the lock before proceeding.") self._oproject = self.odesktop.OpenProject(proj_name) + if not is_windows and settings.aedt_version: + time.sleep(1) + self.odesktop.CloseAllWindows() self._add_handler() self.logger.info("Project %s has been opened.", self._oproject.GetName()) time.sleep(0.5) @@ -1169,7 +1172,7 @@ def oproject(self, proj_name=None): if not self._oproject: new_project_list = [i for i in self.odesktop.GetProjectList() if i not in project_list] if new_project_list: - self._oproject = self.odesktop.SetActiveProject(new_project_list[0]) + self._oproject = self.desktop_class.active_project(new_project_list[0]) if proj_name.endswith(".aedt"): self._oproject.Rename(proj_name, True) elif not proj_name.endswith(".aedtz"): @@ -1182,7 +1185,7 @@ def oproject(self, proj_name=None): if not self._oproject: new_project_list = [i for i in self.odesktop.GetProjectList() if i not in project_list] if new_project_list: - self._oproject = self.odesktop.SetActiveProject(new_project_list[0]) + self._oproject = self.desktop_class.active_project(new_project_list[0]) self._add_handler() self.logger.info("Project %s has been created.", self._oproject.GetName()) @@ -3133,7 +3136,7 @@ def close_project(self, name=None, save_project=True): if self.design_type == "HFSS 3D Layout Design": self._close_edb() self.logger.info("Closing the AEDT Project {}".format(name)) - oproj = self.odesktop.SetActiveProject(name) + oproj = self.desktop_class.active_project(name) proj_path = oproj.GetPath() proj_file = os.path.join(proj_path, name + ".aedt") if save_project: @@ -3148,7 +3151,7 @@ def close_project(self, name=None, save_project=True): self._oproject = None self._odesign = None else: - self.odesktop.SetActiveProject(legacy_name) + self.desktop_class.active_project(legacy_name) AedtObjects.__init__(self, self._desktop_class, is_inherithed=True) i = 0 @@ -3323,10 +3326,14 @@ def _insert_design(self, design_type, design_name=None): new_design = self._oproject.InsertDesign( design_type, unique_design_name, self.default_solution_type, "" ) + if not is_windows and settings.aedt_version and self.design_type == "Circuit Design": + time.sleep(1) + self.odesktop.CloseAllWindows() + if new_design is None: # pragma: no cover - new_design = self.oproject.SetActiveDesign(unique_design_name) + new_design = self.desktop_class.active_design(self.oproject, unique_design_name, self.design_type) if new_design is None: - self.logger.error("Fail to create new design.") + self.logger.error("Failed to create design.") return self.logger.info("Added design '%s' of type %s.", unique_design_name, design_type) name = new_design.GetName() @@ -3452,8 +3459,11 @@ def copy_design_from(self, project_fullname, design_name, save_project=True, set proj_from.CopyDesign(design_name) # paste in the destination project and get the name self._oproject.Paste() - new_designname = self._oproject.GetActiveDesign().GetName() - if self._oproject.GetActiveDesign().GetDesignType() == "HFSS 3D Layout Design": + new_designname = self.desktop_class.active_design(self._oproject, design_type=self.design_type).GetName() + if ( + self.desktop_class.active_design(self._oproject, design_type=self.design_type).GetDesignType() + == "HFSS 3D Layout Design" + ): new_designname = new_designname[2:] # name is returned as '2;EMDesign3' # close the source project self.odesktop.CloseProject(proj_from_name) @@ -3930,7 +3940,7 @@ def design_variation(self, variation_string=None): @pyaedt_function_handler() def _assert_consistent_design_type(self, des_name): if des_name in self.design_list: - self._odesign = self._oproject.SetActiveDesign(des_name) + self._odesign = self.desktop_class.active_design(self.oproject, des_name, self.design_type) dtype = self._odesign.GetDesignType() if dtype != "RMxprt": if dtype != self._design_type: @@ -3940,7 +3950,7 @@ def _assert_consistent_design_type(self, des_name): return True elif ":" in des_name: try: - self._odesign = self._oproject.SetActiveDesign(des_name) + self._odesign = self.desktop_class.active_design(self.oproject, des_name, self.design_type) return True except Exception: return des_name diff --git a/pyaedt/application/aedt_objects.py b/pyaedt/application/aedt_objects.py index ace9bd1e616..81fad1bd4fc 100644 --- a/pyaedt/application/aedt_objects.py +++ b/pyaedt/application/aedt_objects.py @@ -1,6 +1,9 @@ import sys +import time +from pyaedt import is_linux from pyaedt import pyaedt_function_handler +from pyaedt import settings from pyaedt.generic.desktop_sessions import _desktop_sessions @@ -371,6 +374,9 @@ def oeditor(self): if not self._oeditor: if self.design_type in ["Circuit Design", "Twin Builder", "Maxwell Circuit", "EMIT"]: self._oeditor = self.odesign.SetActiveEditor("SchematicEditor") + if is_linux and settings.aedt_version == "2024.1": + time.sleep(1) + self._odesktop.CloseAllWindows() elif self.design_type in ["HFSS 3D Layout Design", "HFSS3DLayout"]: self._oeditor = self.odesign.SetActiveEditor("Layout") elif self.design_type in ["RMxprt", "RMxprtSolution"]: diff --git a/pyaedt/circuit.py b/pyaedt/circuit.py index e8638873c11..82296a387d8 100644 --- a/pyaedt/circuit.py +++ b/pyaedt/circuit.py @@ -8,8 +8,10 @@ import os import re import shutil +import time from pyaedt import Hfss3dLayout +from pyaedt import settings from pyaedt.application.AnalysisNexxim import FieldAnalysisCircuit from pyaedt.application.analysis_hf import ScatteringMethods from pyaedt.generic import ibis_reader @@ -17,6 +19,7 @@ from pyaedt.generic.constants import unit_converter from pyaedt.generic.filesystem import search_files from pyaedt.generic.general_methods import generate_unique_name +from pyaedt.generic.general_methods import is_linux from pyaedt.generic.general_methods import open_file from pyaedt.generic.general_methods import pyaedt_function_handler from pyaedt.modules.Boundary import CurrentSinSource @@ -649,6 +652,9 @@ def get_source_pin_names( self._desktop.OpenProject(source_project_path) oSrcProject = self._desktop.SetActiveProject(source_project_name) oDesign = oSrcProject.SetActiveDesign(source_design_name) + if is_linux and settings.aedt_version == "2024.1": + time.sleep(1) + self._desktop.CloseAllWindows() tmp_oModule = oDesign.GetModule("BoundarySetup") port = None if port_selector == 1: @@ -1609,9 +1615,9 @@ def import_edb_in_circuit(self, input_dir): self.logger.error( "Failed to setup co-simulation settings, make sure the simulation setup is properly defined" ) - active_project = hfss.odesktop.SetActiveProject(hfss.project_name) + active_project = hfss.desktop_class.active_project(hfss.project_name) active_project.CopyDesign(hfss.design_name) - active_project = self.odesktop.SetActiveProject(self.project_name) + active_project = hfss.desktop_class.active_project(self.project_name) active_project.Paste() hfss_3d_layout_model = self.modeler.schematic.add_subcircuit_3dlayout(hfss.design_name) hfss.close_project(save_project=False) diff --git a/pyaedt/desktop.py b/pyaedt/desktop.py index 88dda626451..38feb28ff68 100644 --- a/pyaedt/desktop.py +++ b/pyaedt/desktop.py @@ -697,9 +697,9 @@ def __getitem__(self, project_design_name): else: return None - initial_oproject = self.odesktop.GetActiveProject() + initial_oproject = self.active_project() if initial_oproject.GetName() != projectname: - self.odesktop.SetActiveProject(projectname) + self.active_project(projectname) if isinstance(project_design_name[1], int) and project_design_name[1] < len(self.design_list()): designname = self.design_list()[project_design_name[1]] @@ -710,6 +710,65 @@ def __getitem__(self, project_design_name): return get_pyaedt_app(projectname, designname, self) + @pyaedt_function_handler() + def active_design(self, project_object=None, name=None, design_type=None): + """Get the active design. + + Parameters + ---------- + project_object : optional + AEDT project object. The default is ``None``, in which case the active project is used. + + name : str, optional + Name of the design to make active. + The default is ``None``, in which case the active design is returned. + + design_type : str, optional + Name of the active design to make active. + The default is ``None``, in which case the active design is returned. + + References + ---------- + + >>> oProject.GetActiveDesign + >>> oProject.SetActiveDesign + """ + if not project_object: + project_object = self.active_project() + if not name: + active_design = project_object.GetActiveDesign() + else: + active_design = project_object.SetActiveDesign(name) + if is_linux and settings.aedt_version == "2024.1" and design_type == "Circuit Design": + time.sleep(1) + self.odesktop.CloseAllWindows() + return active_design + + @pyaedt_function_handler() + def active_project(self, name=None): + """Get the active project. + + Parameters + ---------- + name : str, optional + Name of the active project to make active. + The default is ``None``, in which case the active project is returned. + + References + ---------- + + >>> oDesktop.GetActiveProject + >>> oDesktop.SetActiveProject + """ + if not name: + active_project = self.odesktop.GetActiveProject() + else: + active_project = self.odesktop.SetActiveProject(name) + if is_linux and settings.aedt_version == "2024.1": + time.sleep(1) + self.odesktop.CloseAllWindows() + return active_project + @property def install_path(self): """Installation path for AEDT.""" @@ -1142,14 +1201,14 @@ def analyze_all(self, project=None, design=None): ``True`` when successful, ``False`` when failed. """ if not project: - oproject = self.odesktop.GetActiveProject() + oproject = self.active_project() else: - oproject = self.odesktop.SetActiveProject(project) + oproject = self.active_project(project) if oproject: if not design: oproject.AnalyzeAll() else: - odesign = oproject.SetActiveDesign(design) + odesign = self.active_design(oproject, design) if odesign: odesign.AnalyzeAll() return True @@ -1217,21 +1276,21 @@ def copy_design(self, project_name=None, design_name=None, target_project=None): ``True`` when successful, ``False`` when failed. """ if not project_name: # pragma: no cover - oproject = self.odesktop.GetActiveProject() + oproject = self.active_project() else: # pragma: no cover - oproject = self.odesktop.SetActiveProject(project_name) + oproject = self.active_project(project_name) if oproject: # pragma: no cover if not design_name: - odesign = oproject.GetActiveDesign() + odesign = self.active_design(oproject) else: - odesign = oproject.SetActiveDesign(design_name) + odesign = self.active_design(oproject, design_name) if odesign: oproject.CopyDesign(design_name) if not target_project: oproject.Paste() return True else: - oproject_target = self.odesktop.SetActiveProject(target_project) + oproject_target = self.active_project(target_project) if not oproject_target: oproject_target = self.odesktop.NewProject(target_project) oproject_target.Paste() @@ -1255,9 +1314,9 @@ def project_path(self, project_name=None): """ if not project_name: - oproject = self.odesktop.GetActiveProject() + oproject = self.active_project() else: - oproject = self.odesktop.SetActiveProject(project_name) + oproject = self.active_project(project_name) if oproject: return oproject.GetPath() return None @@ -1280,9 +1339,9 @@ def design_list(self, project=None): updateddeslist = [] if not project: - oproject = self.odesktop.GetActiveProject() + oproject = self.active_project() else: - oproject = self.odesktop.SetActiveProject(project) + oproject = self.active_project(project) if oproject: deslist = list(oproject.GetTopDesignList()) for el in deslist: @@ -1309,15 +1368,15 @@ def design_type(self, project_name=None, design_name=None): Design type. """ if not project_name: - oproject = self.odesktop.GetActiveProject() + oproject = self.active_project() else: - oproject = self.odesktop.SetActiveProject(project_name) + oproject = self.active_project(project_name) if not oproject: return "" if not design_name: - odesign = oproject.GetActiveDesign() + odesign = self.active_design(oproject) else: - odesign = oproject.SetActiveDesign(design_name) + odesign = self.active_design(oproject.design_name) if odesign: return odesign.GetDesignType() return "" @@ -1428,11 +1487,11 @@ def load_project(self, project_file, design_name=None): """ if os.path.splitext(os.path.split(project_file)[-1])[0] in self.project_list(): - proj = self.odesktop.SetActiveProject(os.path.splitext(os.path.split(project_file)[-1])[0]) + proj = self.active_project(os.path.splitext(os.path.split(project_file)[-1])[0]) else: proj = self.odesktop.OpenProject(project_file) if proj: - active_design = proj.GetActiveDesign() + active_design = self.active_design(proj) if design_name and design_name in proj.GetChildNames(): # pragma: no cover return self[[proj.GetName(), design_name]] elif active_design: diff --git a/pyaedt/emit.py b/pyaedt/emit.py index 70b37b3fa13..f67e403be6e 100644 --- a/pyaedt/emit.py +++ b/pyaedt/emit.py @@ -3,7 +3,6 @@ import warnings from pyaedt import emit_core -from pyaedt import generate_unique_project_name from pyaedt.application.Design import Design from pyaedt.emit_core.Couplings import CouplingsEmit from pyaedt.emit_core.emit_constants import EMIT_VALID_UNITS @@ -114,8 +113,6 @@ def __init__( port=0, aedt_process_id=None, ): - if projectname is None: - projectname = generate_unique_project_name() self.__emit_api_enabled = False self.results = None """Constructor for the ``FieldAnalysisEmit`` class""" diff --git a/pyaedt/emit_core/results/results.py b/pyaedt/emit_core/results/results.py index 667f45ef31b..5cc9d46b2f2 100644 --- a/pyaedt/emit_core/results/results.py +++ b/pyaedt/emit_core/results/results.py @@ -33,7 +33,7 @@ def __init__(self, emit_obj): self.revisions = [] """List of all result revisions. Only one loaded at a time""" - self.design = emit_obj.odesktop.GetActiveProject().GetActiveDesign() + self.design = emit_obj.desktop_class.active_design(emit_obj.odesktop.GetActiveProject()) """Active design for the EMIT project.""" @pyaedt_function_handler() @@ -214,7 +214,9 @@ def analyze(self): # no changes since last created revision, load it elif ( self.revisions[-1].revision_number - == self.emit_project.odesktop.GetActiveProject().GetActiveDesign().GetRevision() + == self.emit_project.desktop_class.active_design( + self.emit_project.desktop_class.active_project() + ).GetRevision() ): self.get_revision(self.revisions[-1].name) else: diff --git a/pyaedt/generic/compliance.py b/pyaedt/generic/compliance.py index 091488d7a3c..c9ff5a6ffdf 100644 --- a/pyaedt/generic/compliance.py +++ b/pyaedt/generic/compliance.py @@ -221,7 +221,7 @@ def load_project(self): self._desktop_class.logger.error("Project path has not been provided.") return False self._desktop_class.load_project(self._project_file) - project = self._desktop_class.odesktop.GetActiveProject() + project = self._desktop_class.active_project() self._project_name = project.GetName() self._output_folder = os.path.join( project.GetPath(), self._project_name + ".pyaedt", generate_unique_name(self._template_name) diff --git a/pyaedt/generic/configurations.py b/pyaedt/generic/configurations.py index 8a3170a6b60..f6ba8b0381e 100644 --- a/pyaedt/generic/configurations.py +++ b/pyaedt/generic/configurations.py @@ -1673,7 +1673,7 @@ def _export_objects_properties(self, dict_out): def _export_mesh_operations(self, dict_out): dict_out["mesh"] = {} args = ["NAME:Settings"] - args += self._app.mesh.global_mesh_region.settings.parse_settings() + args += self._app.mesh.global_mesh_region.settings.parse_settings_as_args() mop = OrderedDict({}) _arg2dict(args, mop) dict_out["mesh"]["Settings"] = mop["Settings"] @@ -1683,7 +1683,7 @@ def _export_mesh_operations(self, dict_out): args = ["NAME:Settings"] else: args = ["NAME:" + mesh.name, "Enable:=", mesh.Enable] - args += mesh.settings.parse_settings() + args += mesh.settings.parse_settings_as_args() args += getattr(mesh, "_parse_assignment_value")() args += ["UserSpecifiedSettings:=", not mesh.manual_settings] mop = OrderedDict({}) diff --git a/pyaedt/generic/design_types.py b/pyaedt/generic/design_types.py index 8d0b889d94f..cb820a104db 100644 --- a/pyaedt/generic/design_types.py +++ b/pyaedt/generic/design_types.py @@ -1,5 +1,9 @@ import re import sys +import time + +from pyaedt import is_linux +from pyaedt.generic.settings import settings # lazy imports @@ -1791,6 +1795,9 @@ def get_pyaedt_app(project_name=None, design_name=None, desktop=None): oProject = odesktop.GetActiveProject() else: oProject = odesktop.SetActiveProject(project_name) + if is_linux and settings.aedt_version == "2024.1": + time.sleep(1) + odesktop.CloseAllWindows() if not oProject: raise AttributeError("No project is present.") design_names = [] @@ -1804,6 +1811,9 @@ def get_pyaedt_app(project_name=None, design_name=None, desktop=None): oDesign = oProject.GetActiveDesign() else: oDesign = oProject.SetActiveDesign(design_name) + if is_linux and settings.aedt_version == "2024.1": + time.sleep(1) + odesktop.CloseAllWindows() if not oDesign: raise AttributeError("No design is present.") design_type = oDesign.GetDesignType() diff --git a/pyaedt/generic/spisim.py b/pyaedt/generic/spisim.py index 9593205a78f..d2e2f1c1507 100644 --- a/pyaedt/generic/spisim.py +++ b/pyaedt/generic/spisim.py @@ -73,6 +73,8 @@ def _compute_spisim(self, parameter, out_file="", touchstone_file="", config_fil my_env = os.environ.copy() my_env.update(settings.aedt_environment_variables) if is_linux: # pragma: no cover + if "ANSYSEM_ROOT_PATH" not in my_env: + my_env["ANSYSEM_ROOT_PATH"] = self.desktop_install_dir command.append("&") with open_file(out_processing, "w") as outfile: subprocess.Popen(command, env=my_env, stdout=outfile, stderr=outfile).wait() # nosec diff --git a/pyaedt/hfss.py b/pyaedt/hfss.py index fd668db9f00..35e3bc7f001 100644 --- a/pyaedt/hfss.py +++ b/pyaedt/hfss.py @@ -1970,7 +1970,9 @@ def create_source_excitation(self, assignment, point1, point2, name, source_type props = OrderedDict({"Objects": [assignment], "Direction": OrderedDict({"Start": point1, "End": point2})}) return self._create_boundary(name, props, source_type) - @pyaedt_function_handler(face="assignment", nummodes="modes", portname="name", renorm="renormalize") + @pyaedt_function_handler( + face="assignment", nummodes="modes", portname="name", renorm="renormalize", deembed_dist="deembed_distance" + ) def create_floquet_port( self, assignment, diff --git a/pyaedt/hfss3dlayout.py b/pyaedt/hfss3dlayout.py index d0392ceaeed..b852dfb0531 100644 --- a/pyaedt/hfss3dlayout.py +++ b/pyaedt/hfss3dlayout.py @@ -707,8 +707,8 @@ def import_edb(self, input_folder): input_folder = os.path.join(input_folder, "edb.def") self.oimport_export.ImportEDB(input_folder) self._close_edb() - project_name = self.odesktop.GetActiveProject().GetName() - design_name = self.odesktop.GetActiveProject().GetActiveDesign().GetName().split(";")[-1] + project_name = self.desktop_class.active_project().GetName() + design_name = self.desktop_class.active_design(self.desktop_class.active_project()).GetName().split(";")[-1] self.__init__(projectname=project_name, designname=design_name) return True diff --git a/pyaedt/icepak.py b/pyaedt/icepak.py index 843f0da26b8..ec956079033 100644 --- a/pyaedt/icepak.py +++ b/pyaedt/icepak.py @@ -2644,12 +2644,12 @@ def copyGroupFrom(self, group_name, source_design, source_project_name=None, sou source_project_path = kwargs["sourceProjectPath"] if source_project_name == self.project_name or source_project_name is None: - active_project = self._desktop.GetActiveProject() + active_project = self.desktop_class.active_project() else: self._desktop.OpenProject(source_project_path) - active_project = self._desktop.SetActiveProject(source_project_name) + active_project = self.desktop_class.active_project(source_project_name) - active_design = active_project.SetActiveDesign(source_design) + active_design = self.desktop_class.active_design(active_project, source_design) active_editor = active_design.SetActiveEditor("3D Modeler") active_editor.Copy(["NAME:Selections", "Selections:=", group_name]) @@ -3297,7 +3297,7 @@ def import_idf( >>> oDesign.ImportIDF """ - active_design_name = self.oproject.GetActiveDesign().GetName() + active_design_name = self.desktop_class.active_design(self.oproject).GetName() if not library_path: if board_path.endswith(".emn"): library_path = board_path[:-3] + "emp" @@ -3389,7 +3389,7 @@ def import_idf( ) self.modeler.add_new_objects() if active_design_name: - self.oproject.SetActiveDesign(active_design_name) + self.desktop_class.active_design(self.oproject, active_design_name) return True @pyaedt_function_handler() diff --git a/pyaedt/maxwell.py b/pyaedt/maxwell.py index 2489fd112f0..a0ba0094986 100644 --- a/pyaedt/maxwell.py +++ b/pyaedt/maxwell.py @@ -6,11 +6,14 @@ import io import os import re +import time +from pyaedt import settings from pyaedt.application.Analysis3D import FieldAnalysis3D from pyaedt.application.Variables import decompose_variable_value from pyaedt.generic.constants import SOLUTIONS from pyaedt.generic.general_methods import generate_unique_name +from pyaedt.generic.general_methods import is_linux from pyaedt.generic.general_methods import open_file from pyaedt.generic.general_methods import pyaedt_function_handler from pyaedt.generic.general_methods import read_configuration_file @@ -1936,8 +1939,11 @@ def edit_external_circuit(self, netlist_file_path, schematic_design_name): """ if schematic_design_name not in self.design_list: return False - odesign = self.oproject.SetActiveDesign(schematic_design_name) + odesign = self.desktop_class.active_design(self.oproject, schematic_design_name) oeditor = odesign.SetActiveEditor("SchematicEditor") + if is_linux and settings.aedt_version == "2024.1": + time.sleep(1) + self.odesktop.CloseAllWindows() comps = oeditor.GetAllComponents() sources_array = [] sources_type_array = [] @@ -3015,6 +3021,17 @@ def assign_balloon(self, assignment, boundary=None): ---------- >>> oModule.AssignBalloon + + + Examples + -------- + Set balloon boundary condition in Maxwell 2D. + + >>> from pyaedt import Maxwell2d + >>> m2d = Maxwell2d() + >>> region_id = m2d.modeler.create_region() + >>> region_edges = region_id.edges + >>> m2d.assign_balloon(edge_list=region_edges) """ assignment = self.modeler.convert_to_selections(assignment, True) @@ -3054,6 +3071,17 @@ def assign_vector_potential(self, assignment, vector_value=0, boundary=None): ---------- >>> oModule.AssignVectorPotential + + + Examples + -------- + Set vector potential to zero at the boundary edges in Maxwell 2D. + + >>> from pyaedt import Maxwell2d + >>> m2d = Maxwell2d() + >>> region_id = m2d.modeler.create_region() + >>> region_edges = region_id.edges + >>> m2d.assign_vector_potential(input_edge=region_edges) """ assignment = self.modeler.convert_to_selections(assignment, True) diff --git a/pyaedt/modeler/cad/Primitives2D.py b/pyaedt/modeler/cad/Primitives2D.py index 0d640ea7724..dbf284685a5 100644 --- a/pyaedt/modeler/cad/Primitives2D.py +++ b/pyaedt/modeler/cad/Primitives2D.py @@ -287,7 +287,8 @@ def create_region(self, pad_value=300, pad_type="Percentage Offset", name="Regio Padding values to apply. If a list is not provided, the same value is applied to all padding directions. If a list of floats or strings is provided, the values are - interpreted as padding for ``["+X", "-X", "+Y", "-Y", "+Z", "-Z"]``. + interpreted as padding for ``["+X", "-X", "+Y", "-Y"]`` for XY geometry mode, + and ``["+R", "+Z", "-Z"]`` for RZ geometry mode. pad_type : str, optional Padding definition. The default is ``"Percentage Offset"``. Options are ``"Absolute Offset"``, @@ -318,24 +319,26 @@ def create_region(self, pad_value=300, pad_type="Percentage Offset", name="Regio if kwarg.get("pad_percent", False): pad_percent = kwarg["pad_percent"] pad_value = pad_percent - if isinstance(pad_value, list) and len(pad_value) < 6: - pad_value = [pad_value[i // 2 + 3 * (i % 2)] for i in range(6)] + if isinstance(pad_value, list) and len(pad_value) == 4: + pad_value = [pad_value[i // 2 + 2 * (i % 2)] for i in range(4)] pad_type = ["Absolute Offset", "Percentage Offset"][int(is_percentage)] if isinstance(pad_type, bool): pad_type = ["Absolute Offset", "Percentage Offset"][int(pad_type)] - if not isinstance(pad_value, list): - pad_value = [pad_value] * 4 if self._app.design_type == "2D Extractor" or ( self._app.design_type == "Maxwell 2D" and self._app.odesign.GetGeometryMode() == "XY" ): + if not isinstance(pad_value, list): + pad_value = [pad_value] * 4 if len(pad_value) != 4: self.logger.error("Wrong padding list provided. Four values have to be provided.") return False pad_value = [pad_value[0], pad_value[2], pad_value[1], pad_value[3], 0, 0] else: - if len(pad_value) < 3: + if not isinstance(pad_value, list): + pad_value = [pad_value] * 3 + if len(pad_value) != 3: self.logger.error("Wrong padding list provided. Three values have to be provided for RZ geometry.") return False pad_value = [pad_value[0], 0, 0, 0, pad_value[1], pad_value[2]] diff --git a/pyaedt/modeler/cad/components_3d.py b/pyaedt/modeler/cad/components_3d.py index 25e3d419424..00bca1d4bf9 100644 --- a/pyaedt/modeler/cad/components_3d.py +++ b/pyaedt/modeler/cad/components_3d.py @@ -885,7 +885,7 @@ def edit_definition(self, password=""): new_project = [i for i in self._primitives._app.project_list if i not in project_list] if new_project: - project = self._primitives._app.odesktop.SetActiveProject(new_project[0]) + project = self._primitives._app.desktop_class.active_project(new_project[0]) # project = self._primitives._app.odesktop.GetActiveProject() project_name = project.GetName() project.GetDesigns()[0].GetName() diff --git a/pyaedt/modeler/circuits/PrimitivesNexxim.py b/pyaedt/modeler/circuits/PrimitivesNexxim.py index bc43400b011..e736fb3273b 100644 --- a/pyaedt/modeler/circuits/PrimitivesNexxim.py +++ b/pyaedt/modeler/circuits/PrimitivesNexxim.py @@ -2,12 +2,15 @@ import os import random import re +import time import warnings +from pyaedt import settings from pyaedt.application.Variables import decompose_variable_value from pyaedt.generic.LoadAEDTFile import load_keyword_in_aedt_file from pyaedt.generic.constants import AEDT_UNITS from pyaedt.generic.general_methods import generate_unique_name +from pyaedt.generic.general_methods import is_linux from pyaedt.generic.general_methods import open_file from pyaedt.generic.general_methods import pyaedt_function_handler from pyaedt.modeler.circuits.PrimitivesCircuit import CircuitComponents @@ -172,10 +175,16 @@ def create_subcircuit(self, location=None, angle=None, name=None, nested_subcirc parent_name = "{}:{}".format(self._app.design_name.split("/")[0], ":U" + str(random.randint(1, 10000))) self._app.odesign.InsertDesign("Circuit Design", name, "", parent_name) + if is_linux and settings.aedt_version == "2024.1": + time.sleep(1) + self._app.odesktop.CloseAllWindows() if nested_subcircuit_id: pname = "{}:{}".format(self._app.design_name.split("/")[0], nested_subcircuit_id) - odes = self._app.oproject.SetActiveDesign(pname) + odes = self._app.desktop_class.active_design(self._app.oproject, pname) oed = odes.SetActiveEditor("SchematicEditor") + if is_linux and settings.aedt_version == "2024.1": + time.sleep(1) + self._app.odesktop.CloseAllWindows() objs = oed.GetAllElements() match = [i for i in objs if name in i] o = CircuitComponent(self, tabname=self.tab_name, custom_editor=oed) diff --git a/pyaedt/modeler/modelerpcb.py b/pyaedt/modeler/modelerpcb.py index 413cdc7856f..d205b74136d 100644 --- a/pyaedt/modeler/modelerpcb.py +++ b/pyaedt/modeler/modelerpcb.py @@ -530,7 +530,7 @@ def import_cadence_brd(self, input_file, output_dir=None, name=None): self._oimportexport.ImportExtracta( input_file, os.path.join(output_dir, name + ".aedb"), os.path.join(output_dir, name + ".xml") ) - self._app.__init__(self._app._desktop.GetActiveProject().GetName()) + self._app.__init__(self._app.desktop_class.active_project().GetName()) return True @pyaedt_function_handler() @@ -584,7 +584,7 @@ def import_ipc2581(self, input_file, output_dir=None, name=None): self._oimportexport.ImportIPC( input_file, os.path.join(output_dir, name + ".aedb"), os.path.join(output_dir, name + ".xml") ) - self._app.__init__(self._app._desktop.GetActiveProject().GetName()) + self._app.__init__(self._app.desktop_class.active_project().GetName()) return True @pyaedt_function_handler() diff --git a/pyaedt/modeler/schematic.py b/pyaedt/modeler/schematic.py index 2a54297351f..c6be0544f93 100644 --- a/pyaedt/modeler/schematic.py +++ b/pyaedt/modeler/schematic.py @@ -1,8 +1,11 @@ # -*- coding: utf-8 -*- import random import re +import time +from pyaedt import settings from pyaedt.generic.constants import AEDT_UNITS +from pyaedt.generic.general_methods import is_linux from pyaedt.generic.general_methods import pyaedt_function_handler from pyaedt.modeler.cad.Modeler import Modeler from pyaedt.modeler.circuits.PrimitivesEmit import EmitComponent @@ -533,7 +536,11 @@ def model_units(self): >>> oEditor.GetActiveUnits >>> oEditor.SetActiveUnits """ - return self.layouteditor.GetActiveUnits() + active_units = self.layouteditor.GetActiveUnits() + if is_linux and settings.aedt_version == "2024.1": + time.sleep(1) + self._app.odesktop.CloseAllWindows() + return active_units @property def layout(self): diff --git a/pyaedt/modules/MeshIcepak.py b/pyaedt/modules/MeshIcepak.py index a0939fbae27..9712122c57c 100644 --- a/pyaedt/modules/MeshIcepak.py +++ b/pyaedt/modules/MeshIcepak.py @@ -274,7 +274,8 @@ def name(self): @name.setter def name(self, value): try: - self._app.modeler.objects_by_name[self._name].name = value + if self._app.modeler.objects_by_name[self._name].name != value: + self._app.modeler.objects_by_name[self._name].name = value except KeyError: if self._app.modeler.objects_by_name[value].history().command == "CreateSubRegion": self._name = value @@ -408,6 +409,13 @@ def parts(self, parts): class MeshSettings(object): + """ + Class for managing mesh settings. + + It can be used like a dictionary. Available keys change according + to the type of settings chosen (manual or automatic). + """ + _automatic_mesh_settings = {"MeshRegionResolution": 3} # min: 1, max: 5 _common_mesh_settings = { "ProximitySizeFunction": True, @@ -464,14 +472,14 @@ def _dim_arg(self, value): else: return _dim_arg(value, getattr(self._mesh_class, "_model_units")) - def parse_settings(self): + def parse_settings_as_args(self): """ Parse mesh region settings. Returns ------- - dict - List of strings containing all the parts that must be included in the subregion. + List + Arguments to pass to native APIs. """ out = [] for k, v in self._instance_settings.items(): @@ -481,6 +489,22 @@ def parse_settings(self): out.append(v) return out + def parse_settings_as_dictionary(self): + """ + Parse mesh region settings. + + Returns + ------- + dict + Settings of the subregion. + """ + out = {} + for k, v in self._instance_settings.items(): + if k in ["MaxElementSizeX", "MaxElementSizeY", "MaxElementSizeZ", "MinGapX", "MinGapY", "MinGapZ"]: + v = self._dim_arg(v) + out[k] = v + return out + def _key_in_dict(self, key): if self._mesh_class.manual_settings: ref_dict = self._manual_mesh_settings @@ -489,13 +513,29 @@ def _key_in_dict(self, key): return key in ref_dict or key in self._common_mesh_settings def keys(self): - return self.parse_settings().keys() + """ + Get mesh region settings keys. + + Returns + ------- + dict_keys + Available settings keys. + """ + return self.parse_settings_as_dictionary().keys() def values(self): - return self.parse_settings().values() + """ + Get mesh region settings values. + + Returns + ------- + dict_values + Settings values. + """ + return self.parse_settings_as_dictionary().values() def __repr__(self): - return repr(self.parse_settings()) + return repr(self.parse_settings_as_dictionary()) def __getitem__(self, key): if key == "Level": @@ -628,7 +668,7 @@ def update(self): >>> oModule.EditGlobalMeshRegion """ args = ["NAME:Settings"] - args += self.settings.parse_settings() + args += self.settings.parse_settings_as_args() args += ["UserSpecifiedSettings:=", self.manual_settings] try: self._app.omeshmodule.EditGlobalMeshRegion(args) @@ -754,7 +794,7 @@ def update(self): >>> oModule.EditMeshRegion """ args = ["NAME:" + self.name, "Enable:=", self.enable] - args += self.settings.parse_settings() + args += self.settings.parse_settings_as_args() args += self._parse_assignment_value() args += ["UserSpecifiedSettings:=", self.manual_settings] try: @@ -854,7 +894,7 @@ def create(self): self._app.logger.error("Cannot create a new mesh region with this Name") return False args = ["NAME:" + self.name, "Enable:=", self.enable] - args += self.settings.parse_settings() + args += self.settings.parse_settings_as_args() args += ["UserSpecifiedSettings:=", not self.manual_settings] args += self._parse_assignment_value() self._app.omeshmodule.AssignMeshRegion(args) diff --git a/pyaedt/modules/PostProcessor.py b/pyaedt/modules/PostProcessor.py index e95d3c7c9e1..6e1b0eab8f6 100644 --- a/pyaedt/modules/PostProcessor.py +++ b/pyaedt/modules/PostProcessor.py @@ -3056,7 +3056,7 @@ def _create_fieldplot( except Exception: pass self._desktop.TileWindows(0) - self._oproject.SetActiveDesign(self._app.design_name) + self._app.desktop_class.active_design(self._oproject, self._app.design_name) char_set = string.ascii_uppercase + string.digits if not plot_name: @@ -3116,7 +3116,7 @@ def _create_fieldplot_line_traces( except Exception: pass self._desktop.TileWindows(0) - self._oproject.SetActiveDesign(self._app.design_name) + self._app.desktop_class.active_design(self._oproject, self._app.design_name) char_set = string.ascii_uppercase + string.digits if not plot_name: diff --git a/pyaedt/modules/SolveSetup.py b/pyaedt/modules/SolveSetup.py index 5597f9ff439..743a7267150 100644 --- a/pyaedt/modules/SolveSetup.py +++ b/pyaedt/modules/SolveSetup.py @@ -1979,7 +1979,7 @@ def _get_primitives_points_per_net(self): while len(primitive_dict[net]) < len(net_primitives[net]): if n > 1000: # adding 1000 as maximum value to prevent infinite loop return - n += 10 + n += 20 primitive_dict[net] = [] for prim in primitives: layer = edb.stackup.signal_layers[prim.layer_name] diff --git a/pyproject.toml b/pyproject.toml index d485a89d2b9..3c2dd415540 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,7 +29,7 @@ dependencies = [ "fpdf2", "jsonschema", "psutil", - "pyedb>=0.4.0,<0.9; python_version == '3.7'", + "pyedb>=0.4.0,<0.10; python_version == '3.7'", "pyedb>=0.5.0; python_version > '3.7'", "pytomlpp; python_version < '3.12'", "rpyc>=6.0.0,<6.1", @@ -38,7 +38,7 @@ dependencies = [ [project.optional-dependencies] tests = [ "imageio>=2.30.0,<2.35", - "ipython>=7.30.0,<8.24", + "ipython>=7.30.0,<8.25", "joblib>=1.0.0,<1.5", "matplotlib>=3.5.0,<3.9", "mock>=5.1.0,<5.2", @@ -46,11 +46,11 @@ tests = [ "openpyxl>=3.1.0,<3.3", "osmnx>=1.1.0,<1.10", "pandas>=1.1.0,<2.3", - "pytest>=7.4.0,<8.2", + "pytest>=7.4.0,<8.3", "pytest-cov>=4.0.0,<5.1", "pytest-xdist>=3.5.0,<3.7", - "pyedb>=0.4.0,<0.9; python_version == '3.7'", - "pyedb>=0.5.0,<0.9; python_version > '3.7'", + "pyedb>=0.4.0,<0.10; python_version == '3.7'", + "pyedb>=0.5.0,<0.10; python_version > '3.7'", "pyvista>=0.38.0,<0.44", "scikit-learn>=1.0.0,<1.5", "scikit-rf>=0.30.0,<1.1", @@ -70,7 +70,7 @@ doc = [ "imageio>=2.30.0,<2.35", #"imageio-ffmpeg>=0.4.0,<0.5", "ipython>=7.34.0; python_version == '3.7'", - "ipython>=8.13.0,<8.24; python_version > '3.7'", + "ipython>=8.13.0,<8.25; python_version > '3.7'", #"ipywidgets>=8.0.0,<8.2", "joblib>=1.3.0,<1.5", "jupyterlab>=4.0.0,<4.3", @@ -92,7 +92,7 @@ doc = [ "sphinx-autobuild==2024.4.16; python_version > '3.8'", #"sphinx-autodoc-typehints", "sphinx-copybutton>=0.5.0,<0.6", - "sphinx-gallery>=0.14.0,<0.16", + "sphinx-gallery>=0.14.0,<0.17", "sphinx-jinja>=2.0,<2.1", #"sphinx-notfound-page", "sphinx_design>=0.4.0,<0.6", @@ -114,7 +114,7 @@ doc-no-examples = [ "sphinx-autobuild==2024.4.16; python_version > '3.8'", #"sphinx-autodoc-typehints", "sphinx-copybutton>=0.5.0,<0.6", - "sphinx-gallery>=0.14.0,<0.16", + "sphinx-gallery>=0.14.0,<0.17", #"sphinx-notfound-page", #"sphinxcontrib-websupport", "sphinx_design>=0.4.0,<0.6",