From 064f0023becaea761b19ac0c16e32792aaeeb4c2 Mon Sep 17 00:00:00 2001 From: Massimo Capodiferro <77293250+maxcapodi78@users.noreply.github.com> Date: Wed, 4 Sep 2024 15:43:01 +0200 Subject: [PATCH] FEAT: added method to enable matrix convergence (#5126) Co-authored-by: maxcapodi78 --- _unittest/test_11_Setup.py | 34 +++++ _unittest/test_41_3dlayout_modeler.py | 33 ++++ examples/07-Circuit/Reports.py | 2 +- src/ansys/aedt/core/modules/solve_setup.py | 170 +++++++++++++++++++++ 4 files changed, 238 insertions(+), 1 deletion(-) diff --git a/_unittest/test_11_Setup.py b/_unittest/test_11_Setup.py index 5124417a691..7da351b0c71 100644 --- a/_unittest/test_11_Setup.py +++ b/_unittest/test_11_Setup.py @@ -68,6 +68,40 @@ def test_01_create_hfss_setup(self): setup1.disable() setup1.enable() + assert setup1.use_matrix_convergence( + entry_selection=0, + ignore_phase_when_mag_is_less_than=0.015, + all_diagonal_entries=True, + max_delta=0.03, + max_delta_phase=8, + custom_entries=None, + ) + assert setup1.use_matrix_convergence( + entry_selection=1, + ignore_phase_when_mag_is_less_than=0.025, + all_diagonal_entries=True, + max_delta=0.023, + max_delta_phase=18, + custom_entries=None, + all_offdiagonal_entries=False, + ) + assert setup1.use_matrix_convergence( + entry_selection=1, + ignore_phase_when_mag_is_less_than=0.025, + all_diagonal_entries=True, + max_delta=0.023, + max_delta_phase=18, + custom_entries=None, + ) + assert setup1.use_matrix_convergence( + entry_selection=2, + ignore_phase_when_mag_is_less_than=0.01, + all_diagonal_entries=True, + max_delta=0.01, + max_delta_phase=8, + custom_entries=[["1", "2", 0.03, 4]], + ) + def test_01b_create_hfss_sweep(self): self.aedtapp.save_project() setup1 = self.aedtapp.get_setup("My_HFSS_Setup") diff --git a/_unittest/test_41_3dlayout_modeler.py b/_unittest/test_41_3dlayout_modeler.py index df072e9f2be..58a66560aaa 100644 --- a/_unittest/test_41_3dlayout_modeler.py +++ b/_unittest/test_41_3dlayout_modeler.py @@ -369,6 +369,39 @@ def test_15_edit_setup(self): setup2.props["AdvancedSettings"]["OrderBasis"] = 2 setup2.props["PercentRefinementPerPass"] = 17 assert setup2.update() + assert setup2.use_matrix_convergence( + entry_selection=0, + ignore_phase_when_mag_is_less_than=0.015, + all_diagonal_entries=True, + max_delta=0.03, + max_delta_phase=8, + custom_entries=None, + ) + assert setup2.use_matrix_convergence( + entry_selection=1, + ignore_phase_when_mag_is_less_than=0.025, + all_diagonal_entries=True, + max_delta=0.023, + max_delta_phase=18, + custom_entries=None, + all_offdiagonal_entries=False, + ) + assert setup2.use_matrix_convergence( + entry_selection=1, + ignore_phase_when_mag_is_less_than=0.025, + all_diagonal_entries=True, + max_delta=0.023, + max_delta_phase=18, + custom_entries=None, + ) + assert setup2.use_matrix_convergence( + entry_selection=2, + ignore_phase_when_mag_is_less_than=0.01, + all_diagonal_entries=True, + max_delta=0.01, + max_delta_phase=8, + custom_entries=[["1", "2", 0.03, 4]], + ) def test_16_disable_enable_setup(self): setup_name = "RFBoardSetup3" diff --git a/examples/07-Circuit/Reports.py b/examples/07-Circuit/Reports.py index f9dc6556001..15fbe039666 100644 --- a/examples/07-Circuit/Reports.py +++ b/examples/07-Circuit/Reports.py @@ -32,7 +32,7 @@ # The Boolean parameter ``new_thread`` defines whether to create a new instance # of AEDT or try to connect to an existing instance of it. -non_graphical = True +non_graphical = False NewThread = True ############################################################################### diff --git a/src/ansys/aedt/core/modules/solve_setup.py b/src/ansys/aedt/core/modules/solve_setup.py index c70979c3cfa..d939e859053 100644 --- a/src/ansys/aedt/core/modules/solve_setup.py +++ b/src/ansys/aedt/core/modules/solve_setup.py @@ -2320,6 +2320,88 @@ def export_to_json(self, file_path, overwrite=False): return False return self.props._export_properties_to_json(file_path, overwrite=overwrite) + @pyaedt_function_handler() + def use_matrix_convergence( + self, + entry_selection=0, + ignore_phase_when_mag_is_less_than=0.01, + all_diagonal_entries=True, + max_delta=0.02, + max_delta_phase=5, + all_offdiagonal_entries=True, + off_diagonal_mag=0.02, + off_diagonal_phase=5, + custom_entries=None, + ): + """Enable Matrix Convergence criteria. + + Parameters + ---------- + entry_selection : int + Entry Selection. ``0`` for All, ``1`` for Diagonal Entries, ``2`` for custom entries. + ignore_phase_when_mag_is_less_than : float + Value of magnitude when phase is ignored. + all_diagonal_entries : bool + Whether diagonal entries has to be included in convergence or not. Default is ``True``. + max_delta : float + Maximum Delta S. + max_delta_phase : float, str + Maximum delta phase in degree. + all_offdiagonal_entries : bool + Whether off-diagonal entries has to be included in convergence or not. Default is ``True``. + off_diagonal_mag : float + Maximum offdiagonal Delta S. + off_diagonal_phase : float, str + Maximum off-diagonal delta phase in degree. + custom_entries : list, optional + Custom entry mapping list. + Every item of the listshall be a list with 4 elements: + ``[port 1 name, port 2 name, max_delta_s, max_delta_angle]``. + + Returns + ------- + bool + """ + legacy_update = self.auto_update + self.auto_update = False + self.props["UseConvergenceMatrix"] = True + self.props["AllEntries"] = True if entry_selection == 0 else False + self.props["AllDiagEntries"] = True if entry_selection == 1 and all_diagonal_entries else False + self.props["AllOffDiagEntries"] = True if entry_selection == 1 and all_offdiagonal_entries else False + self.props["MagMinThreshold"] = ignore_phase_when_mag_is_less_than + aa = self._app.excitations + if entry_selection < 2: + val = [] + if entry_selection == 0 or (entry_selection == 1 and all_diagonal_entries): + entry = { + "Port1": aa[0], + "Port2": aa[0], + "MagLimit": str(max_delta), + "PhaseLimit": self._app.value_with_units(max_delta_phase, "deg"), + } + val.append(SetupProps(self, entry)) + if entry_selection == 1 and all_offdiagonal_entries and len(aa) > 1: + entry = { + "Port1": aa[0], + "Port2": aa[1], + "MagLimit": str(off_diagonal_mag), + "PhaseLimit": self._app.value_with_units(off_diagonal_phase, "deg"), + } + val.append(SetupProps(self, entry)) + self.props["MatrixConvEntry"] = val + else: + self.props["MatrixConvEntry"] = [] + for entry_custom in custom_entries: + entry = { + "Port1": entry_custom[0], + "Port2": entry_custom[1], + "MagLimit": str(entry_custom[2]), + "PhaseLimit": self._app.value_with_units(entry_custom[3], "deg"), + } + self.props["MatrixConvEntry"].append(SetupProps(self, entry)) + self.auto_update = legacy_update + return self.update() + class SetupHFSS(Setup, object): """Initializes, creates, and updates an HFSS setup. @@ -2949,6 +3031,94 @@ def enable_adaptive_setup_multifrequency(self, frequencies, max_delta_s=0.02): self.auto_update = True return self.update() + @pyaedt_function_handler() + def use_matrix_convergence( + self, + entry_selection=0, + ignore_phase_when_mag_is_less_than=0.01, + all_diagonal_entries=True, + max_delta=0.02, + max_delta_phase=5, + all_offdiagonal_entries=True, + off_diagonal_mag=0.02, + off_diagonal_phase=5, + custom_entries=None, + ): + """Enable Matrix Convergence criteria. + + Parameters + ---------- + entry_selection : int + Entry Selection. ``0`` for All, ``1`` for Diagonal Entries, ``2`` for custom entries. + ignore_phase_when_mag_is_less_than : float + Value of magnitude when phase is ignored. + all_diagonal_entries : bool + Whether diagonal entries has to be included in convergence or not. Default is ``True``. + max_delta : float + Maximum Delta S. + max_delta_phase : float, str + Maximum delta phase in degree. + all_offdiagonal_entries : bool + Whether off-diagonal entries has to be included in convergence or not. Default is ``True``. + off_diagonal_mag : float + Maximum offdiagonal Delta S. + off_diagonal_phase : float, str + Maximum off-diagonal delta phase in degree. + custom_entries : list, optional + Custom entry mapping list. + Every item of the lists hall be a list with 4 elements: + ``[port 1 name, port 2 name, max_delta_s, max_delta_angle]``. + + Returns + ------- + bool + """ + legacy_update = self.auto_update + self.auto_update = False + conv_data = {} + if entry_selection == 0: + conv_data = { + "AllEntries": True, + "MagLimit": str(max_delta), + "PhaseLimit": self._app.value_with_units(max_delta_phase, "deg"), + "MagMinThreshold": ignore_phase_when_mag_is_less_than, + } + elif entry_selection == 1: + conv_data = {} + if all_diagonal_entries: + conv_data["AllDiagEntries"] = True + conv_data["DiagonalMag"] = str(max_delta) + conv_data["DiagonalPhase"] = self._app.value_with_units(max_delta_phase, "deg") + conv_data["MagMinThreshold"] = ignore_phase_when_mag_is_less_than + if all_offdiagonal_entries and len(self._app.excitations) > 1: + conv_data["AllOffDiagEntries"] = True + conv_data["OffDiagonalMag"] = str(off_diagonal_mag) + conv_data["OffDiagonalPhase"] = self._app.value_with_units(off_diagonal_phase, "deg") + conv_data["MagMinThreshold"] = ignore_phase_when_mag_is_less_than + elif entry_selection == 2 and custom_entries: + if len(custom_entries) > 1: + conv_data = {"Entries": []} + else: + conv_data = {"Entries": {}} + for entry_custom in custom_entries: + entry = { + "Port1": entry_custom[0], + "Port2": entry_custom[1], + "MagLimit": entry_custom[2], + "PhaseLimit": self._app.value_with_units(entry_custom[3], "deg"), + } + if isinstance(conv_data["Entries"], list): + conv_data["Entries"].append(SetupProps(self, {"Entry": entry})) + else: + conv_data["Entries"] = SetupProps(self, {"Entry": entry}) + if conv_data: + props = SetupProps(self, conv_data) + self.props["Matrix Convergence"] = props + self.props["UseMatrixConv"] = True + self.auto_update = legacy_update + return self.update() + return False + class SetupHFSSAuto(Setup, object): """Initializes, creates, and updates an HFSS SBR+ or HFSS Auto setup.