diff --git a/doc/changelog.d/7674.maintenance.md b/doc/changelog.d/7674.maintenance.md new file mode 100644 index 000000000000..5146b7a0673a --- /dev/null +++ b/doc/changelog.d/7674.maintenance.md @@ -0,0 +1 @@ +Delete deprecation diff --git a/src/ansys/aedt/core/application/analysis.py b/src/ansys/aedt/core/application/analysis.py index c3595e6b4e63..b65fff5618c2 100644 --- a/src/ansys/aedt/core/application/analysis.py +++ b/src/ansys/aedt/core/application/analysis.py @@ -38,7 +38,6 @@ import tempfile import time from typing import TYPE_CHECKING -import warnings from ansys.aedt.core.application.design import Design from ansys.aedt.core.application.job_manager import update_hpc_option @@ -47,7 +46,6 @@ from ansys.aedt.core.generic.constants import Gravity from ansys.aedt.core.generic.file_utils import generate_unique_name from ansys.aedt.core.generic.file_utils import open_file -from ansys.aedt.core.generic.general_methods import deprecate_argument from ansys.aedt.core.generic.general_methods import filter_tuple from ansys.aedt.core.generic.general_methods import is_linux from ansys.aedt.core.generic.general_methods import is_windows @@ -670,13 +668,11 @@ def list_of_variations(self, setup: str = None, sweep: str = None) -> list[str]: if not setup and ":" in self.nominal_sweep: setup = self.nominal_adaptive.split(":")[0].strip() elif not setup: - self.logger.warning("No Setup defined.") - return False + raise ValueError("No Setup defined.") if not sweep and ":" in self.nominal_sweep: sweep = self.nominal_adaptive.split(":")[1].strip() elif not sweep: - self.logger.warning("No Sweep defined.") - return False + raise ValueError("No Sweep defined.") if ( self.solution_type == "HFSS3DLayout" or self.solution_type == "HFSS 3D Layout Design" @@ -693,13 +689,8 @@ def list_of_variations(self, setup: str = None, sweep: str = None) -> list[str]: return [""] @pyaedt_function_handler() - @deprecate_argument( - arg_name="analyze", - message="The ``analyze`` argument will be removed in future versions. Analyze before exporting results.", - ) def export_results( self, - analyze: bool = False, export_folder: str = None, matrix_name: str = "Original", matrix_type: str = "S", @@ -715,8 +706,6 @@ def export_results( Parameters ---------- - analyze : bool - Whether to analyze before export. Solutions must be present for the design. export_folder : str, optional Full path to the project folder. The default is ``None``, in which case the working directory is used. @@ -768,8 +757,6 @@ def export_results( exported_files = [] if not export_folder: export_folder = self.working_directory - if analyze: - self.analyze() # excitations if self.design_type == "HFSS3DLayout" or self.design_type == "HFSS 3D Layout Design": excitations = len(self.oexcitation.GetAllPortsList()) @@ -1129,7 +1116,7 @@ def export_parametric_results(self, sweep: str, output_file: str, export_units: Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -1267,7 +1254,7 @@ def delete_setup(self, name: str) -> bool: Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -1289,7 +1276,7 @@ def delete_setup(self, name: str) -> bool: if s.name == name: self._setups.remove(s) return True - return False + raise ValueError(f"Setup '{name}' not found.") @pyaedt_function_handler() def _get_setup(self, name: str): @@ -1368,7 +1355,7 @@ def create_output_variable( Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -1582,7 +1569,7 @@ def analyze( Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -1624,7 +1611,7 @@ def set_hpc_from_file(self, acf_file: str | Path = None, configuration_name: str Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. """ if not acf_file and not configuration_name: raise AEDTRuntimeError("No custom ACF file or configuration name provided.") @@ -1677,7 +1664,7 @@ def set_custom_hpc_options( Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. """ config_name = "pyaedt_config" source_name = os.path.join(self.pyaedt_dir, "misc", "pyaedt_local_config.acf") @@ -1795,7 +1782,7 @@ def analyze_setup( Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -1961,7 +1948,7 @@ def solve_in_batch( Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. """ import subprocess # nosec @@ -2332,7 +2319,7 @@ def change_properties( Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -2397,7 +2384,7 @@ def change_property( Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -2443,8 +2430,7 @@ def change_property( ] ) else: - self.logger.error("Wrong Property Value") - return False + raise ValueError(f"Wrong property value for '{property_name}'.") self.logger.info(f"Property {property_name} changed correctly.") return True @@ -2463,7 +2449,7 @@ def apply_solved_variation( Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -2671,25 +2657,6 @@ def variations(self, setup_sweep: str, output_as_dict: bool = False) -> list[lis families.append(family_list) return families - @pyaedt_function_handler() - def get_independent_nominal_values(self) -> dict: # pragma: no cover - """Retrieve variations for a given setup. - - .. deprecated:: 0.22.0 - Use :func:`nominal_variation` method instead. - - Returns - ------- - dict - Dictionary of independent nominal variations with values. - """ - warnings.warn( - "Usage of get_independent_nominal_values is deprecated. Use nominal_variation instead.", - DeprecationWarning, - stacklevel=2, - ) - return self.nominal_variation(dependent_params=False) - @pyaedt_function_handler() def nominal_variation(self, dependent_params: bool = True, expressions: bool = False) -> dict: """Retrieve variations for a given setup. diff --git a/src/ansys/aedt/core/application/design.py b/src/ansys/aedt/core/application/design.py index 4a71435295ef..e9ad134a02fe 100644 --- a/src/ansys/aedt/core/application/design.py +++ b/src/ansys/aedt/core/application/design.py @@ -1405,7 +1405,7 @@ def remove_all_unused_definitions(self) -> bool: return True @pyaedt_function_handler() - def get_profile(self, name: str = None) -> Profiles: + def get_profile(self, name: str = None) -> Profiles | None: """Get profile information. Parameters @@ -1457,7 +1457,7 @@ def get_profile(self, name: str = None) -> Profiles: return None else: # pragma: no cover self.logger.error("Profile can not be obtained.") - return False + return None @pyaedt_function_handler() def get_oo_name(self, aedt_object: object, object_name: str = None) -> list[str]: @@ -2584,9 +2584,6 @@ def autosave_enable(self) -> bool: def release_desktop(self, close_projects: bool = True, close_desktop: bool = True) -> bool: """Release AEDT. - .. deprecated:: 0.19.1 - This method is deprecated. Use the ``ansys.aedt.core.desktop.release_desktop()`` method instead. - Parameters ---------- close_projects : bool, optional diff --git a/src/ansys/aedt/core/circuit.py b/src/ansys/aedt/core/circuit.py index 4b5dc52def3b..f16e5c338bfc 100644 --- a/src/ansys/aedt/core/circuit.py +++ b/src/ansys/aedt/core/circuit.py @@ -43,11 +43,11 @@ from ansys.aedt.core.generic.file_utils import generate_unique_name from ansys.aedt.core.generic.file_utils import open_file from ansys.aedt.core.generic.file_utils import read_configuration_file -from ansys.aedt.core.generic.general_methods import deprecate_argument from ansys.aedt.core.generic.general_methods import is_linux from ansys.aedt.core.generic.general_methods import pyaedt_function_handler from ansys.aedt.core.generic.settings import settings from ansys.aedt.core.hfss3dlayout import Hfss3dLayout +from ansys.aedt.core.internal.errors import AEDTRuntimeError from ansys.aedt.core.internal.filesystem import search_files from ansys.aedt.core.modeler.circuits.object_3d_circuit import CircuitComponent from ansys.aedt.core.modules.boundary.circuit_boundary import CurrentSinSource @@ -157,14 +157,14 @@ def __init__( solution_type: str | None = None, setup: str | None = None, version: str | None = None, - non_graphical: bool | None = False, - new_desktop: bool | None = False, - close_on_exit: bool | None = False, - student_version: bool | None = False, - machine: str | None = "", - port: int | None = 0, + non_graphical: bool = False, + new_desktop: bool = False, + close_on_exit: bool = False, + student_version: bool = False, + machine: str = "", + port: int = 0, aedt_process_id: int | None = None, - remove_lock: bool | None = False, + remove_lock: bool = False, ) -> None: FieldAnalysisCircuit.__init__( self, @@ -684,7 +684,7 @@ def get_source_pin_names( source_design_name: str, source_project_name: str | None = None, source_project_path: str | None = None, - port_selector: int | None = 3, + port_selector: int = 3, ) -> list: """Retrieve pin names. @@ -726,7 +726,9 @@ def get_source_pin_names( if is_linux and settings.aedt_version == "2024.1": # pragma: no cover time.sleep(1) self.desktop_class.close_windows() + tmp_oModule = oDesign.GetModule("BoundarySetup") + port = None if port_selector == 1: port = "Wave Port" @@ -734,8 +736,10 @@ def get_source_pin_names( port = "Terminal" elif port_selector == 3: port = "Circuit Port" + if not port: - return False + raise ValueError("Selected port is not valid.") + pins = list(tmp_oModule.GetExcitationsOfType(port)) self.logger.info("%s Excitations Pins found.", len(pins)) return pins @@ -1200,7 +1204,7 @@ def push_time_excitations( return True @pyaedt_function_handler() - def create_source(self, source_type: str, name: str | None = None) -> Sources: + def create_source(self, source_type: str, name: str | None = None) -> "Sources": """Create a source in Circuit. Parameters @@ -1230,11 +1234,11 @@ def create_source(self, source_type: str, name: str | None = None) -> Sources: if not name: name = generate_unique_name("Source") if name in self.source_names: - self.logger.warning("Source name is defined in the design.") - return False + raise ValueError(f"Source name '{name}' is already defined in the design.") if source_type not in SourceKeys.SourceNames: - self.logger.warning("Source type is not correct.") - return False + raise ValueError( + f"Source type '{source_type}' is not valid. Available types are: {', '.join(SourceKeys.SourceNames)}." + ) if source_type == "PowerSin": new_source = PowerSinSource(self, name, source_type) elif source_type == "PowerIQ": @@ -1257,7 +1261,7 @@ def create_source(self, source_type: str, name: str | None = None) -> Sources: return new_source @pyaedt_function_handler() - def assign_voltage_sinusoidal_excitation_to_ports(self, ports: list) -> Sources: + def assign_voltage_sinusoidal_excitation_to_ports(self, ports: list) -> "Sources": """Assign a voltage sinusoidal excitation to circuit ports. Parameters @@ -1281,7 +1285,7 @@ def assign_voltage_sinusoidal_excitation_to_ports(self, ports: list) -> Sources: return source_v @pyaedt_function_handler() - def assign_current_sinusoidal_excitation_to_ports(self, ports: list) -> Sources: + def assign_current_sinusoidal_excitation_to_ports(self, ports: list) -> "Sources": """Assign a current sinusoidal excitation to circuit ports. Parameters @@ -1305,7 +1309,7 @@ def assign_current_sinusoidal_excitation_to_ports(self, ports: list) -> Sources: return source_i @pyaedt_function_handler() - def assign_power_sinusoidal_excitation_to_ports(self, ports: list) -> Sources: + def assign_power_sinusoidal_excitation_to_ports(self, ports: list) -> "Sources": """Assign a power sinusoidal excitation to circuit ports. Parameters @@ -1329,7 +1333,7 @@ def assign_power_sinusoidal_excitation_to_ports(self, ports: list) -> Sources: return source_p @pyaedt_function_handler() - def assign_voltage_frequency_dependent_excitation_to_ports(self, ports: list, input_file: str | Path) -> Sources: + def assign_voltage_frequency_dependent_excitation_to_ports(self, ports: list, input_file: str | Path) -> "Sources": """Assign a frequency dependent excitation to circuit ports from a frequency dependent source (FDS format). Parameters @@ -1348,16 +1352,19 @@ def assign_voltage_frequency_dependent_excitation_to_ports(self, ports: list, in ---------- >>> oDesign.UpdateSources """ - if not Path(input_file).exists() or Path(input_file).suffix != ".fds": - self.logger.error("Introduced file is not correct. Check path and format.") - return False + input_path = Path(input_file) + if not input_path.exists(): + raise FileNotFoundError(f"Input file '{input_file}' does not exist.") + + if input_path.suffix != ".fds": + raise ValueError(f"Input file '{input_file}' must have '.fds' extension, got '{input_path.suffix}'.") if not all(elem in self.excitation_names for elem in ports): - self.logger.error("Defined ports do not exist") - return False + missing = [p for p in ports if p not in self.excitation_names] + raise ValueError(f"Ports {missing} do not exist in the design.") source_freq = self.create_source(source_type="VoltageFrequencyDependent") - source_freq.fds_filename = input_file + source_freq.fds_filename = str(input_file) for port in ports: self.design_excitations[port].enabled_sources.append(source_freq.name) self.design_excitations[port].update() @@ -1396,7 +1403,7 @@ def set_differential_pair( Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -1470,7 +1477,7 @@ def set_differential_pair( try: self.odesign.SetDiffPairs(arg) except Exception: # pragma: no cover - return False + raise AEDTRuntimeError("Error setting the differential pair definition.") return True @pyaedt_function_handler() @@ -1488,7 +1495,7 @@ def load_diff_pairs_from_file(self, input_file: str | Path) -> bool: Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -1508,7 +1515,7 @@ def load_diff_pairs_from_file(self, input_file: str | Path) -> bool: self.odesign.LoadDiffPairsFromFile(str(new_file)) new_file.unlink() except Exception: # pragma: no cover - return False + raise AEDTRuntimeError("Error setting the differential pair definition.") return True @pyaedt_function_handler() @@ -1549,11 +1556,10 @@ def add_netlist_datablock(self, input_file: str | Path, name: str | None = None) Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. """ if not Path(input_file).exists(): - self.logger.error("Netlist File doesn't exists") - return False + raise FileNotFoundError(f"Input file '{input_file}' does not exist.") if not name: name = generate_unique_name("Inc") @@ -1638,7 +1644,7 @@ def connect_circuit_models_from_multi_zone_cutout( Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. Examples -------- @@ -1652,52 +1658,48 @@ def connect_circuit_models_from_multi_zone_cutout( >>> circ = Circuit() >>> circ.connect_circuit_models_from_multi_zone_cutout(project_connexions, edb_zones, defined_ports) """ - if project_connections and edb_zones_dict: - self.modeler.schematic_units = schematic_units - inc = model_inc - ind = 1 - for edb_file in list(edb_zones_dict.keys()): - hfss3d_layout_model = self.import_edb_in_circuit(input_dir=edb_file) - model_position = [ind * inc, 0] - hfss3d_layout_model.location = model_position - ind += 1 - for connection in project_connections: - pin1 = None - pin2 = None - model1 = next( - cmp for cmp in list(self.modeler.schematic.components.values()) if connection[0][0] in cmp.name - ) - if model1: - try: - pin1 = next(pin for pin in model1.pins if pin.name == connection[0][1]) - except Exception: - print("failed to get pin1") - model2 = next( - cmp for cmp in list(self.modeler.schematic.components.values()) if connection[1][0] in cmp.name - ) - if model2: - try: - pin2 = next(pin for pin in model2.pins if pin.name == connection[1][1]) - except Exception: - print("failed to get pin2") - if pin1 and pin2: - pin1.connect_to_component(assignment=pin2, use_wire=False) - for model_name, ports in ports.items(): - if any(cmp for cmp in list(self.modeler.schematic.components.values()) if model_name in cmp.name): - model = next( - cmp for cmp in list(self.modeler.schematic.components.values()) if model_name in cmp.name - ) - if model: - for port_name in ports: - try: - model_pin = next(pin for pin in model.pins if pin.name == port_name) - except StopIteration: - model_pin = None - if model_pin: - self.modeler.schematic.create_interface_port(port_name, model_pin.location) - self.save_project() - return True - return False + self.modeler.schematic_units = schematic_units + inc = model_inc + ind = 1 + for edb_file in list(edb_zones_dict.keys()): + hfss3d_layout_model = self.import_edb_in_circuit(input_dir=edb_file) + model_position = [ind * inc, 0] + hfss3d_layout_model.location = model_position + ind += 1 + for connection in project_connections: + pin1 = None + pin2 = None + model1 = next( + cmp for cmp in list(self.modeler.schematic.components.values()) if connection[0][0] in cmp.name + ) + if model1: + try: + pin1 = next(pin for pin in model1.pins if pin.name == connection[0][1]) + except Exception: + print("failed to get pin1") + model2 = next( + cmp for cmp in list(self.modeler.schematic.components.values()) if connection[1][0] in cmp.name + ) + if model2: + try: + pin2 = next(pin for pin in model2.pins if pin.name == connection[1][1]) + except Exception: + print("failed to get pin2") + if pin1 and pin2: + pin1.connect_to_component(assignment=pin2, use_wire=False) + for model_name, ports in ports.items(): + if any(cmp for cmp in list(self.modeler.schematic.components.values()) if model_name in cmp.name): + model = next(cmp for cmp in list(self.modeler.schematic.components.values()) if model_name in cmp.name) + if model: + for port_name in ports: + try: + model_pin = next(pin for pin in model.pins if pin.name == port_name) + except StopIteration: + model_pin = None + if model_pin: + self.modeler.schematic.create_interface_port(port_name, model_pin.location) + self.save_project() + return True @pyaedt_function_handler() def import_edb_in_circuit(self, input_dir: str | Path) -> CircuitComponent: @@ -1740,7 +1742,7 @@ def create_tdr_schematic_from_snp( termination_pins: list | None = None, differential: bool | None = True, rise_time: float | int = 30, - use_convolution: bool | None = True, + use_convolution: bool = True, design_name: str | None = "LNA", impedance: float | None = 50, time_step: str | None = None, @@ -1877,10 +1879,6 @@ def create_tdr_schematic_from_snp( return tdr_probe_names @pyaedt_function_handler() - @deprecate_argument( - arg_name="analyze", - message="The ``analyze`` argument will be removed in future versions. Analyze before exporting results.", - ) def create_lna_schematic_from_snp( self, input_file: str, @@ -1889,7 +1887,6 @@ def create_lna_schematic_from_snp( auto_assign_diff_pairs: bool = False, separation: str | None = ".", pattern: list | None = None, - analyze: bool | None = False, design_name: str | None = "LNA", ) -> tuple[bool, list, list]: """Create a schematic from a Touchstone file and automatically set up an LNA analysis. @@ -1910,8 +1907,6 @@ def create_lna_schematic_from_snp( Character to use to separate port names. The default is ``"."``. pattern : list, optional Port name pattern. The default is ``["component", "pin", "net"]``. - analyze : bool - Whether to automatically assign differential pairs. The default is ``False``. design_name : str, optional New schematic name. The default is ``"LNA"``. @@ -1983,15 +1978,9 @@ def create_lna_schematic_from_snp( break setup1 = self.create_setup() setup1.props["SweepDefinition"]["Data"] = f"LINC {start_frequency}GHz {stop_frequency}GHz 1001" - if analyze: - self.analyze() return True, diff_pairs, comm_pairs @pyaedt_function_handler() - @deprecate_argument( - arg_name="analyze", - message="The ``analyze`` argument will be removed in future versions. Analyze before exporting results.", - ) def create_ami_schematic_from_snp( self, input_file: str, @@ -2008,8 +1997,7 @@ def create_ami_schematic_from_snp( differential: bool | None = True, bit_pattern: str | None = None, unit_interval: str | None = None, - use_convolution: bool | None = True, - analyze: bool | None = True, + use_convolution: bool = True, design_name: str | None = "AMI", ibis_rx_file: str | None = None, create_setup: bool | None = True, @@ -2054,8 +2042,6 @@ def create_ami_schematic_from_snp( use_convolution : bool, optional Whether to use convolution for the Touchstone file. The default is ``True``. If ``False``, state-space is used. - analyze : bool - Whether to automatically assign differential pairs. The default is ``False``. design_name : str, optional New schematic name. The default is ``"LNA"``. ibis_rx_file : str, optional @@ -2086,17 +2072,12 @@ def create_ami_schematic_from_snp( bit_pattern=bit_pattern, unit_interval=unit_interval, use_convolution=use_convolution, - analyze=analyze, design_name=design_name, is_ami=True, create_setup=create_setup, ) @pyaedt_function_handler() - @deprecate_argument( - arg_name="analyze", - message="The ``analyze`` argument will be removed in future versions. Analyze before exporting results.", - ) def create_ibis_schematic_from_snp( self, input_file: str, @@ -2115,7 +2096,6 @@ def create_ibis_schematic_from_snp( bit_pattern: str | None = None, unit_interval: str | None = None, use_convolution: bool = True, - analyze: bool | None = False, design_name: str | None = "IBIS", is_ami: bool | None = False, create_setup: bool | None = True, @@ -2161,8 +2141,6 @@ def create_ibis_schematic_from_snp( use_convolution : bool, optional Whether to use convolution for the Touchstone file. The default is ``True``. If ``False``, state-space is used. - analyze : bool - Whether to automatically assign differential pairs. The default is ``False``. design_name : str, optional New schematic name. The default is ``"IBIS"``. is_ami : bool, optional @@ -2205,20 +2183,15 @@ def create_ibis_schematic_from_snp( bit_pattern=bit_pattern, unit_interval=unit_interval, use_convolution=use_convolution, - analyze=analyze, is_ami=is_ami, create_setup=create_setup, ) @pyaedt_function_handler() - @deprecate_argument( - arg_name="analyze", - message="The ``analyze`` argument will be removed in future versions. Analyze before exporting results.", - ) def create_ibis_schematic_from_pins( self, - ibis_tx_file, - ibis_rx_file=None, + ibis_tx_file: str, + ibis_rx_file: str | None = None, tx_buffer_name: str = "", rx_buffer_name: str = "", tx_schematic_pins: list | None = None, @@ -2233,8 +2206,7 @@ def create_ibis_schematic_from_pins( differential: bool | None = True, bit_pattern: str | None = None, unit_interval: str | None = None, - use_convolution: bool | None = True, - analyze: bool | None = False, + use_convolution: bool = True, is_ami: bool | None = False, create_setup: bool | None = True, ) -> tuple[bool, list, list]: @@ -2244,21 +2216,21 @@ def create_ibis_schematic_from_pins( ---------- ibis_tx_file : str Full path to the IBIS file for transmitters. - ibis_rx_file : str + ibis_rx_file : str, optional Full path to the IBIS file for receiver. - tx_buffer_name : str + tx_buffer_name : str, optional Transmission buffer name. It can be a buffer or a ibis pin name. In this last case the user has to provide also the component_name. - rx_buffer_name : str + rx_buffer_name : str, optional Receiver buffer name. - tx_schematic_pins : list + tx_schematic_pins : list, optional Pins to assign to the transmitter IBIS. rx_schematic_pins : list, optional Pins to assign to the receiver IBIS. tx_schematic_differential_pins : list, optional Reference pins to assign to the transmitter IBIS. This parameter is only used in a differential configuration. - rx_schematic_differential_pins : list + rx_schematic_differential_pins : list, optional Reference pins to assign to the receiver IBIS. This parameter is only used in a differential configuration. tx_component_name : str, optional @@ -2283,8 +2255,6 @@ def create_ibis_schematic_from_pins( use_convolution : bool, optional Whether to use convolution for the Touchstone file. The default is ``True``. If ``False``, state-space is used. - analyze : bool - Whether to automatically assign differential pairs. The default is ``False``. is_ami : bool, optional Whether the ibis is AMI. The default is ``False``. create_setup : bool, optional @@ -2307,8 +2277,9 @@ def create_ibis_schematic_from_pins( and v.parameters["ModelName"] == "FieldSolver" ][0] except Exception: - self.logger.error("A component has to be passed or an Sparameter present.") - return False + raise AEDTRuntimeError( + "A component name must be provided or an S-parameter component must be present in the schematic." + ) if rx_component_name is None: rx_component_name = tx_component_name sub = self.modeler.schematic[tx_component_name] @@ -2453,8 +2424,6 @@ def create_ibis_schematic_from_pins( ] ) setup_ibis.props["OptionName"] = "Nexxim Options" - if analyze: - setup_ibis.analyze() return True, tx_eye_names, rx_eye_names @pyaedt_function_handler() @@ -2720,7 +2689,7 @@ def import_table( sweep_columns: int | None = 0, total_columns: int | None = -1, real_columns: int | None = 1, - ) -> bool | str: + ) -> str: """Import a data table as a solution. Parameters @@ -2749,7 +2718,7 @@ def import_table( Returns ------- str - ``True`` when successful, ``False`` when failed. + Name of the imported sweep when successful. References ---------- @@ -2762,15 +2731,16 @@ def import_table( >>> cir.import_table(input_file="my_file.csv") """ columns_separator_map = {"Space": 0, "Tab": 1, "Comma": 2, "Period": 3} - if column_separator not in ["Space", "Tab", "Comma", "Period"]: - self.logger.error("Invalid column separator.") - return False + if column_separator not in columns_separator_map: + raise ValueError( + f"Invalid column separator '{column_separator}'. " + f"Available options are: {', '.join(columns_separator_map)}." + ) input_path = Path(input_file).resolve() if not input_path.is_file(): - self.logger.error("File does not exist.") - return False + raise FileNotFoundError(f"Input file '{input_path}' does not exist.") existing_sweeps = self.existing_analysis_sweeps @@ -2803,8 +2773,7 @@ def import_table( new_sweep = list(set(new_sweeps) - set(existing_sweeps)) if not new_sweep: # pragma: no cover - self.logger.error("Data not imported.") - return False + raise AEDTRuntimeError("Data not imported.") return new_sweep[0] @pyaedt_function_handler() @@ -2818,8 +2787,13 @@ def delete_imported_data(self, name: str) -> bool: Returns ------- - str - ``True`` when successful, ``False`` when failed. + bool + ``True`` when successful. + + Raises + ------ + ValueError + If the specified data name does not exist in the design. References ---------- @@ -2833,7 +2807,6 @@ def delete_imported_data(self, name: str) -> bool: >>> cir.delete_imported_data(table_name) """ if name not in self.existing_analysis_sweeps: - self.logger.error("Data does not exist.") - return False + raise ValueError(f"Data '{name}' does not exist in the design.") self.odesign.RemoveImportData(name) return True diff --git a/src/ansys/aedt/core/circuit_netlist.py b/src/ansys/aedt/core/circuit_netlist.py index c5f62137546a..8d2a8a412e4f 100644 --- a/src/ansys/aedt/core/circuit_netlist.py +++ b/src/ansys/aedt/core/circuit_netlist.py @@ -125,14 +125,14 @@ def __init__( project: str | None = None, design: str | None = None, version: str | None = None, - non_graphical: bool | None = False, - new_desktop: bool | None = False, - close_on_exit: bool | None = False, - student_version: bool | None = False, - machine: str | None = "", - port: int | None = 0, + non_graphical: bool = False, + new_desktop: bool = False, + close_on_exit: bool = False, + student_version: bool = False, + machine: str = "", + port: int = 0, aedt_process_id: int | None = None, - remove_lock: bool | None = False, + remove_lock: bool = False, ) -> None: AnalysisCircuitNetlist.__init__( self, diff --git a/src/ansys/aedt/core/desktop.py b/src/ansys/aedt/core/desktop.py index 72740ff6552b..086a6590647f 100644 --- a/src/ansys/aedt/core/desktop.py +++ b/src/ansys/aedt/core/desktop.py @@ -60,7 +60,6 @@ from ansys.aedt.core.generic.general_methods import _normalize_version_to_string from ansys.aedt.core.generic.general_methods import active_sessions from ansys.aedt.core.generic.general_methods import com_active_sessions -from ansys.aedt.core.generic.general_methods import deprecate_argument from ansys.aedt.core.generic.general_methods import grpc_active_sessions from ansys.aedt.core.generic.general_methods import inside_desktop_ironpython_console from ansys.aedt.core.generic.general_methods import is_grpc_session_active @@ -678,12 +677,12 @@ def __new__(cls, *args, **kwargs): def __init__( self, version: str | None = None, - non_graphical: bool | None = False, - new_desktop: bool | None = True, - close_on_exit: bool | None = True, - student_version: bool | None = False, + non_graphical: bool = False, + new_desktop: bool = True, + close_on_exit: bool = True, + student_version: bool = False, machine: str | None = None, - port: int | None = 0, + port: int = 0, aedt_process_id: int | None = None, ) -> None: """Initialize desktop.""" @@ -1825,11 +1824,6 @@ def __release_and_close_desktop(self, close_projects, close_aedt_app): return result @pyaedt_function_handler() - @deprecate_argument( - arg_name="close_on_exit", - message="The ``close_on_exit`` argument will be removed in future versions. " - "Use ``close_desktop`` method to close the desktop.", - ) def release_desktop(self, close_projects: bool | None = True, close_on_exit: bool | None = True) -> bool: """Release AEDT. @@ -1856,13 +1850,6 @@ def release_desktop(self, close_projects: bool | None = True, close_on_exit: boo >>> desktop.release_desktop(close_projects=False) # doctest: +SKIP """ - if close_on_exit: - warnings.warn( - "The `close_on_exit` argument will be removed in future versions. " - "Use `close_desktop` method to close the desktop.", - DeprecationWarning, - ) - return self.__release_and_close_desktop(close_projects, close_on_exit) def close_desktop(self) -> bool: @@ -2234,7 +2221,7 @@ def launch_job_monitor( @pyaedt_function_handler() def job_status(self) -> str: # pragma: no cover - """Get job status from job monitor.Job monitor has to be opened. + """Get job status from job monitor. Job monitor has to be opened. Returns ------- diff --git a/src/ansys/aedt/core/edb.py b/src/ansys/aedt/core/edb.py index 3cb38401ba8d..bd58bfe69fcf 100644 --- a/src/ansys/aedt/core/edb.py +++ b/src/ansys/aedt/core/edb.py @@ -43,12 +43,12 @@ def Edb( edbpath: str | None = None, cellname: str | None = None, - isreadonly: bool | None = False, + isreadonly: bool = False, version: str | None = None, - isaedtowned: bool | None = False, + isaedtowned: bool = False, oproject: Any | None = None, - student_version: bool | None = False, - use_ppe: bool | None = False, + student_version: bool = False, + use_ppe: bool = False, technology_file: str | None = None, ) -> "EdbApp": """Provides the EDB application interface. diff --git a/src/ansys/aedt/core/emit.py b/src/ansys/aedt/core/emit.py index 3645106bbf32..f12efb4e001b 100644 --- a/src/ansys/aedt/core/emit.py +++ b/src/ansys/aedt/core/emit.py @@ -133,14 +133,14 @@ def __init__( design: str | None = None, solution_type: str | None = None, version: str | None = None, - non_graphical: bool | None = False, + non_graphical: bool = False, new_desktop: bool = True, close_on_exit: bool = True, - student_version: bool | None = False, + student_version: bool = False, machine: str | None = "", - port: int | None = 0, + port: int = 0, aedt_process_id: int | None = None, - remove_lock: bool | None = False, + remove_lock: bool = False, ) -> None: self.__emit_api_enabled = False self.results = None diff --git a/src/ansys/aedt/core/emit_core/nodes/emit_node.py b/src/ansys/aedt/core/emit_core/nodes/emit_node.py index 62c6f4dcfe4b..929819191125 100644 --- a/src/ansys/aedt/core/emit_core/nodes/emit_node.py +++ b/src/ansys/aedt/core/emit_core/nodes/emit_node.py @@ -510,33 +510,6 @@ def _delete(self) -> None: else: self._oRevisionData.DeleteEmitNode(self._result_id, self._node_id) - @min_aedt_version("2025.2") - def _rename(self, requested_name: str) -> str: - """Renames the node/component. - - .. deprecated: 0.21.3 - Use name property instead - - Parameters - ---------- - requested_name : str - New name for the node/component. - - Returns - ------- - str - New name of the node/component. - - Raises - ------ - ValueError - If the node is read-only and cannot be renamed. - """ - warnings.warn("This property is deprecated in 0.21.3. Use the name property instead.", DeprecationWarning) - self.name = requested_name - - return self.name - @min_aedt_version("2025.2") def _duplicate(self: T, new_name: str = "") -> T: """Duplicate component using oEditor's Copy/Paste. diff --git a/src/ansys/aedt/core/generic/configurations.py b/src/ansys/aedt/core/generic/configurations.py index 67eedea2cac4..51bee774bbd1 100644 --- a/src/ansys/aedt/core/generic/configurations.py +++ b/src/ansys/aedt/core/generic/configurations.py @@ -861,7 +861,7 @@ def _update_object_properties(self, name: str, val) -> bool: if name in self._app.modeler.object_names: arg = ["NAME:AllTabs", ["NAME:Geometry3DAttributeTab", ["NAME:PropServers", name]]] arg2 = ["NAME:ChangedProps"] - if self._app.modeler[name].is3d or self._app.design_type in ["Maxwell 2D", "2D Extractor"]: + if self._app.modeler[name].is_3d or self._app.design_type in ["Maxwell 2D", "2D Extractor"]: if val.get("Material", None): arg2.append(["NAME:Material", "Value:=", chr(34) + val["Material"] + chr(34)]) if val.get("SolveInside", None): @@ -1356,7 +1356,7 @@ def _export_objects_properties(self, dict_out): dict_out["objects"] = {} for val in self._app.modeler.objects.values(): dict_out["objects"][val.name] = {} - if self._app.modeler[val.name].is3d or self._app.design_type in ["Maxwell 2D", "2D Extractor"]: + if self._app.modeler[val.name].is_3d or self._app.design_type in ["Maxwell 2D", "2D Extractor"]: dict_out["objects"][val.name]["Material"] = val.material_name dict_out["objects"][val.name]["SolveInside"] = val.solve_inside dict_out["objects"][val.name]["Model"] = val.model diff --git a/src/ansys/aedt/core/generic/constants.py b/src/ansys/aedt/core/generic/constants.py index 643019c052a3..3276ff5b64e6 100644 --- a/src/ansys/aedt/core/generic/constants.py +++ b/src/ansys/aedt/core/generic/constants.py @@ -26,7 +26,6 @@ from enum import IntEnum from enum import auto import math -from typing import Callable import warnings from ansys.aedt.core.generic.settings import settings @@ -693,36 +692,6 @@ def validate_enum_class_value(cls, value: int) -> bool: } -def deprecate_enum(new_enum: type) -> Callable: - """Decorator to mark an enumeration class as deprecated. - - It allows you to keep the old enumeration class in the code - and redirect its attributes to a new enumeration class. - """ - - def decorator(cls) -> type: - class Wrapper: - # NOTE: Required to handle correctly the documentation, name of the class and nested classes. - __doc__ = cls.__doc__ - __name__ = cls.__name__ - __qualname__ = cls.__qualname__ - - def __getattr__(self, name: str): - warnings.warn( - f"{cls.__qualname__} is deprecated. Use {new_enum.__qualname__} instead.", - DeprecationWarning, - stacklevel=2, - ) - return getattr(new_enum, name) - - def __dir__(self): - return dir(new_enum) - - return Wrapper() - - return decorator - - class DynamicMeta(type): def __hash__(cls): return hash((cls.__module__, cls.__qualname__)) @@ -2533,118 +2502,3 @@ class SubstrateType(IntEnumProps): SubstrateReference = 10 """Substrate reference — named reference substrate used by transmission-line models.""" - - -# ########################## Deprecated enumeration classes ############################# - -# TODO: Remove these classes in v1.0.0. - - -@deprecate_enum(InfiniteSphereType) -class INFINITE_SPHERE_TYPE: - """Deprecated: Use `InfiniteSphereType` instead.""" - - -@deprecate_enum(Fillet) -class FILLET: - """Deprecated: Use `Fillet` instead.""" - - -@deprecate_enum(Axis) -class AXIS: - """Deprecated: Use `Axis` instead.""" - - -@deprecate_enum(Plane) -class PLANE: - """Deprecated: Use `Plane` instead.""" - - -@deprecate_enum(Gravity) -class GRAVITY: - """Deprecated: Use `Gravity` instead.""" - - -@deprecate_enum(View) -class VIEW: - """Deprecated: Use `View` instead.""" - - -@deprecate_enum(GlobalCS) -class GLOBALCS: - """Deprecated: Use `GlobalCS` instead.""" - - -@deprecate_enum(MatrixOperationsQ3D) -class MATRIXOPERATIONSQ3D: - """Deprecated: Use `MatricOperationsQ3D` instead.""" - - -@deprecate_enum(MatrixOperationsQ2D) -class MATRIXOPERATIONSQ2D: - """Deprecated: Use `MatricOperationsQ2D` instead.""" - - -class CATEGORIESQ3D: - """Deprecated: Use `PlotCategoriesQ3D` or `PlotCategoriesQ2D` instead.""" - - @deprecate_enum(PlotCategoriesQ2D) - class Q2D: - """Deprecated: Use `PlotCategoriesQ2D` instead.""" - - @deprecate_enum(PlotCategoriesQ3D) - class Q3D: - """Deprecated: Use `PlotCategoriesQ3D` instead.""" - - -@deprecate_enum(CSMode) -class CSMODE: - """Deprecated: Use `CSMode` instead.""" - - -@deprecate_enum(SegmentType) -class SEGMENTTYPE: - """Deprecated: Use `SegmentType` instead.""" - - -@deprecate_enum(CrossSection) -class CROSSSECTION: - """Deprecated: Use `CrossSection` instead.""" - - -@deprecate_enum(SweepDraft) -class SWEEPDRAFT: - """Deprecated: Use `SweepDraft` instead.""" - - -class SOLUTIONS: - """Deprecated.""" - - @deprecate_enum(SolutionsHfss) - class Hfss: - """Deprecated: Use `SolutionsHfss` instead.""" - - @deprecate_enum(SolutionsMaxwell3D) - class Maxwell3d: - """Deprecated: Use `SolutionsMaxwell3d` instead.""" - - @deprecate_enum(SolutionsMaxwell2D) - class Maxwell2d: - """Deprecated: Use `SolutionsMaxwell2d` instead.""" - - @deprecate_enum(SolutionsIcepak) - class Icepak: - """Deprecated: Use `SolutionsIcepak` instead.""" - - @deprecate_enum(SolutionsCircuit) - class Circuit: - """Deprecated: Use `SolutionsCircuit` instead.""" - - @deprecate_enum(SolutionsMechanical) - class Mechanical: - """Deprecated: Use `SolutionsMechanical` instead.""" - - -@deprecate_enum(Setups) -class SETUPS: - """Deprecated: Use `Setups` instead.""" diff --git a/src/ansys/aedt/core/generic/file_utils.py b/src/ansys/aedt/core/generic/file_utils.py index 01e734e8bf87..cfa7fafe9c9a 100644 --- a/src/ansys/aedt/core/generic/file_utils.py +++ b/src/ansys/aedt/core/generic/file_utils.py @@ -700,9 +700,11 @@ def parse_excitation_file( try: import pandas - except ImportError: # pragma: no cover - pyaedt_logger.error("Pandas is not available. Install it.") - return False + except ImportError as e: # pragma: no cover + from ansys.aedt.core.internal.checks import install_message + + msg = install_message("pandas", "all", level="module") + raise ImportError(msg) from e input_file = Path(input_file) df = read_csv_pandas(input_file, encoding=encoding) diff --git a/src/ansys/aedt/core/hfss.py b/src/ansys/aedt/core/hfss.py index 809e01fd12a5..4293310af145 100644 --- a/src/ansys/aedt/core/hfss.py +++ b/src/ansys/aedt/core/hfss.py @@ -214,15 +214,15 @@ def __init__( design: str | None = None, solution_type: str | None = None, setup: str | None = None, - version: str | None = None, - non_graphical: bool | None = False, - new_desktop: bool | None = False, - close_on_exit: bool | None = False, - student_version: bool | None = False, - machine: str | None = "", - port: int | None = 0, + version: str | int | None = None, + non_graphical: bool = False, + new_desktop: bool = False, + close_on_exit: bool = False, + student_version: bool = False, + machine: str = "", + port: int = 0, aedt_process_id: int | None = None, - remove_lock: bool | None = False, + remove_lock: bool = False, ) -> None: FieldAnalysis3D.__init__( self, @@ -252,7 +252,6 @@ def _init_from_design(self, *args, **kwargs) -> None: self.__init__(*args, **kwargs) @pyaedt_function_handler - # NOTE: Extend Mixin behaviour to handle near field setups def _create_boundary(self, name: str, props, boundary_type) -> "NearFieldSetup | BoundaryObject": # No-near field cases if boundary_type not in ( @@ -376,7 +375,7 @@ def table_names(self): return table_names @pyaedt_function_handler() - def set_auto_open(self, enable: bool | None = True, opening_type: str | None = "Radiation"): + def set_auto_open(self, enable: bool | None = True, opening_type: str | None = "Radiation") -> bool: """Set the HFSS auto open type. Parameters @@ -390,7 +389,7 @@ def set_auto_open(self, enable: bool | None = True, opening_type: str | None = " Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. Examples -------- @@ -463,7 +462,7 @@ def _create_port_terminal( iswaveport: bool = False, impedance: float | None = None, terminals_rename: bool = True, - ) -> NearFieldSetup: + ) -> BoundaryObject: ref_conductors = self.modeler.convert_to_selections(int_line_stop, True) props = {} props["Faces"] = int(assignment) @@ -561,7 +560,7 @@ def _create_port_terminal( @pyaedt_function_handler() def _create_circuit_port( self, assignment: str | list, impedance, name: str, renorm, deemb, renorm_impedance: str = "" - ) -> NearFieldSetup: + ) -> BoundaryObject: edgelist = self.modeler.convert_to_selections(assignment, True) props = dict( { @@ -597,7 +596,7 @@ def _create_waveport_driven( nummodes: int = 1, deemb_distance: int = 0, characteristic_impedance: str = "Zpi", - ): + ) -> BoundaryObject: if not int_line_start or not int_line_stop: int_line_start = [] int_line_stop = [] @@ -1656,7 +1655,7 @@ def assign_radiation_boundary_to_faces(self, assignment: str | list, name: str | @pyaedt_function_handler() def create_setup( self, name: str = "MySetupAuto", setup_type: str | None = None, **kwargs - ) -> "SetupHFSS" | "SetupHFSSAuto": + ) -> "SetupHFSS | SetupHFSSAuto": """Create an analysis setup for HFSS. Optional arguments are passed along with ``setup_type`` and ``name``. Keyword @@ -1738,7 +1737,7 @@ def create_linear_count_sweep( sweep_type: str = "Discrete", interpolation_tol: float = 0.5, interpolation_max_solutions: int = 250, - ) -> "SweepHFSS" | bool: + ) -> "SweepHFSS": """Create a sweep with a specified number of points. Parameters @@ -1774,8 +1773,8 @@ def create_linear_count_sweep( Returns ------- - :class:`ansys.aedt.core.modules.solve_sweeps.SweepHFSS` or bool - Sweep object if successful, ``False`` otherwise. + :class:`ansys.aedt.core.modules.solve_sweeps.SweepHFSS` + Sweep object if successful. References ---------- @@ -1842,7 +1841,7 @@ def create_linear_count_sweep( sweepdata.update() self.logger.info(f"Linear count sweep {name} has been correctly created.") return sweepdata - return False + raise AEDTRuntimeError(f"Setup '{setup}' is not found in the design.") @pyaedt_function_handler() def create_linear_step_sweep( @@ -1856,7 +1855,7 @@ def create_linear_step_sweep( save_fields: bool = True, save_rad_fields: bool = False, sweep_type: str = "Discrete", - ) -> "SweepHFSS" | bool: + ) -> "SweepHFSS": """Create a sweep with a specified frequency step. Parameters @@ -1884,8 +1883,8 @@ def create_linear_step_sweep( Returns ------- - :class:`ansys.aedt.core.modules.solve_sweeps.SweepHFSS` or bool - Sweep object if successful, ``False`` otherwise. + :class:`ansys.aedt.core.modules.solve_sweeps.SweepHFSS` + Sweep object if successful. References ---------- @@ -1910,6 +1909,7 @@ def create_linear_step_sweep( ) if setup not in self.setup_names: raise AEDTRuntimeError(f"Unknown setup '{setup}'") + if name is None: sweep_name = generate_unique_name("Sweep") else: @@ -1927,7 +1927,7 @@ def create_linear_step_sweep( save_rad_fields=save_rad_fields, sweep_type=sweep_type, ) - return False + raise AEDTRuntimeError(f"Setup '{setup}' is not found in the design.") # pragma: no cover @pyaedt_function_handler() def create_single_point_sweep( @@ -1939,7 +1939,7 @@ def create_single_point_sweep( save_single_field: bool = True, save_fields: bool = False, save_rad_fields: bool = False, - ) -> "SweepHFSS" | bool: + ) -> "SweepHFSS": """Create a sweep with a single frequency point. Parameters @@ -1964,8 +1964,8 @@ def create_single_point_sweep( Returns ------- - :class:`ansys.aedt.core.modules.solve_sweeps.SweepHFSS` or bool - Sweep object if successful, ``False`` otherwise. + :class:`ansys.aedt.core.modules.solve_sweeps.SweepHFSS` + Sweep object if successful. References ---------- @@ -2019,7 +2019,7 @@ def create_single_point_sweep( save_fields=save_fields, save_rad_fields=save_rad_fields, ) - return False + raise AEDTRuntimeError(f"Setup '{setup}' is not found in the design.") # pragma: no cover @pyaedt_function_handler() def _create_native_component( @@ -5761,7 +5761,7 @@ def set_differential_pair( Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -5804,7 +5804,7 @@ def set_differential_pair( if len(self.oboundary.GetDiffPairs()) == num_old_pairs + 1: return True else: - return False + raise AEDTRuntimeError("Failed to create differential pair.") @pyaedt_function_handler() def create_3d_component_array( @@ -5881,7 +5881,7 @@ def get_antenna_data( link_to_hfss: bool | None = True, export_touchstone: bool | None = True, set_phase_center_per_port: bool | None = True, - ) -> "FfdSolutionDataExporter | FfdSolutionData | bool": + ) -> "FfdSolutionDataExporter | FfdSolutionData": """Export the antenna parameters to Far Field Data (FFD) files and return an instance of the ``FfdSolutionDataExporter`` object. @@ -5916,7 +5916,7 @@ def get_antenna_data( Returns ------- :class:`ansys.aedt.core.visualization.advanced.farfield_visualization.FfdSolutionDataExporter` or - :class:`ansys.aedt.core.visualization.advanced.farfield_visualization.FfdSolutionData` or bool + :class:`ansys.aedt.core.visualization.advanced.farfield_visualization.FfdSolutionData` SolutionData object or False if frequencies could not be obtained. Examples @@ -5978,8 +5978,7 @@ def get_antenna_data( frequencies = frequencies.tolist() frequencies = _units_assignment(frequencies) else: # pragma: no cover - self.logger.info("Frequencies could not be obtained.") - return False + raise AEDTRuntimeError("Frequencies could not be obtained.") frequencies = [ self.value_with_units(i, self.units.frequency, "Freq") if not isinstance(i, Quantity) else str(i) for i in frequencies @@ -6001,7 +6000,7 @@ def get_antenna_data( elif metadata_file: return FfdSolutionData(input_file=metadata_file) - raise AEDTRuntimeError("Farfield solution data could not be exported.") + raise AEDTRuntimeError("Farfield solution data could not be exported.") # pragma: no cover @pyaedt_function_handler() def get_rcs_data( @@ -6010,10 +6009,10 @@ def get_rcs_data( setup: str | None = None, expression: str | None = "ComplexMonostaticRCSTheta", variations: dict | None = None, - overwrite: bool | None = True, - link_to_hfss: bool | None = True, + overwrite: bool = True, + link_to_hfss: bool = True, variation_name: str | None = None, - ) -> "MonostaticRCSExporter | Path | bool": + ) -> "MonostaticRCSExporter | Path": """Export monostatic radar cross-section (RCS) data from HFSS. This method exports RCS simulation data into a standardized metadata format @@ -6059,10 +6058,9 @@ def get_rcs_data( Returns ------- - :class:`ansys.aedt.core.visualization.post.rcs_exporter.MonostaticRCSExporter` or pathlib.Path or bool + :class:`ansys.aedt.core.visualization.post.rcs_exporter.MonostaticRCSExporter` or pathlib.Path - If ``link_to_hfss=True``: Returns a ``MonostaticRCSExporter`` object. - If ``link_to_hfss=False``: Returns a ``Path`` object pointing to the metadata file. - - Returns ``False`` if frequencies cannot be obtained. Examples -------- @@ -6125,8 +6123,7 @@ def get_rcs_data( if rcs_data and rcs_data.primary_sweep_values is not None: frequencies = rcs_data.primary_sweep_values if len(frequencies) == 0: # pragma: no cover - self.logger.info("Frequencies could not be obtained.") - return False + raise AEDTRuntimeError("Frequencies could not be obtained.") frequencies = list(frequencies) @@ -6148,7 +6145,7 @@ def get_rcs_data( elif metadata: return metadata - raise AEDTRuntimeError("Farfield solution data could not be exported.") + raise AEDTRuntimeError("Farfield solution data could not be exported.") # pragma: no cover @pyaedt_function_handler() def set_material_threshold(self, threshold: float | None = 100000) -> bool: @@ -6257,7 +6254,6 @@ def set_impedance_multiplier(self, multiplier: float) -> bool: @pyaedt_function_handler() def set_phase_center_per_port(self, coordinate_system: list = None) -> bool: - # type: (list) -> bool """Set phase center per port. Parameters @@ -6269,7 +6265,7 @@ def set_phase_center_per_port(self, coordinate_system: list = None) -> bool: Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -6288,14 +6284,17 @@ def set_phase_center_per_port(self, coordinate_system: list = None) -> bool: port_names = self.ports[::] if not port_names: # pragma: no cover - return False + raise AEDTRuntimeError("No ports found in the design.") if not coordinate_system: coordinate_system = ["<-Port Location->"] * len(port_names) elif not isinstance(coordinate_system, list): - return False + raise TypeError("The 'coordinate_system' argument must be a list.") elif len(coordinate_system) != len(port_names): - return False + raise ValueError( + f"Length of 'coordinate_system' ({len(coordinate_system)}) " + f"must match the number of ports ({len(port_names)})." + ) cont = 0 arg = [] @@ -6305,12 +6304,12 @@ def set_phase_center_per_port(self, coordinate_system: list = None) -> bool: try: self.oboundary.SetPhaseCenterPerPort(arg) - except Exception: - return False + except Exception as e: + raise AEDTRuntimeError(f"Failed to set phase center per port: {e}") from e return True @pyaedt_function_handler() - def parse_hdm_file(self, file_name: str | Path) -> Parser | bool: + def parse_hdm_file(self, file_name: str | Path) -> Parser: """Parse an HFSS SBR+ or Creeping Waves ``hdm`` file. Parameters @@ -6320,11 +6319,12 @@ def parse_hdm_file(self, file_name: str | Path) -> Parser | bool: Returns ------- - :class:`ansys.aedt.core.modules.hdm_parser.Parser` or bool + :class:`ansys.aedt.core.modules.hdm_parser.Parser` + """ if Path(file_name).exists(): return Parser(str(file_name)).parse_message() - return False + raise FileNotFoundError(f"HDM file '{file_name}' does not exist.") @pyaedt_function_handler() def get_hdm_plotter(self, file_name: str | None = None) -> "HDMPlotter": @@ -7638,11 +7638,11 @@ def import_table( ) -> bool: """Import a data table. - The table can have multiple independent real-valued columns of data, - and multiple dependent real- or complex-valued columns of data. - The data supported is comma-delimited format (.csv). - The first row may contain column names. Complex data columns are inferred from the column data format. - In comma-delimited format, "(double, double)" denotes a complex number. + The table can have multiple independent real-valued columns of data, + and multiple dependent real- or complex-valued columns of data. + The data supported is comma-delimited format (.csv). + The first row may contain column names. Complex data columns are inferred from the column data format. + In comma-delimited format, "(double, double)" denotes a complex number. Parameters ---------- @@ -7931,7 +7931,7 @@ def _get_sd(varname: str): theta_set = set() for var in active_variations: - th = var[theta_name] + th = float(var[theta_name]) theta_set.add(th) var_index[(th, None)] = var @@ -7948,17 +7948,17 @@ def _get_sd(varname: str): phi_units = r_te.units_sweeps[phi_name] new_phi = None for var in r_te.variations: - theta = var[theta_name] - phi = var[phi_name] + theta = float(var[theta_name]) + phi = float(var[phi_name]) phi_plus_180 = np.radians(phi) + np.pi * (1 if theta >= 0 else 0) z = np.exp(1j * phi_plus_180) - new_phi = np.round(np.mod(np.angle(z, deg=True) + (360 if np.angle(z) < 0 else 0), 360), 6) + new_phi = float(np.round(np.mod(np.angle(z, deg=True) + (360 if np.angle(z) < 0 else 0), 360), 6)) if new_phi >= 0: phi_values.append(new_phi) var_index[(abs(theta), new_phi)] = var - theta_fp_round = np.round(abs(theta), 6) + theta_fp_round = float(np.round(abs(theta), 6)) key = f"{new_phi}{phi_units}" if theta_fp_round not in angles.setdefault(key, []): diff --git a/src/ansys/aedt/core/hfss3dlayout.py b/src/ansys/aedt/core/hfss3dlayout.py index 7d84a8208a12..72af60ee54bb 100644 --- a/src/ansys/aedt/core/hfss3dlayout.py +++ b/src/ansys/aedt/core/hfss3dlayout.py @@ -42,6 +42,7 @@ from ansys.aedt.core.generic.general_methods import pyaedt_function_handler from ansys.aedt.core.generic.settings import settings from ansys.aedt.core.internal.checks import min_aedt_version +from ansys.aedt.core.internal.errors import AEDTRuntimeError if TYPE_CHECKING: from pandas import DataFrame @@ -160,15 +161,15 @@ def __init__( solution_type: str | None = None, setup: str | None = None, version: str | None = None, - non_graphical: bool | None = False, - new_desktop: bool | None = False, - close_on_exit: bool | None = False, - student_version: bool | None = False, - machine: str | None = "", - port: int | None = 0, + non_graphical: bool = False, + new_desktop: bool = False, + close_on_exit: bool = False, + student_version: bool = False, + machine: str = "", + port: int = 0, aedt_process_id: int | None = None, ic_mode: bool | None = None, - remove_lock: bool | None = False, + remove_lock: bool = False, ) -> None: FieldAnalysis3DLayout.__init__( self, @@ -219,8 +220,7 @@ def create_edge_port( wave_launcher: str | None = "1mm", reference_primitive: str | None = None, reference_edge_number: str | int | None = 0, - ) -> BoundaryObject3dLayout | bool: - # type: (str | Line3dLayout,int,bool, bool,float,float, str, str, str | int) -> BoundaryObject3dLayout | bool + ) -> "BoundaryObject3dLayout": """Create an edge port. Parameters @@ -249,7 +249,7 @@ def create_edge_port( Returns ------- :class:`ansys.aedt.core.modules.boundary.layout_boundary.BoundaryObject3dLayout` - Port objcet port when successful, ``False`` when failed. + Port objcet port when successful. References ---------- @@ -315,10 +315,10 @@ def create_edge_port( if bound: self._boundaries[bound.name] = bound return bound - else: - return False - else: - return False + else: # pragma: no cover + raise AEDTRuntimeError("Failed to update port information.") + else: # pragma: no cover + raise AEDTRuntimeError("Failed to create edge port.") @pyaedt_function_handler() def create_wave_port( @@ -328,7 +328,7 @@ def create_wave_port( wave_horizontal_extension: float | None = 5, wave_vertical_extension: float | None = 3, wave_launcher: str | None = "1mm", - ) -> BoundaryObject3dLayout | bool: + ) -> "BoundaryObject3dLayout": """Create a single-ended wave port. Parameters @@ -347,33 +347,34 @@ def create_wave_port( Returns ------- - :class:`ansys.aedt.core.modules.boundary.layout_boundary.BoundaryObject3dLayout` or bool - Port object when successful, ``False`` when failed. + :class:`ansys.aedt.core.modules.boundary.layout_boundary.BoundaryObject3dLayout`. + Port objcet port when successful. References ---------- + >>> oEditor.CreateEdgePort """ - port_name = self.create_edge_port( + port_object = self.create_edge_port( assignment, edge_number, wave_horizontal_extension=wave_horizontal_extension, wave_vertical_extension=wave_vertical_extension, wave_launcher=wave_launcher, ) - if port_name: - port_name["HFSS Type"] = "Wave" - port_name["Horizontal Extent Factor"] = str(wave_horizontal_extension) - if "Vertical Extent Factor" in list(port_name.props.keys()): - port_name["Vertical Extent Factor"] = str(wave_vertical_extension) - port_name["PEC Launch Width"] = str(wave_launcher) - return port_name - else: - return False + if port_object: + port_object["HFSS Type"] = "Wave" + port_object["Horizontal Extent Factor"] = str(wave_horizontal_extension) + if "Vertical Extent Factor" in list(port_object.props.keys()): + port_object["Vertical Extent Factor"] = str(wave_vertical_extension) + port_object["PEC Launch Width"] = str(wave_launcher) + return port_object + else: # pragma: no cover + raise AEDTRuntimeError("Failed to create wave port.") @pyaedt_function_handler() def create_wave_port_from_two_conductors( self, assignment: list | None = None, edge_numbers: list | None = None - ) -> BoundaryObject3dLayout | bool: + ) -> "BoundaryObject3dLayout": """Create a wave port. Parameters @@ -391,7 +392,7 @@ def create_wave_port_from_two_conductors( Returns ------- :class:`ansys.aedt.core.modules.boundary.layout_boundary.BoundaryObject3dLayout` - Port objcet port when successful, ``False`` when failed. + Port objcet port when successful. References ---------- @@ -423,12 +424,12 @@ def create_wave_port_from_two_conductors( if bound: self._boundaries[bound.name] = bound return bound - else: - return False - else: - return False - else: - return False + else: # pragma: no cover + raise AEDTRuntimeError("Failed to update port information.") + else: # pragma: no cover + raise AEDTRuntimeError("Failed to create wave port.") + else: # pragma: no cover + raise AEDTRuntimeError("Failed to create wave port.") @pyaedt_function_handler() def dissolve_component(self, component: str) -> bool: @@ -561,7 +562,7 @@ def create_pec_on_component_by_nets( @pyaedt_function_handler() def create_differential_port( self, via_signal: str, via_reference: float, name: str, deembed: bool | None = True - ) -> BoundaryObject3dLayout | bool: + ) -> "BoundaryObject3dLayout": """Create a differential port. Parameters @@ -578,7 +579,7 @@ def create_differential_port( Returns ------- :class:`ansys.aedt.core.modules.boundary.layout_boundary.BoundaryObject3dLayout` - Port Object when successful, ``False`` when failed. + Port Object when successful. References ---------- @@ -586,8 +587,8 @@ def create_differential_port( """ listp = self.port_list if name in self.port_list: - self.logger.error(f"Port already existd on via {name}.") - return False + raise ValueError(f"Port '{name}' already exists in the design.") + self.oeditor.ToggleViaPin(["NAME:elements", via_signal]) listnew = self.port_list @@ -603,15 +604,15 @@ def create_differential_port( if bound: self._boundaries[bound.name] = bound return bound - else: - return False - else: - return False + else: # pragma: no cover + raise AEDTRuntimeError(f"Failed to update port information for '{name}'.") + else: # pragma: no cover + raise AEDTRuntimeError(f"Failed to create differential port '{name}'.") @pyaedt_function_handler() def create_coax_port( self, via: str, radial_extent: float = 0.1, layer: str = None, alignment: str | None = "lower" - ) -> BoundaryObject3dLayout | bool: + ) -> "BoundaryObject3dLayout": """Create a coax port. Parameters @@ -628,7 +629,7 @@ def create_coax_port( Returns ------- :class:`ansys.aedt.core.modules.boundary.layout_boundary.BoundaryObject3dLayout` - Port Object when successful, ``False`` when failed. + Port Object when successful. References ---------- @@ -636,8 +637,8 @@ def create_coax_port( """ listp = self.port_list if via in self.port_list: - self.logger.error(f"Port already exists on via {via}.") - return False + raise ValueError(f"Port already exists on via '{via}'.") + self.oeditor.ToggleViaPin(["NAME:elements", via]) listnew = self.port_list @@ -651,10 +652,10 @@ def create_coax_port( if bound: self._boundaries[bound.name] = bound return bound - else: - return False - else: - return False + else: # pragma: no cover + raise AEDTRuntimeError(f"Failed to update port information for via '{via}'.") + else: # pragma: no cover + raise AEDTRuntimeError(f"Failed to create coax port on via '{via}'.") @pyaedt_function_handler() def create_pin_port( @@ -665,7 +666,7 @@ def create_pin_port( rotation: float | None = 0, top_layer: str | None = None, bottom_layer: str | None = None, - ) -> BoundaryObject3dLayout | bool: + ) -> "BoundaryObject3dLayout": """Create a pin port. Parameters @@ -725,8 +726,8 @@ def create_pin_port( if bound: self._boundaries[bound.name] = bound return bound - else: - return False + else: # pragma: no cover + raise AEDTRuntimeError("Failed to create pin port.") @pyaedt_function_handler() def delete_port( @@ -1125,7 +1126,7 @@ def create_linear_count_sweep( interpolation_tol_percent: float | None = 0.5, interpolation_max_solutions: int | None = 250, use_q3d_for_dc: bool | None = False, - ) -> Union["SweepHFSS3DLayout", bool]: + ) -> "SweepHFSS3DLayout": """Create a sweep with the specified number of points. Parameters @@ -1164,8 +1165,8 @@ def create_linear_count_sweep( Returns ------- - :class:`ansys.aedt.core.modules.solve_sweeps.SweepHFSS3DLayout` or bool - Sweep object if successful, ``False`` otherwise. + :class:`ansys.aedt.core.modules.solve_sweeps.SweepHFSS3DLayout` + Sweep object if successful. References ---------- @@ -1200,8 +1201,8 @@ def create_linear_count_sweep( "Sweep %s is already present. Sweep has been renamed in %s.", oldname, sweep_name ) sweep = setupdata.add_sweep(name=sweep_name, sweep_type=sweep_type) - if not sweep: - return False + if not sweep: # pragma: no cover + raise AEDTRuntimeError(f"Failed to add sweep '{sweep_name}' to setup '{setup}'.") sweep.change_range("LinearCount", start_frequency, stop_frequency, num_of_freq_points, unit) sweep.props["GenerateSurfaceCurrent"] = save_fields sweep.props["SaveRadFieldsOnly"] = save_rad_fields_only @@ -1213,7 +1214,7 @@ def create_linear_count_sweep( sweep.update() self.logger.info("Linear count sweep %s has been correctly created.", sweep_name) return sweep - return False + raise ValueError(f"Setup '{setup}' is not found in the design.") @pyaedt_function_handler() def create_linear_step_sweep( @@ -1230,7 +1231,7 @@ def create_linear_step_sweep( interpolation_tol_percent: float | None = 0.5, interpolation_max_solutions: int | None = 250, use_q3d_for_dc: bool | None = False, - ) -> Union["SweepHFSS3DLayout", bool]: + ) -> "SweepHFSS3DLayout": """Create a sweep with the specified frequency step. Parameters @@ -1269,8 +1270,8 @@ def create_linear_step_sweep( Returns ------- - :class:`ansys.aedt.core.modules.solve_sweeps.SweepHFSS3DLayout` or bool - Sweep object if successful, ``False`` otherwise. + :class:`ansys.aedt.core.modules.solve_sweeps.SweepHFSS3DLayout` + Sweep object if successful. References ---------- @@ -1305,8 +1306,8 @@ def create_linear_step_sweep( "Sweep %s is already present. Sweep has been renamed in %s.", oldname, sweep_name ) sweep = setupdata.add_sweep(name=sweep_name, sweep_type=sweep_type) - if not sweep: - return False + if not sweep: # pragma: no cover + raise AEDTRuntimeError(f"Failed to add sweep '{sweep_name}' to setup '{setup}'.") sweep.change_range("LinearStep", start_frequency, stop_frequency, step_size, unit) sweep.props["GenerateSurfaceCurrent"] = save_fields sweep.props["SaveRadFieldsOnly"] = save_rad_fields_only @@ -1318,7 +1319,7 @@ def create_linear_step_sweep( sweep.update() self.logger.info("Linear step sweep %s has been correctly created.", sweep_name) return sweep - return False + raise ValueError(f"Setup '{setup}' is not found in the design.") @pyaedt_function_handler() def create_single_point_sweep( @@ -1329,7 +1330,7 @@ def create_single_point_sweep( name: str | None = None, save_fields: bool | None = False, save_rad_fields_only: bool | None = False, - ) -> Union["SweepHFSS", bool]: + ) -> "SweepHFSS": """Create a sweep with a single frequency point. Parameters @@ -1350,8 +1351,8 @@ def create_single_point_sweep( Returns ------- - :class:`ansys.aedt.core.modules.solve_sweeps.SweepHFSS` or bool - Sweep object if successful, ``False`` otherwise. + :class:`ansys.aedt.core.modules.solve_sweeps.SweepHFSS` + Sweep object if successful. References ---------- @@ -1373,7 +1374,8 @@ def create_single_point_sweep( freq0 = freq if setup not in self.setup_names: - return False + raise ValueError(f"Setup '{setup}' is not found in the design.") + for s in self.setups: if s.name == setup: setupdata = s @@ -1393,7 +1395,7 @@ def create_single_point_sweep( sweepdata.add_subrange(range_type="SinglePoint", start=f, unit=unit) self.logger.info("Single point sweep %s has been correctly created.", sweep_name) return sweepdata - return False + raise AEDTRuntimeError(f"Failed to add sweep '{sweep_name}' to setup '{setup}'.") # pragma: no cover @pyaedt_function_handler() def _import_cad( @@ -1421,7 +1423,10 @@ def _import_cad( elif cad_format == "odb++": method = self.oimport_export.ImportODB if not method: - return False + raise ValueError( + f"Invalid CAD format '{cad_format}'. " + f"Available formats are: 'gds', 'dxf', 'gerber', 'awr', 'brd', 'ipc2581', 'odb++'." + ) active_project = self.project_name if not aedb_path: aedb_path = str(Path(cad_path).with_suffix(".aedb")) @@ -1454,8 +1459,8 @@ def import_gds( input_file: str, output_dir: str | None = None, control_file: str | None = None, - set_as_active: bool | None = True, - close_active_project: bool | None = False, + set_as_active: bool = True, + close_active_project: bool = False, ) -> bool: """Import a GDS file into HFSS 3D Layout and assign the stackup from an XML file if present. @@ -1479,7 +1484,7 @@ def import_gds( Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -1493,8 +1498,8 @@ def import_dxf( input_file: str, output_dir: str | None = None, control_file: str | None = None, - set_as_active: bool | None = True, - close_active_project: bool | None = False, + set_as_active: bool = True, + close_active_project: bool = False, ) -> bool: """Import a DXF file into HFSS 3D Layout and assign the stackup from an XML file if present. @@ -1518,7 +1523,7 @@ def import_dxf( Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -1532,8 +1537,8 @@ def import_gerber( input_file: str, output_dir: str | None = None, control_file: str | None = None, - set_as_active: bool | None = True, - close_active_project: bool | None = False, + set_as_active: bool = True, + close_active_project: bool = False, ) -> bool: """Import a Gerber zip file into HFSS 3D Layout and assign the stackup from an XML file if present. @@ -1555,7 +1560,7 @@ def import_gerber( Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -1568,9 +1573,9 @@ def import_brd( self, input_file: str, output_dir: str | None = None, - set_as_active: bool | None = True, - close_active_project: bool | None = False, control_file: str | None = None, + set_as_active: bool = True, + close_active_project: bool = False, ) -> bool: # pragma: no cover """Import a board file into HFSS 3D Layout and assign the stackup from an XML file if present. @@ -1580,19 +1585,19 @@ def import_brd( Full path to the board file. output_dir : str, optional Full path to the AEDB folder. For example, ``"c:\\temp\\test.aedb"``. + control_file : str, optional + Path to the XML file with the stackup information. The default is ``None``, in + which case the stackup is not edited. set_as_active : bool, optional Whether to set the board file as active. The default is ``True``. close_active_project : bool, optional Whether to close the active project after loading the board file. The default is ''False``. - control_file : str, optional - Path to the XML file with the stackup information. The default is ``None``, in - which case the stackup is not edited. Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -1606,8 +1611,8 @@ def import_awr( input_file: str, output_dir: str | None = None, control_file: str | None = None, - set_as_active: bool | None = True, - close_active_project: bool | None = False, + set_as_active: bool = True, + close_active_project: bool = False, ) -> bool: # pragma: no cover """Import an AWR Microwave Office file into HFSS 3D Layout and assign the stackup from an XML file if present. @@ -1629,7 +1634,7 @@ def import_awr( Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -1643,8 +1648,8 @@ def import_ipc2581( input_file: str, output_dir: str | None = None, control_file: str | None = None, - set_as_active: bool | None = True, - close_active_project: bool | None = False, + set_as_active: bool = True, + close_active_project: bool = False, ) -> bool: """Import an IPC2581 file into HFSS 3D Layout and assign the stackup from an XML file if present. @@ -1666,7 +1671,7 @@ def import_ipc2581( Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -1680,8 +1685,8 @@ def import_odb( input_file: str, output_dir: str | None = None, control_file: str | None = None, - set_as_active: bool | None = True, - close_active_project: bool | None = False, + set_as_active: bool = True, + close_active_project: bool = False, ) -> bool: """Import an ODB++ file into HFSS 3D Layout and assign the stackup from an XML file if present. @@ -1703,7 +1708,7 @@ def import_odb( Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -1754,7 +1759,7 @@ def edit_cosim_options( Returns ------- bool - ``True`` if successful and ``False`` if failed. + ``True`` if successful. References ---------- @@ -1778,8 +1783,10 @@ def edit_cosim_options( """ if interpolation_algorithm not in ["auto", "lin", "shadH", "shadNH"]: - self.logger.error("Wrong Interpolation Algorithm") - return False + raise ValueError( + f"Invalid interpolation algorithm '{interpolation_algorithm}'. " + f"Available options are: 'auto', 'lin', 'shadH', 'shadNH'." + ) arg = ["NAME:CoSimOptions", "Override:="] if setup_override_name: @@ -1856,7 +1863,7 @@ def set_differential_pair( Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -1929,12 +1936,11 @@ def set_differential_pair( try: self.oexcitation.SetDiffPairs(arg) except Exception: # pragma: no cover - return False + raise AEDTRuntimeError("Failed to set differential pair.") return True @pyaedt_function_handler() def get_differential_pairs(self) -> list: - # type: () -> list """Get the list defined differential pairs. Returns @@ -1968,7 +1974,6 @@ def get_differential_pairs(self) -> list: @pyaedt_function_handler() def load_diff_pairs_from_file(self, input_file: str | Path) -> bool: - # type: (str) -> bool """Load differential pairs definition from a file. You can use the ``save_diff_pairs_to_file`` method to obtain the file format. @@ -2003,12 +2008,11 @@ def load_diff_pairs_from_file(self, input_file: str | Path) -> bool: self.oexcitation.LoadDiffPairsFromFile(str(new_file)) new_file.unlink() except Exception: # pragma: no cover - return False + raise AEDTRuntimeError("Failed to load differential pairs.") return True @pyaedt_function_handler() def save_diff_pairs_to_file(self, output_file: str) -> bool: - # type: (str) -> bool """Save differtential pairs definition to a file. If a file with the specified name already exists, it is overwritten. @@ -2338,8 +2342,7 @@ def find_scale(data, header_line): ) self.logger.info("Source Excitation updated with Dataset.") return True - self.logger.error("Port not found.") - return False + raise AEDTRuntimeError("Failed to edit source from file. Port not found.") # pragma: no cover @pyaedt_function_handler() def get_dcir_solution_data( @@ -2365,17 +2368,20 @@ def get_dcir_solution_data( Returns ------- - from ansys.aedt.core.modules.solutions.SolutionData + :class:`ansys.aedt.core.modules.solutions.SolutionData` + """ all_categories = self.post.available_quantities_categories(context=show, is_siwave_dc=True) if category not in all_categories: - return False # pragma: no cover + raise ValueError( + f"Category '{category}' is not available for element type '{show}'. " + f"Available categories are: {all_categories}." + ) all_quantities = self.post.available_report_quantities( context=show, is_siwave_dc=True, quantities_category=category ) - if not all_quantities: - self._logger.error("No expressions found.") - return False + if not all_quantities: # pragma: no cover + raise AEDTRuntimeError(f"No expressions found for category '{category}' with element type '{show}'.") return self.post.get_solution_data(all_quantities, setup_sweep_name=setup, domain="DCIR", context=show) @pyaedt_function_handler() @@ -2504,7 +2510,8 @@ def show_extent(self, show: bool | None = True) -> bool: Returns ------- bool - ``True`` is successful, ``False`` if it fails. + ``True`` if successful. + >>> oEditor.SetHfssExtentsVisible @@ -2517,8 +2524,8 @@ def show_extent(self, show: bool | None = True) -> bool: try: self.oeditor.SetHfssExtentsVisible(show) return True - except Exception: - return False + except Exception as e: + raise AEDTRuntimeError(f"Failed to set extent visibility: {e}") from e @pyaedt_function_handler() def change_options(self, color_by_net: bool | None = True) -> bool: @@ -2535,7 +2542,7 @@ def change_options(self, color_by_net: bool | None = True) -> bool: Returns ------- bool - ``True`` if successful, ``False`` if it fails. + ``True`` if successful. >>> oEditor.ChangeOptions @@ -2550,8 +2557,8 @@ def change_options(self, color_by_net: bool | None = True) -> bool: oeditor = self.odesign.SetActiveEditor("Layout") oeditor.ChangeOptions(options) return True - except Exception: - return False + except Exception as e: + raise AEDTRuntimeError(f"Failed to change options: {e}") from e @pyaedt_function_handler() def export_touchstone_on_completion(self, export: bool | None = True, output_dir: str | None = None) -> bool: @@ -2595,7 +2602,7 @@ def import_table( sweep_columns: int | None = 0, total_columns: int | None = -1, real_columns: int | None = 1, - ) -> bool | str: + ) -> str: """Import a data table as a solution. Parameters @@ -2624,7 +2631,7 @@ def import_table( Returns ------- str - ``True`` when successful, ``False`` when failed. + Name of the imported sweep when successful. References ---------- @@ -2637,15 +2644,16 @@ def import_table( >>> h3d.import_table(input_file="my_file.csv") """ columns_separator_map = {"Space": 0, "Tab": 1, "Comma": 2, "Period": 3} - if column_separator not in ["Space", "Tab", "Comma", "Period"]: - self.logger.error("Invalid column separator.") - return False + if column_separator not in columns_separator_map: + raise ValueError( + f"Invalid column separator '{column_separator}'. " + f"Available options are: {', '.join(columns_separator_map)}." + ) input_path = Path(input_file).resolve() if not input_path.is_file(): - self.logger.error("File does not exist.") - return False + raise FileNotFoundError(f"Input file '{input_path}' does not exist.") existing_sweeps = self.existing_analysis_sweeps @@ -2678,8 +2686,7 @@ def import_table( new_sweep = list(set(new_sweeps) - set(existing_sweeps)) if not new_sweep: # pragma: no cover - self.logger.error("Data not imported.") - return False + raise AEDTRuntimeError("Data not imported.") return new_sweep[0] @pyaedt_function_handler() @@ -2694,7 +2701,7 @@ def delete_imported_data(self, name: str) -> bool: Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -2708,7 +2715,6 @@ def delete_imported_data(self, name: str) -> bool: >>> h3d.delete_imported_data(table_name) """ if name not in self.existing_analysis_sweeps: - self.logger.error("Data does not exist.") - return False + raise ValueError(f"Data '{name}' does not exist in the design.") self.odesign.RemoveImportData(name) return True diff --git a/src/ansys/aedt/core/icepak.py b/src/ansys/aedt/core/icepak.py index 5908f09cf9fe..6284fd3ad495 100644 --- a/src/ansys/aedt/core/icepak.py +++ b/src/ansys/aedt/core/icepak.py @@ -176,14 +176,14 @@ def __init__( solution_type: str | None = None, setup: str | None = None, version: str | None = None, - non_graphical: bool | None = False, - new_desktop: bool | None = False, - close_on_exit: bool | None = False, - student_version: bool | None = False, - machine: str | None = "", - port: int | None = 0, + non_graphical: bool = False, + new_desktop: bool = False, + close_on_exit: bool = False, + student_version: bool = False, + machine: str = "", + port: int = 0, aedt_process_id: int | None = None, - remove_lock: bool | None = False, + remove_lock: bool = False, ) -> None: FieldAnalysisIcepak.__init__( self, @@ -349,7 +349,7 @@ def assign_2way_coupling( self, setup: str | None = None, number_of_iterations: int | None = 2, - continue_ipk_iterations: bool | None = True, + continue_ipk_iterations: bool = True, ipk_iterations_per_coupling: int | None = 20, ) -> bool: """Assign two-way coupling to a setup. @@ -368,7 +368,7 @@ def assign_2way_coupling( Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -403,7 +403,7 @@ def assign_2way_coupling( def create_source_blocks_from_list( self, list_powers: list, - assign_material: bool | None = True, + assign_material: bool = True, default_material: str | None = "Ceramic_material", ): """Assign to a box in Icepak the sources that come from the CSV file. @@ -664,7 +664,7 @@ def find_top(self, gravity_dir: int) -> float: def create_parametric_heatsink_on_face( self, top_face: FacePrimitive, - relative: bool | None = True, + relative: bool = True, hs_basethick: float | None = 0.1, fin_thick: float | None = 0.05, fin_length: float | None = 0.25, @@ -673,7 +673,7 @@ def create_parametric_heatsink_on_face( pattern_angle: int | None = 10, separation: float | None = 0.05, column_separation: float | None = 0.05, - symmetric: bool | None = True, + symmetric: bool = True, symmetric_separation: float | None = 0.05, numcolumn_perside: int | None = 2, material: str | None = "Al-Extruded", @@ -991,18 +991,18 @@ def edit_design_settings( self, gravity_dir: int | None = 0, ambient_temperature: float | str | BoundaryDictionary | dict = 20, - perform_validation: bool | None = False, + perform_validation: bool = False, check_level: str | None = "None", default_fluid: str | None = "air", default_solid: str | None = "Al-Extruded", default_surface: str | None = "Steel-oxidised-surface", - export_monitor: bool | None = False, - export_sherlock: bool | None = False, + export_monitor: bool = False, + export_sherlock: bool = False, export_directory: str | None = os.getcwd(), gauge_pressure: int | None = 0, radiation_temperature: int | None = 20, - ignore_unclassified_objects: bool | None = False, - skip_intersection_checks: bool | None = False, + ignore_unclassified_objects: bool = False, + skip_intersection_checks: bool = False, ) -> bool: """Update the main settings of the design. @@ -1132,10 +1132,10 @@ def assign_em_losses( name: str | None = None, surface_objects: list[str | int] | None = None, parameters: list[str] | dict[str, str] | None = None, - force_source_solve: bool | None = True, - preserve_source_solution: bool | None = True, + force_source_solve: bool = True, + preserve_source_solution: bool = True, loss_multiplier: float | PieceWiseLinearDictionary | None = 1.0, - harmonic_loss_sweep_coupling: bool | None = False, + harmonic_loss_sweep_coupling: bool = False, q3d_loss_type: Literal["DCVolOrACSurfLoss", "ContactResistanceLoss", "HarmonicLoss"] = "DCVolOrACSurfLoss", ) -> BoundaryObject: """ @@ -1606,7 +1606,7 @@ def get_link_data(self, links_data: list, **kwargs) -> list: def create_fan( self, name: str | None = None, - is_2d: bool | None = False, + is_2d: bool = False, shape: str | None = "Circular", cross_section: str | None = "XY", radius: str | float | None = "0.008mm", @@ -1727,7 +1727,7 @@ def create_fan( if origin: self.modeler.move(new_name, origin) return native - return False + raise AEDTRuntimeError("Fan creation failed.") # pragma: no cover @pyaedt_function_handler() def create_ipk_3dcomponent_pcb( @@ -1863,7 +1863,7 @@ def create_ipk_3dcomponent_pcb( if outline_polygon: native.set_board_extents("Polygon", outline_polygon) return native - return False + raise AEDTRuntimeError("PCB creation failed.") # pragma: no cover @pyaedt_function_handler() def create_pcb_from_3dlayout( @@ -1874,13 +1874,12 @@ def create_pcb_from_3dlayout( resolution: int | None = 2, extent_type: str | None = "Bounding Box", outline_polygon: str | None = "", - close_linked_project_after_import: bool | None = True, + close_linked_project_after_import: bool = True, custom_x_resolution: int | None = None, custom_y_resolution: int | None = None, power_in: float | None = 0, - rad: str | None = "Nothing", **kwargs, # fmt: skip - ) -> bool: + ) -> NativeComponentPCB: """Create a PCB component in Icepak that is linked to an HFSS 3DLayout object linking only to the geometry file. .. note:: @@ -1909,20 +1908,11 @@ def create_pcb_from_3dlayout( The default is ``None``. power_in : float, optional Power in Watt. - rad : str, optional - Radiating faces. Options are: - - * ``"Nothing"`` - * ``"Low"`` - * ``"High"`` - * ``"Both"`` - - The default is ``"Nothing"``. Returns ------- - bool - ``True`` when successful, ``False`` when failed. + :class:`ansys.aedt.core.modules.boundary.layout_boundary.NativeComponentPCB` + NativeComponentObject object. References ---------- @@ -2006,10 +1996,10 @@ def globalMeshSettings( self, meshtype: int, gap_min_elements: str | None = "1", - noOgrids: bool | None = False, - MLM_en: bool | None = True, + noOgrids: bool = False, + MLM_en: bool = True, MLM_Type: str | None = "3D", - stairStep_en: bool | None = False, + stairStep_en: bool = False, edge_min_elements: str | None = "1", object: str | None = "Region", ) -> bool: @@ -2390,9 +2380,9 @@ def import_idf( filter_ind: bool = False, filter_res: bool = False, filter_height_under: float | None = None, - filter_height_exclude_2d: bool | None = False, + filter_height_exclude_2d: bool = False, power_under: float | None = None, - create_filtered_as_non_model: bool | None = False, + create_filtered_as_non_model: bool = False, high_surface_thick: str | None = "0.07mm", low_surface_thick: str | None = "0.07mm", internal_thick: str | None = "0.07mm", @@ -2402,9 +2392,9 @@ def import_idf( internal_layer_coverage: int | None = 30, trace_material: str | None = "Cu-Pure", substrate_material: str | None = "FR-4", - create_board: bool | None = True, - model_board_as_rect: bool | None = False, - model_device_as_rect: bool | None = True, + create_board: bool = True, + model_board_as_rect: bool = False, + model_device_as_rect: bool = True, cutoff_height: str | None = "5mm", component_lib: str | None = "", ) -> bool: @@ -2686,9 +2676,9 @@ def assign_stationary_wall( temperature: str | float | None = "0cel", ref_temperature: str | float | None = "AmbientTemp", material: str | None = "Al-Extruded", # relevant if th>0 - radiate: bool | None = False, + radiate: bool = False, radiate_surf_mat: str = "Steel-oxidised-surface", # relevant if radiate = False - ht_correlation: bool | None = False, + ht_correlation: bool = False, ht_correlation_type: str | None = "Natural Convection", ht_correlation_fluid: str | None = "air", ht_correlation_flow_type: str | None = "Turbulent", @@ -2697,8 +2687,8 @@ def assign_stationary_wall( ht_correlation_free_stream_velocity: str | float | None = "1m_per_sec", ht_correlation_surface: str | None = "Vertical", # Top, Bottom, Vertical ht_correlation_amb_temperature: str | float | None = "AmbientTemp", - shell_conduction: bool | None = False, - ext_surf_rad: bool | None = False, + shell_conduction: bool = False, + ext_surf_rad: bool = False, ext_surf_rad_material: str | None = "Stainless-steel-cleaned", ext_surf_rad_ref_temp: str | float | dict | BoundaryDictionary | None = "AmbientTemp", ext_surf_rad_view_factor: str | float | None = "1", @@ -2912,9 +2902,9 @@ def assign_stationary_wall_with_heat_flux( heat_flux: str | float | dict | BoundaryDictionary | None = "0irrad_W_per_m2", thickness: str | float | None = "0mm", material: str | None = "Al-Extruded", - radiate: bool | None = False, + radiate: bool = False, radiate_surf_mat: str | None = "Steel-oxidised-surface", - shell_conduction: bool | None = False, + shell_conduction: bool = False, ) -> BoundaryObject: """Assign a surface wall boundary condition with specified heat flux. @@ -2973,9 +2963,9 @@ def assign_stationary_wall_with_temperature( temperature: str | float | dict | BoundaryDictionary | None = "0cel", thickness: str | float | None = "0mm", material: str | None = "Al-Extruded", - radiate: bool | None = False, + radiate: bool = False, radiate_surf_mat: str | None = "Steel-oxidised-surface", - shell_conduction: bool | None = False, + shell_conduction: bool = False, ) -> BoundaryObject: """Assign a surface wall boundary condition with specified temperature. @@ -3036,7 +3026,7 @@ def assign_stationary_wall_with_htc( material: str | None = "Al-Extruded", htc: str | float | dict | BoundaryDictionary | None = "0w_per_m2kel", ref_temperature: str | float | None = "AmbientTemp", - ht_correlation: bool | None = False, + ht_correlation: bool = False, ht_correlation_type: str | None = "Natural Convection", ht_correlation_fluid: str | None = "air", ht_correlation_flow_type: str | None = "Turbulent", @@ -3045,13 +3035,13 @@ def assign_stationary_wall_with_htc( ht_correlation_free_stream_velocity: str | float | None = "1m_per_sec", ht_correlation_surface: str | None = "Vertical", ht_correlation_amb_temperature: str | float | None = "AmbientTemp", - ext_surf_rad: bool | None = False, + ext_surf_rad: bool = False, ext_surf_rad_material: str | None = "Stainless-steel-cleaned", ext_surf_rad_ref_temp: str | float | dict | BoundaryDictionary | None = "AmbientTemp", ext_surf_rad_view_factor: str | float | None = "1", - radiate: bool | None = False, + radiate: bool = False, radiate_surf_mat: str | None = "Steel-oxidised-surface", - shell_conduction: bool | None = False, + shell_conduction: bool = False, ) -> BoundaryObject: """Assign a surface wall boundary condition with a given heat transfer coefficient. @@ -3259,8 +3249,8 @@ def assign_source( thermal_condition: str, assignment_value: str | dict | BoundaryDictionary, boundary_name: str | None = None, - radiate: bool | None = False, - voltage_current_choice: str | bool | None = False, + radiate: bool = False, + voltage_current_choice: str | bool = False, voltage_current_value: str | dict | BoundaryDictionary | None = None, ) -> BoundaryObject: """Create a source power for a face. @@ -3372,7 +3362,7 @@ def assign_source( @pyaedt_function_handler() def create_network_object( - self, name: str | None = None, props: dict | None = None, create: bool | None = False + self, name: str | None = None, props: dict | None = None, create: bool = False ) -> NetworkObject: """Create a thermal network. @@ -3790,7 +3780,7 @@ def assign_free_opening( no_reverse_flow: bool = False, velocity: list | None = None, mass_flow_rate: str | float | dict | BoundaryDictionary | None = "0kg_per_s", - inflow: bool | None = True, + inflow: bool = True, direction_vector: list | None = None, ) -> BoundaryObject | None: """Assign free opening boundary condition. @@ -3949,7 +3939,7 @@ def assign_pressure_free_opening( temperature: str | float | dict | BoundaryDictionary | None = "AmbientTemp", radiation_temperature: str | float | None = "AmbientRadTemp", pressure: str | float | dict | BoundaryDictionary | None = "AmbientPressure", - no_reverse_flow: bool | None = False, + no_reverse_flow: bool = False, ) -> BoundaryObject | None: """ Assign free opening boundary condition. @@ -4093,7 +4083,7 @@ def assign_mass_flow_free_opening( radiation_temperature: str | float | None = "AmbientRadTemp", pressure: str | float | dict | BoundaryDictionary | None = "AmbientPressure", mass_flow_rate: str | float | dict | BoundaryDictionary | None = "0kg_per_s", - inflow: bool | None = True, + inflow: bool = True, direction_vector: list | None = None, ) -> BoundaryObject | None: """ @@ -4290,7 +4280,7 @@ def assign_resistance( boundary_name: str | None = None, total_power: str | float | dict | BoundaryDictionary | None = "0W", fluid: str | None = "air", - laminar: bool | None = False, + laminar: bool = False, loss_type: str | None = "Device", linear_loss: list[float] | list[str] | None = ["1m_per_sec", "1m_per_sec", "1m_per_sec"], quadratic_loss: list[float] | list[str] | None = [1, 1, 1], @@ -4460,7 +4450,7 @@ def assign_power_law_resistance( boundary_name: str | None = None, total_power: str | float | dict | BoundaryDictionary | None = "0W", fluid: str | None = "air", - laminar: bool | None = False, + laminar: bool = False, power_law_constant: str | float | None = 1, power_law_exponent: str | float | None = 1, ) -> BoundaryObject | None: @@ -4526,7 +4516,7 @@ def assign_loss_curve_resistance( boundary_name: str | None = None, total_power: str | float | dict | BoundaryDictionary | None = "0W", fluid: str | None = "air", - laminar: bool | None = False, + laminar: bool = False, loss_curves_x: list[list[float]] | None = [[0, 1], [0, 1]], loss_curves_y: list[list[float]] | None = [[0, 1], [0, 1]], loss_curves_z: list[list[float]] | None = [[0, 1], [0, 1]], @@ -4616,7 +4606,7 @@ def assign_device_resistance( boundary_name: str | None = None, total_power: str | float | dict | BoundaryDictionary | None = "0W", fluid: str | None = "air", - laminar: bool | None = False, + laminar: bool = False, linear_loss: list[str] | list[float] = ["1m_per_sec", "1m_per_sec", "1m_per_sec"], quadratic_loss: list[str] | list[float] = [1, 1, 1], linear_loss_free_area_ratio: list[str] | list[float] = [1, 1, 1], @@ -5063,7 +5053,7 @@ def assign_conducting_plate( thickness: str | float | None = "1mm", solid_material: str | None = "Al-Extruded", conductance: str | float | None = "0W_per_Cel", - shell_conduction: bool | None = False, + shell_conduction: bool = False, thermal_resistance: str | float | None = "0Kel_per_W", low_side_rad_material: str | None = None, high_side_rad_material: str | None = None, @@ -5180,7 +5170,7 @@ def assign_conducting_plate_with_thickness( total_power: str | float | dict | BoundaryDictionary | None = "0W", thickness: str | float | None = "1mm", solid_material: str | None = "Al-Extruded", - shell_conduction: bool | None = False, + shell_conduction: bool = False, low_side_rad_material: str | None = None, high_side_rad_material: str | None = None, ) -> BoundaryObject | None: @@ -5240,7 +5230,7 @@ def assign_conducting_plate_with_resistance( boundary_name: str | None = None, total_power: str | float | dict | BoundaryDictionary | None = "0W", thermal_resistance: str | float | None = "0Kel_per_W", - shell_conduction: bool | None = False, + shell_conduction: bool = False, low_side_rad_material: str | None = None, high_side_rad_material: str | None = None, ) -> BoundaryObject | None: @@ -5296,7 +5286,7 @@ def assign_conducting_plate_with_impedance( boundary_name: str | None = None, total_power: str | float | dict | BoundaryDictionary | None = "0W", thermal_impedance: str | float | None = "0celm2_per_W", - shell_conduction: bool | None = False, + shell_conduction: bool = False, low_side_rad_material: str | None = None, high_side_rad_material: str | None = None, ) -> BoundaryObject | None: @@ -5352,7 +5342,7 @@ def assign_conducting_plate_with_conductance( boundary_name: str | None = None, total_power: str | float | dict | BoundaryDictionary | None = "0W", conductance: str | float | None = "0W_per_Cel", - shell_conduction: bool | None = False, + shell_conduction: bool = False, low_side_rad_material: str | None = None, high_side_rad_material: str | None = None, ) -> BoundaryObject | None: diff --git a/src/ansys/aedt/core/maxwell.py b/src/ansys/aedt/core/maxwell.py index 2d292a66469a..e9ca5a51f984 100644 --- a/src/ansys/aedt/core/maxwell.py +++ b/src/ansys/aedt/core/maxwell.py @@ -1331,7 +1331,7 @@ def assign_winding( parallel_branches: int | None = 1, phase: float | None = 0, name: str | None = None, - ) -> BoundaryObject | bool: + ) -> BoundaryObject: """Assign a winding to a Maxwell design. Parameters @@ -1365,7 +1365,6 @@ def assign_winding( ------- :class:`ansys.aedt.core.modules.boundary.common.BoundaryObject` Bounding object for the winding, otherwise only the bounding object. - ``False`` when failed. References ---------- @@ -1411,7 +1410,7 @@ def assign_winding( if coil_names: self.add_winding_coils(bound.name, coil_names) return bound - return False + raise AEDTRuntimeError("Assigning winding failed.") @pyaedt_function_handler() def add_winding_coils(self, assignment: str, coils: list) -> bool: @@ -2823,14 +2822,14 @@ def __init__( solution_type: str | None = None, setup: str | None = None, version: str | None = None, - non_graphical: bool | None = False, - new_desktop: bool | None = False, - close_on_exit: bool | None = False, - student_version: bool | None = False, - machine: str | None = "", - port: int | None = 0, + non_graphical: bool = False, + new_desktop: bool = False, + close_on_exit: bool = False, + student_version: bool = False, + machine: str = "", + port: int = 0, aedt_process_id: int | None = None, - remove_lock: bool | None = False, + remove_lock: bool = False, ) -> None: """Initialize the ``Maxwell`` class.""" self.is3d = True @@ -3019,7 +3018,7 @@ def assign_current_density_terminal( Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -3070,9 +3069,11 @@ def assign_current_density_terminal( boundary = self._create_boundary(bound_name, props, bound_type) if boundary: return True + else: # pragma: no cover + raise AEDTRuntimeError("Current density terminal could not be assigned.") + except GrpcApiError as e: raise AEDTRuntimeError("Current density terminal could not be assigned.") from e - return False @pyaedt_function_handler() def get_conduction_paths(self) -> dict: @@ -3120,7 +3121,7 @@ def assign_master_slave( reverse_slave: bool | None = False, same_as_master: bool | None = True, bound_name: str | None = None, - ) -> tuple[BoundaryObject, BoundaryObject] | bool: + ) -> tuple[BoundaryObject, BoundaryObject]: """Assign dependent and independent boundary conditions to two faces of the same object. Parameters @@ -3151,7 +3152,7 @@ def assign_master_slave( ------- :class:`ansys.aedt.core.modules.boundary.common.BoundaryObject`, :class:`ansys.aedt.core.modules.boundary.common.BoundaryObject` - Master and slave objects. If the method fails to execute it returns ``False``. + Master and slave objects. References ---------- @@ -3226,9 +3227,12 @@ def assign_master_slave( slave = self._create_boundary(bound_name_s, slave_props, "Dependent") if slave: return master, slave + else: # pragma: no cover + raise AEDTRuntimeError("Slave boundary could not be created.") + else: # pragma: no cover + raise AEDTRuntimeError("Master boundary could not be created.") except GrpcApiError as e: raise AEDTRuntimeError("Slave boundary could not be created.") from e - return False @pyaedt_function_handler() def assign_flux_tangential(self, assignment: list, flux_name: str | None = None) -> BoundaryObject | bool: @@ -3891,14 +3895,14 @@ def __init__( solution_type: str | None = None, setup: str | None = None, version: str | None = None, - non_graphical: bool | None = False, - new_desktop: bool | None = False, - close_on_exit: bool | None = False, - student_version: bool | None = False, - machine: str | None = "", - port: int | None = 0, + non_graphical: bool = False, + new_desktop: bool = False, + close_on_exit: bool = False, + student_version: bool = False, + machine: str = "", + port: int = 0, aedt_process_id: int | None = None, - remove_lock: bool | None = False, + remove_lock: bool = False, ) -> None: self.is3d = False FieldAnalysis3D.__init__( @@ -4118,7 +4122,7 @@ def assign_master_slave( reverse_slave: bool | None = False, same_as_master: bool | None = True, boundary: str | None = None, - ) -> tuple[BoundaryObject, BoundaryObject] | bool: + ) -> tuple[BoundaryObject, BoundaryObject]: """Assign dependent and independent boundary conditions to two edges of the same object. Parameters @@ -4141,7 +4145,7 @@ def assign_master_slave( ------- :class:`ansys.aedt.core.modules.boundary.common.BoundaryObject`, :class:`ansys.aedt.core.modules.boundary.common.BoundaryObject` - Master and slave objects. If the method fails to execute it returns ``False``. + Master and slave objects.. References ---------- @@ -4184,9 +4188,12 @@ def assign_master_slave( slave = self._create_boundary(bound_name_s, slave_props, "Dependent") if slave: return master, slave + else: # pragma: no cover + raise AEDTRuntimeError("Slave boundary could not be created.") + else: # pragma: no cover + raise AEDTRuntimeError("Master boundary could not be created.") except GrpcApiError as e: raise AEDTRuntimeError("Slave boundary could not be created.") from e - return False @pyaedt_function_handler() def assign_end_connection( diff --git a/src/ansys/aedt/core/maxwellcircuit.py b/src/ansys/aedt/core/maxwellcircuit.py index a62876cc904a..1aaa54489773 100644 --- a/src/ansys/aedt/core/maxwellcircuit.py +++ b/src/ansys/aedt/core/maxwellcircuit.py @@ -31,6 +31,7 @@ from ansys.aedt.core.base import PyAedtBase from ansys.aedt.core.generic.file_utils import open_file from ansys.aedt.core.generic.general_methods import pyaedt_function_handler +from ansys.aedt.core.internal.errors import AEDTRuntimeError class MaxwellCircuit(AnalysisMaxwellCircuit, PyAedtBase): @@ -113,14 +114,14 @@ def __init__( design: str | None = None, version: str | None = None, solution_type: str | None = None, - non_graphical: bool | None = False, - new_desktop: bool | None = False, - close_on_exit: bool | None = False, - student_version: bool | None = False, + non_graphical: bool = False, + new_desktop: bool = False, + close_on_exit: bool = False, + student_version: bool = False, machine: str | None = "", - port: int | None = 0, + port: int = 0, aedt_process_id: int | None = None, - remove_lock: bool | None = False, + remove_lock: bool = False, ) -> None: """Constructor.""" AnalysisMaxwellCircuit.__init__( @@ -212,7 +213,7 @@ def create_schematic_from_netlist(self, input_file: str) -> bool: return True @pyaedt_function_handler() - def export_netlist_from_schematic(self, output_file: str | Path) -> str | bool: + def export_netlist_from_schematic(self, output_file: str | Path) -> str: """Create netlist from schematic circuit. Parameters @@ -223,7 +224,7 @@ def export_netlist_from_schematic(self, output_file: str | Path) -> str | bool: Returns ------- str - Netlist file path when successful, ``False`` when failed. + Netlist file path when successful. Examples -------- @@ -246,14 +247,13 @@ def export_netlist_from_schematic(self, output_file: str | Path) -> str | bool: >>> v.pins[0].connect_to_component(gnd.pins[0], use_wire=True) >>> gnd.pins[0].connect_to_component(v.pins[0], use_wire=True) Export circuit netlist. - >>> circ.export_netlist_from_schematic(output_file="C:\\Users\\netlist.sph") + >>> circ.export_netlist_from_schematic(output_file=r"C:\\Users\\netlist.sph") >>> circ.desktop_class.close_desktop() """ if Path(output_file).suffix != ".sph": - self.logger.error("Invalid file extension. It must be ``.sph``.") - return False + raise ValueError("Invalid file extension. It must be ``.sph``.") try: self.odesign.ExportNetlist("", str(output_file)) return output_file - except Exception: - return False + except Exception: # pragma: no cover + raise AEDTRuntimeError("Unable to export netlist.") diff --git a/src/ansys/aedt/core/mechanical.py b/src/ansys/aedt/core/mechanical.py index 0878a7717ae9..8fd69d1ea522 100644 --- a/src/ansys/aedt/core/mechanical.py +++ b/src/ansys/aedt/core/mechanical.py @@ -131,14 +131,14 @@ def __init__( solution_type: str | None = None, setup: str | None = None, version: str | None = None, - non_graphical: bool | None = False, - new_desktop: bool | None = False, - close_on_exit: bool | None = False, - student_version: bool | None = False, - machine: str | None = "", - port: int | None = 0, + non_graphical: bool = False, + new_desktop: bool = False, + close_on_exit: bool = False, + student_version: bool = False, + machine: str = "", + port: int = 0, aedt_process_id: int | None = None, - remove_lock: bool | None = False, + remove_lock: bool = False, ) -> None: FieldAnalysis3D.__init__( self, @@ -678,8 +678,7 @@ def assign_2way_coupling(self, setup: str | None = None, number_of_iterations: i if self.setups: setup = self.setups[0].name else: - self.logger.error("Setup is not defined.") - return False + raise ValueError("No setup is defined in the design.") self.oanalysis.AddTwoWayCoupling( setup, diff --git a/src/ansys/aedt/core/modeler/advanced_cad/stackup_3d.py b/src/ansys/aedt/core/modeler/advanced_cad/stackup_3d.py index aaa75c67fa31..bcf36d004ccd 100644 --- a/src/ansys/aedt/core/modeler/advanced_cad/stackup_3d.py +++ b/src/ansys/aedt/core/modeler/advanced_cad/stackup_3d.py @@ -843,14 +843,14 @@ def add_polygon( if self._layer_type == "ground": if not is_void: - if polygon.aedt_object.is3d: + if polygon.aedt_object.is_3d: self._app.modeler[self._name].subtract(polygon.aedt_object, True) polygon.aedt_object.material_name = self.filling_material_name else: self._app.modeler[self._name].subtract(polygon.aedt_object, False) return True elif is_void: - if polygon.aedt_object.is3d: + if polygon.aedt_object.is_3d: self._app.modeler.subtract(self._obj_3d, polygon.aedt_object, True) polygon.aedt_object.material_name = self.filling_material_name else: diff --git a/src/ansys/aedt/core/modeler/cad/component_array.py b/src/ansys/aedt/core/modeler/cad/component_array.py index 5451740f9f9f..c64d6a74440b 100644 --- a/src/ansys/aedt/core/modeler/cad/component_array.py +++ b/src/ansys/aedt/core/modeler/cad/component_array.py @@ -564,8 +564,7 @@ def parse_array_info_from_csv(self, input_file: str) -> dict: # pragma: no cove """ info = read_csv(input_file) if not info: - self.logger.error("Data from CSV file is not loaded.") - return False + raise AEDTRuntimeError(f"Failed to parse array information from CSV file: {input_file}") components = {} array_matrix = [] diff --git a/src/ansys/aedt/core/modeler/cad/elements_3d.py b/src/ansys/aedt/core/modeler/cad/elements_3d.py index 0d4e75aa7d89..e66d16ea32cc 100644 --- a/src/ansys/aedt/core/modeler/cad/elements_3d.py +++ b/src/ansys/aedt/core/modeler/cad/elements_3d.py @@ -60,7 +60,7 @@ def fillet(self, radius: float = 0.1, setback: float = 0.0) -> bool: Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -73,11 +73,10 @@ def fillet(self, radius: float = 0.1, setback: float = 0.0) -> bool: if isinstance(self, VertexPrimitive): vertex_id_list = [self.id] else: - if self._object3d.is3d: + if self._object3d.is_3d: edge_id_list = [self.id] else: - self._object3d.logger.error("Fillet is possible only on a vertex in 2D designs.") - return False + raise AEDTRuntimeError("Fillet is possible only on a vertex in 2D designs.") vArg1 = ["NAME:Selections", "Selections:=", self._object3d.name, "NewPartsModelFlag:=", "Model"] vArg2 = ["NAME:FilletParameters"] @@ -117,7 +116,7 @@ def chamfer( Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -130,11 +129,10 @@ def chamfer( if isinstance(self, VertexPrimitive): vertex_id_list = [self.id] else: - if self._object3d.is3d: + if self._object3d.is_3d: edge_id_list = [self.id] else: - self._object3d.logger.error("chamfer is possible only on Vertex in 2D Designs ") - return False + raise AEDTRuntimeError("chamfer is possible only on Vertex in 2D Designs ") vArg1 = ["NAME:Selections", "Selections:=", self._object3d.name, "NewPartsModelFlag:=", "Model"] vArg2 = ["NAME:ChamferParameters"] vArg2.append("Edges:="), vArg2.append(edge_id_list) @@ -182,13 +180,12 @@ def chamfer( ) vArg2.append("ChamferType:="), vArg2.append("Right Distance-Angle") else: - self._object3d.logger.error("Wrong chamfer_type provided. Value must be an integer from 0 to 3.") - return False + raise AEDTRuntimeError("Wrong chamfer_type provided. Value must be an integer from 0 to 3.") + self._object3d._oeditor.Chamfer(vArg1, ["NAME:Parameters", vArg2]) if self._object3d.name in list(self._object3d._oeditor.GetObjectsInGroup("UnClassified")): self._object3d.odesign.Undo() - self._object3d.logger.error("Operation Failed generating Unclassified object. Check and retry") - return False + raise AEDTRuntimeError("Operation Failed generating Unclassified object. Check and retry") return True @@ -431,13 +428,13 @@ def midpoint(self) -> list[float] | None: return [float(i) for i in self.oeditor.GetEdgePositionAtNormalizedParameter(self.id, 0.5)] @property - def length(self) -> float | bool: + def length(self) -> float: """Length of the edge. Returns ------- - float or bool - Edge length in model units when edge has two vertices, ``False`` otherwise. + float + Edge length in model units when edge has two vertices. References ---------- @@ -447,7 +444,7 @@ def length(self) -> float | bool: try: return float(self.oeditor.GetEdgeLength(self.id)) except Exception: - return False + raise AEDTRuntimeError(f"Failed to calculate edge length: {self.id}") @pyaedt_function_handler() def create_object(self, non_model: bool = False) -> "Object3d": @@ -480,15 +477,14 @@ def move_along_normal(self, offset: float = 1.0) -> bool: Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- >>> oEditor.MoveEdges """ if self._object3d.object_type == "Solid": - self._object3d.logger.error("Edge Movement applies only to 2D objects.") - return False + raise AEDTRuntimeError("Edge Movement applies only to 2D objects.") return self._object3d._primitives.move_edge(self, offset) @pyaedt_function_handler() @@ -518,7 +514,7 @@ def fillet(self, radius: float = 0.1, setback: float = 0.0) -> bool: if isinstance(self, VertexPrimitive): vertex_id_list = [self.id] else: - if self._object3d.is3d: + if self._object3d.is_3d: edge_id_list = [self.id] else: raise AEDTRuntimeError("Fillet is possible only on a vertex in 2D designs.") @@ -574,11 +570,11 @@ def chamfer( if isinstance(self, VertexPrimitive): vertex_id_list = [self.id] else: - if self._object3d.is3d: + if self._object3d.is_3d: edge_id_list = [self.id] else: - self._object3d.logger.error("chamfer is possible only on Vertex in 2D Designs ") - return False + raise AEDTRuntimeError("chamfer is possible only on Vertex in 2D Designs ") + vArg1 = ["NAME:Selections", "Selections:=", self._object3d.name, "NewPartsModelFlag:=", "Model"] vArg2 = ["NAME:ChamferParameters"] vArg2.append("Edges:="), vArg2.append(edge_id_list) @@ -626,13 +622,12 @@ def chamfer( ) vArg2.append("ChamferType:="), vArg2.append("Right Distance-Angle") else: - self._object3d.logger.error("Wrong chamfer_type provided. Value must be an integer from 0 to 3.") - return False + raise AEDTRuntimeError("Wrong chamfer_type provided. Value must be an integer from 0 to 3.") + self._object3d._oeditor.Chamfer(vArg1, ["NAME:Parameters", vArg2]) if self._object3d.name in list(self._object3d._oeditor.GetObjectsInGroup("UnClassified")): self._object3d.odesign.Undo() - self._object3d.logger.error("Operation Failed generating Unclassified object. Check and retry") - return False + raise AEDTRuntimeError("Operation Failed generating Unclassified object. Check and retry") return True @@ -758,13 +753,13 @@ def id(self) -> int: return self._id @property - def center_from_aedt(self) -> list[float] | bool: + def center_from_aedt(self) -> list[float]: """Face center for a planar face in model units. Returns ------- - list or bool - Center position in ``[x, y, z]`` coordinates for the planar face, ``False`` otherwise. + list + Center position in ``[x, y, z]`` coordinates for the planar face. References ---------- @@ -774,8 +769,7 @@ def center_from_aedt(self) -> list[float] | bool: try: c = self.oeditor.GetFaceCenter(self.id) except Exception: - self.logger.warning("Non-planar face does not provide a face center.") - return False + raise AEDTRuntimeError("Non-planar face does not provide a face center.") center = [float(i) for i in c] return center diff --git a/src/ansys/aedt/core/modeler/cad/object_3d.py b/src/ansys/aedt/core/modeler/cad/object_3d.py index 26bf14fed37c..ca905d043cdb 100644 --- a/src/ansys/aedt/core/modeler/cad/object_3d.py +++ b/src/ansys/aedt/core/modeler/cad/object_3d.py @@ -38,7 +38,6 @@ from pathlib import Path import re from typing import TYPE_CHECKING -import warnings from ansys.aedt.core.base import PyAedtBase from ansys.aedt.core.generic.constants import AEDT_UNITS @@ -161,7 +160,7 @@ def _bounding_box_unmodel(self): vArg1 = ["NAME:Model", "Value:=", False] self._primitives._change_geometry_property(vArg1, objs_to_unmodel) modeled = True - if not self.model: + if not self.is_model: vArg1 = ["NAME:Model", "Value:=", True] self._primitives._change_geometry_property(vArg1, self.name) modeled = False @@ -837,7 +836,7 @@ def surface_material_name(self) -> str | None: """ if self._surface_material is not None: return self._surface_material - if "Surface Material" in self.valid_properties and self.model: + if "Surface Material" in self.valid_properties and self.is_model: self._surface_material = self._oeditor.GetPropertyValue( "Geometry3DAttributeTab", self._m_name, "Surface Material" ) @@ -939,7 +938,7 @@ def material_name(self) -> str | None: """ if self._material_name is not None: return self._material_name - if "Material" in self.valid_properties and self.model: + if "Material" in self.valid_properties and self.is_model: mat = self._oeditor.GetPropertyValue("Geometry3DAttributeTab", self._m_name, "Material") self._material_name = "" if mat: @@ -956,8 +955,8 @@ def material_name(self, mat: str) -> None: elif "[" in mat or "(" in mat: mat_value = mat if mat_value is not None: - if not self.model: - self.model = True + if not self.is_model: + self.is_model = True vMaterial = ["NAME:Material", "Value:=", mat_value] self._change_property(vMaterial) self._material_name = mat_value.strip('"') @@ -968,8 +967,8 @@ def material_name(self, mat: str) -> None: @surface_material_name.setter def surface_material_name(self, mat: str) -> None: try: - if not self.model: - self.model = True + if not self.is_model: + self.is_model = True self._surface_material = mat vMaterial = ["NAME:Surface Material", "Value:=", '"' + mat + '"'] self._change_property(vMaterial) @@ -1025,25 +1024,6 @@ def object_type(self) -> str: self._object_type = "Unclassified" # pragma: no cover return self._object_type - @property - def is3d(self) -> bool: - """Check if the object is a 3D solid object. - - This method determines whether the current object represents a - three-dimensional solid geometry by checking its object type. - - .. deprecated:: - Use :func:`is_3d` property instead. - - Returns - ------- - bool - ``True`` if the object is a 3D solid, ``False`` otherwise. - """ - warnings.warn("`is3d` is deprecated. Use `is_3d` property instead.", DeprecationWarning) - res = self.is_3d - return res - @property def is_3d(self) -> bool: """Check if the object is a 3D solid object. @@ -1074,7 +1054,7 @@ def mass(self) -> float | None: >>> oEditor.GetObjectVolume """ - if self.model and self.material_name: + if self.is_model and self.material_name: volume = self._primitives.oeditor.GetObjectVolume(self._m_name) units = self.object_units mass_density = ( @@ -1311,7 +1291,7 @@ def solve_inside(self) -> bool: """ if self._solve_inside is not None: return self._solve_inside - if "Solve Inside" in self.valid_properties and self.model: + if "Solve Inside" in self.valid_properties and self.is_model: solveinside = self._oeditor.GetPropertyValue("Geometry3DAttributeTab", self._m_name, "Solve Inside") if solveinside == "false" or solveinside == "False": self._solve_inside = False @@ -1322,8 +1302,8 @@ def solve_inside(self) -> bool: @solve_inside.setter def solve_inside(self, S: bool) -> None: - if not self.model: - self.model = True + if not self.is_model: + self.is_model = True vSolveInside = [] # fS = self._to_boolean(S) fs = S @@ -1422,7 +1402,7 @@ def history(self) -> BinaryTreeNode | bool: return False @property - def is_model(self) -> bool: + def is_model(self) -> bool | None: """Part model or non-model property. Returns @@ -1445,6 +1425,8 @@ def is_model(self) -> bool: else: self._model = True return self._model + else: + return self._model @is_model.setter def is_model(self, fModel: bool) -> None: @@ -1453,31 +1435,6 @@ def is_model(self, fModel: bool) -> None: self._change_property(vArg1) self._model = fModel - @property - def model(self) -> bool: - """Part model or non-model property. - - .. deprecated:: - Use :func:`is_model` property instead. - - Returns - ------- - bool - ``True`` when model, ``False`` otherwise. - - References - ---------- - >>> oEditor.GetPropertyValue - >>> oEditor.ChangeProperty - - """ - warnings.warn("`model` is deprecated. Use `is_model` property instead.", DeprecationWarning) - return self.is_model - - @model.setter - def model(self, fModel: bool) -> None: - self.is_model = fModel - @pyaedt_function_handler() def unite(self, assignment: list[str] | list[Object3d]) -> Object3d: """Unite a list of objects with this object. diff --git a/src/ansys/aedt/core/modeler/cad/primitives.py b/src/ansys/aedt/core/modeler/cad/primitives.py index d74c17a675d8..19d0adc2fe7a 100644 --- a/src/ansys/aedt/core/modeler/cad/primitives.py +++ b/src/ansys/aedt/core/modeler/cad/primitives.py @@ -51,6 +51,7 @@ from ansys.aedt.core.generic.numbers_utils import decompose_variable_value from ansys.aedt.core.generic.numbers_utils import is_number from ansys.aedt.core.generic.quaternion import Quaternion +from ansys.aedt.core.internal.errors import AEDTRuntimeError from ansys.aedt.core.internal.errors import GrpcApiError from ansys.aedt.core.modeler.cad.components_3d import UserDefinedComponent from ansys.aedt.core.modeler.cad.elements_3d import EdgePrimitive @@ -1471,7 +1472,7 @@ def cover_lines(self, assignment: str | int) -> bool: Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -1493,7 +1494,7 @@ def cover_faces(self, assignment: str | int) -> bool: Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -1515,7 +1516,7 @@ def uncover_faces(self, assignment: list) -> bool: Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -1670,14 +1671,14 @@ def create_coordinate_system( ) if result: return cs - return False + raise AEDTRuntimeError("Coordinate system not created.") @pyaedt_function_handler() def create_face_coordinate_system( self, - face: int | "FacePrimitive", - origin: int | "FacePrimitive" | "EdgePrimitive" | "VertexPrimitive", - axis_position: int | "FacePrimitive" | "EdgePrimitive" | "VertexPrimitive", + face: "int | FacePrimitive", + origin: "int | FacePrimitive | EdgePrimitive | VertexPrimitive", + axis_position: "int | FacePrimitive | EdgePrimitive | VertexPrimitive", axis: str = "X", name: str | None = None, offset: list | None = None, @@ -1750,15 +1751,15 @@ def create_face_coordinate_system( if result: return cs - return False + raise AEDTRuntimeError("Failed to create face coordinate system.") @pyaedt_function_handler() def create_object_coordinate_system( self, - assignment: int | "FacePrimitive" | "EdgePrimitive" | "VertexPrimitive", - origin: int | "FacePrimitive" | "EdgePrimitive" | "VertexPrimitive" | list, - x_axis: int | "FacePrimitive" | "EdgePrimitive" | "VertexPrimitive" | list, - y_axis: int | "FacePrimitive" | "EdgePrimitive" | "VertexPrimitive" | list, + assignment: "int | FacePrimitive | EdgePrimitive | VertexPrimitive", + origin: "int | FacePrimitive | EdgePrimitive | VertexPrimitive | list", + x_axis: "int | FacePrimitive | EdgePrimitive | VertexPrimitive | list", + y_axis: "int | FacePrimitive | EdgePrimitive | VertexPrimitive | list", move_to_end: bool = True, reverse_x_axis: bool = False, reverse_y_axis: bool = False, @@ -1810,7 +1811,7 @@ def create_object_coordinate_system( Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. """ if name: cs_names = [i.name for i in self.coordinate_systems] @@ -1831,10 +1832,10 @@ def create_object_coordinate_system( if result: return cs - return False + raise AEDTRuntimeError("Failed to create object coordinate system.") @pyaedt_function_handler() - def global_to_cs(self, point: list, coordinate_system: str | "CoordinateSystem") -> list: + def global_to_cs(self, point: list, coordinate_system: "str | CoordinateSystem") -> list: """Transform a point from the global coordinate system to another coordinate system. Parameters @@ -1912,7 +1913,7 @@ def set_working_coordinate_system(self, name: str) -> bool: Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -1945,7 +1946,7 @@ def get_working_coordinate_system(self) -> str: @pyaedt_function_handler() def invert_cs( - self, coordinate_system: str | "CoordinateSystem", to_global: bool = False + self, coordinate_system: "str | CoordinateSystem", to_global: bool = False ) -> tuple[list, "Quaternion"]: """Get the inverse translation and the conjugate quaternion of the input coordinate system. @@ -1988,7 +1989,7 @@ def invert_cs( return o, q @pyaedt_function_handler() - def reference_cs_to_global(self, coordinate_system: str | "CoordinateSystem") -> tuple[list, "Quaternion"]: + def reference_cs_to_global(self, coordinate_system: "str | CoordinateSystem") -> tuple[list, "Quaternion"]: """Get the origin and quaternion defining the coordinate system in the global coordinates. Parameters @@ -2024,7 +2025,7 @@ def reference_cs_to_global(self, coordinate_system: str | "CoordinateSystem") -> return origin, quaternion @pyaedt_function_handler() - def duplicate_coordinate_system_to_global(self, coordinate_system: str | "CoordinateSystem") -> "CoordinateSystem": + def duplicate_coordinate_system_to_global(self, coordinate_system: "str | CoordinateSystem") -> "CoordinateSystem": """Create a duplicate coordinate system referenced to the global coordinate system. Having this coordinate system referenced to the global coordinate @@ -2186,7 +2187,7 @@ def duplicate_coordinate_system_to_global(self, coordinate_system: str | "Coordi ) if result: return obj_cs - return False + raise AEDTRuntimeError("Failed to reference coordinate system to global.") @pyaedt_function_handler() def set_objects_deformation(self, assignment: list) -> bool: @@ -2200,7 +2201,7 @@ def set_objects_deformation(self, assignment: list) -> bool: Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -2209,9 +2210,8 @@ def set_objects_deformation(self, assignment: list) -> bool: self.logger.info("Enabling deformation feedback") try: self._odesign.SetObjectDeformation(["EnabledObjects:=", assignment]) - except Exception: # pragma: no cover - self.logger.error("Failed to enable the deformation dependence") - return False + except Exception as e: # pragma: no cover + raise AEDTRuntimeError(f"Failed to enable the deformation dependence: {e}") from e else: self.logger.info("Successfully enabled deformation feedback") return True @@ -2237,7 +2237,7 @@ def set_objects_temperature( Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -2265,14 +2265,13 @@ def set_objects_temperature( vargs2.append(obj) vargs2.append(var) if not vargs2: - return False + raise ValueError("No objects with thermal modifiers found in the assignment list.") else: vargs1.append(vargs2) try: self._odesign.SetObjectTemperature(vargs1) - except Exception: # pragma: no cover - self.logger.error("Failed to enable the temperature dependence") - return False + except Exception as e: # pragma: no cover + raise AEDTRuntimeError(f"Failed to enable the temperature dependence: {e}") from e else: self.logger.info("Assigned Objects Temperature") return True @@ -2586,7 +2585,7 @@ def set_object_model_state(self, assignment: list, model: bool = True) -> bool: Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -2777,8 +2776,7 @@ def split( >>> oEditor.Split """ if plane is None and not tool or plane and tool: - self.logger.info("One method to split the objects has to be defined.") - return False + raise ValueError("Exactly one method to split the objects has to be defined (plane or tool).") assignment = self.convert_to_selections(assignment) all_objs = [i for i in self.object_names] selections = [] @@ -2813,8 +2811,7 @@ def split( if objs: obj = objs[0] else: - self.logger.info("Tool must be a sheet object or a face of an object.") - return False + raise ValueError("Tool must be a sheet object or a face of an object.") if isinstance(obj, FacePrimitive) or isinstance(obj, Object3d) and obj.object_type != "Line": obj_name = obj.name obj = obj.faces[0] @@ -2844,8 +2841,7 @@ def split( obj = o.edges[0] tool_type = "EdgeTool" else: # pragma: no cover - self.logger.error("Face tool part has to be provided as a string (name) or an int (face id).") - return False + raise ValueError("Face tool part has to be provided as a string (name) or an int (face id).") planes = "Dummy" tool_type = tool_type tool_entity_id = obj.id @@ -2860,8 +2856,7 @@ def split( ] else: if plane is None and tool or not plane: - self.logger.info("For 2D design types only planes can be defined.") - return False + raise ValueError("For 2D design types only planes can be defined.") elif plane is not None: tool_type = "PlaneTool" tool_entity_id = -1 @@ -2961,7 +2956,7 @@ def mirror( Returns ------- bool, list - List of objects created or ``True`` when successful, ``False`` when failed. + List of objects created or ``True`` when successful. References ---------- @@ -3034,7 +3029,7 @@ def move(self, assignment: list, vector: list) -> bool: Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -3286,7 +3281,7 @@ def sweep_along_normal( return [self.update_object(self[o]) for o in obj] else: return self.update_object(self[obj[0]]) - return False + raise AEDTRuntimeError("Failed to sweep along normal. No new objects created.") @pyaedt_function_handler() def sweep_along_vector( @@ -3372,7 +3367,7 @@ def sweep_along_path( Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -3423,7 +3418,7 @@ def sweep_around_axis( Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -3483,7 +3478,7 @@ def section( Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -3546,8 +3541,8 @@ def separate_bodies( if obj.name == new_obj: new_objects_list.append(obj) return new_objects_list - except Exception: - return False + except Exception as e: + raise AEDTRuntimeError(f"Failed to separate bodies: {e}") from e @pyaedt_function_handler() def rotate(self, assignment: str | int | list | Object3d, axis, angle: float = 90.0, units: str = "deg") -> bool: @@ -3569,7 +3564,7 @@ def rotate(self, assignment: str | int | list | Object3d, axis, angle: float = 9 Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -3609,7 +3604,7 @@ def subtract( Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -3650,7 +3645,7 @@ def imprint( Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -3715,7 +3710,7 @@ def imprint_normal_projection( Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -3748,7 +3743,7 @@ def imprint_vector_projection( Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -3770,7 +3765,7 @@ def purge_history(self, assignment: list, non_model: bool = False) -> bool: Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -3847,10 +3842,9 @@ def unite(self, assignment: list, purge: bool = False, keep_originals: bool = Fa arg_2 += ["TurnOnNBodyBoolean:=", True] self.oeditor.Unite(arg_1, arg_2) if selections.split(",")[0] in self.unclassified_names: # pragma: no cover - self.logger.error("Error in uniting objects.") self._odesign.Undo() self.cleanup_objects() - return False + raise AEDTRuntimeError("Error in uniting objects.") elif purge: self.purge_history(objs[0]) objs_groups.append(objs[0]) @@ -3877,7 +3871,7 @@ def clone(self, assignment: list) -> tuple[bool, list]: Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. list List of names of objects cloned when successful. @@ -4034,8 +4028,7 @@ def connect(self, assignment: list) -> list[Object3d] | bool: self.oeditor.Connect(vArg1) if unclassified_before != self.unclassified_names: # pragma: no cover self._odesign.Undo() - self.logger.error("Error in connection. Reverting Operation") - return False + raise AEDTRuntimeError("Error in connection. Reverting Operation.") self.cleanup_objects() self.logger.info("Connection Correctly created") @@ -4045,8 +4038,8 @@ def connect(self, assignment: list) -> list[Object3d] | bool: object_list = self.object_list.copy() objects_list_after_connection = [obj for obj in object_list if obj.name in selected_names] return objects_list_after_connection - except Exception: - return False + except Exception as e: + raise AEDTRuntimeError(f"Failed to connect objects: {e}") from e @pyaedt_function_handler() def chassis_subtraction(self, chassis_part: str) -> bool: @@ -4207,7 +4200,7 @@ def clean_objects_name(self, main_part_name: str) -> bool: Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -4335,7 +4328,7 @@ def edit_region_dimensions(self, values: list) -> bool: Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -4390,11 +4383,9 @@ def create_face_list(self, assignment: list, name: str = None) -> Lists | bool: if result: return user_list else: # pragma: no cover - self._app.logger.error("Wrong object definition. Review object list and type") - return False + raise AEDTRuntimeError("Wrong object definition. Review face list and type.") else: # pragma: no cover - self._app.logger.error("User list object could not be created") - return False + raise AEDTRuntimeError("User list object could not be created.") @pyaedt_function_handler() def create_object_list(self, assignment: list, name: str | None = None) -> Lists | bool: @@ -4429,11 +4420,9 @@ def create_object_list(self, assignment: list, name: str | None = None) -> Lists if result: return user_list else: # pragma: no cover - self._app.logger.error("Wrong object definition. Review object list and type") - return False + raise AEDTRuntimeError("Wrong object definition. Review object list and type.") else: # pragma: no cover - self._app.logger.error("User list object could not be created") - return False + raise AEDTRuntimeError("User list object could not be created.") @pyaedt_function_handler() def generate_object_history(self, assignment: str | int, non_model: bool = False) -> bool: @@ -4449,7 +4438,7 @@ def generate_object_history(self, assignment: str | int, non_model: bool = False Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -4525,8 +4514,7 @@ def create_faceted_bondwire_from_true_surface( edgelist.append(el) verlist.append([p1, p2]) if not edgelist: # pragma: no cover - self.logger.error("No edges found specified direction. Check again") - return False + raise AEDTRuntimeError("No edges found in specified direction. Check again.") connected = [edgelist[0]] tol = 1e-6 for edge in edgelist[1:]: @@ -4597,10 +4585,10 @@ def create_faceted_bondwire_from_true_surface( ) if status: self.move(new_edges[0], move_vector) - old_bondwire.model = False + old_bondwire.is_model = False return new_edges[0] else: - return False + raise AEDTRuntimeError("Failed to create faceted bondwire from true surface.") @pyaedt_function_handler() def get_entitylist_id(self, name: str) -> int: @@ -4637,7 +4625,7 @@ def create_outer_facelist(self, assignment: list, name: str = "outer_faces") -> Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. """ list2 = self.select_allfaces_fromobjects(assignment) # find ALL faces of outer objects @@ -4659,7 +4647,7 @@ def explicitly_subtract(self, tool_parts: list, blank_parts: list) -> bool: Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -4715,7 +4703,7 @@ def find_port_faces(self, assignment: list) -> list: """ faces = [] - solids = [s for s in self.solid_objects if s.material_name not in ["vacuum", "air"] and s.model] + solids = [s for s in self.solid_objects if s.material_name not in ["vacuum", "air"] and s.is_model] for sheet_name in assignment: sheet = self[sheet_name] # get the sheet object _, cloned = self.clone(sheet) @@ -4787,8 +4775,8 @@ def get_object_name_from_edge_id(self, assignment: int) -> str | bool: if str(assignment) in oEdgeIDs: return obj except Exception: - return False - return False + return None + return None @pyaedt_function_handler() def get_solving_volume(self) -> str: @@ -4904,7 +4892,7 @@ def export_3d_model( Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -5028,7 +5016,7 @@ def import_3d_cad( Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -5077,7 +5065,7 @@ def import_spaceclaim_document(self, input_file: str) -> bool: # pragma: no cov Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -5297,26 +5285,23 @@ def import_discovery_model(self, input_file: str) -> bool: Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- >>> oEditor.CreateUserDefinedModel """ if is_linux: # pragma: no cover - self.logger.error("Discovery not supported on Linux.") - return False + raise AEDTRuntimeError("Discovery not supported on Linux.") version = self._app.aedt_version_id[-3:] ansys_install_dir = os.environ.get(f"AWP_ROOT{version}", "") if ansys_install_dir: if "Discovery" not in os.listdir(ansys_install_dir): # pragma: no cover - self.logger.error("Discovery installation not found.") - return False + raise AEDTRuntimeError("Discovery installation not found.") else: # pragma: no cover - self.logger.error("Discovery version is different from AEDT version.") - return False + raise AEDTRuntimeError("Discovery version is different from AEDT version.") model = self.oeditor.CreateUserDefinedModel( [ @@ -5411,7 +5396,7 @@ def break_spaceclaim_connection(self) -> bool: # TODO: Need to change this name Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -5434,7 +5419,7 @@ def load_scdm_in_hfss(self, input_file: str) -> bool: Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -5499,7 +5484,7 @@ def scale(self, assignment: list, x: float = 2.0, y: float = 2.0, z: float = 2.0 Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -5547,7 +5532,7 @@ def setunassigned_mats(self) -> bool: Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -5583,7 +5568,7 @@ def automatic_thicken_sheets( Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -5681,7 +5666,7 @@ def move_face(self, assignment: list, offset: float = 1.0) -> bool: Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -5741,7 +5726,7 @@ def move_edge(self, assignment: list, offset: float = 1.0) -> bool: Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -5877,7 +5862,7 @@ def ungroup(self, groups: list) -> bool: Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -5895,7 +5880,7 @@ def flatten_assembly(self) -> bool: Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -5928,11 +5913,9 @@ def wrap_sheet(self, sheet: str | Object3d, object: str | Object3d, imprinted: b object = self.convert_to_selections(object, False) if sheet not in self.sheet_names: # pragma: no cover - self.logger.error(f"{sheet} is not a valid sheet.") - return False + raise ValueError(f"'{sheet}' is not a valid sheet.") if object not in self.solid_names: # pragma: no cover - self.logger.error(f"{object} is not a valid solid body.") - return False + raise ValueError(f"'{object}' is not a valid solid body.") unclassified = [i for i in self.unclassified_objects] self.oeditor.WrapSheet( ["NAME:Selections", "Selections:=", f"{sheet},{object}"], @@ -5940,9 +5923,8 @@ def wrap_sheet(self, sheet: str | Object3d, object: str | Object3d, imprinted: b ) is_unclassified = [i for i in self.unclassified_objects if i not in unclassified] if is_unclassified: # pragma: no cover - self.logger.error("Failed to Wrap sheet. Reverting to original objects.") self._odesign.Undo() - return False + raise AEDTRuntimeError("Failed to wrap sheet. Operation reverted.") if imprinted: self.cleanup_objects() return True @@ -5978,7 +5960,7 @@ def project_sheet( Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -6003,12 +5985,10 @@ def project_sheet( ) unclassified_new = [i for i in self.unclassified_objects if i not in unclassified] if unclassified_new: - self.logger.error("Failed to Project Sheet. Reverting to original objects.") self._odesign.Undo() - return False - except Exception: - self.logger.error("Failed to Project Sheet.") - return False + raise AEDTRuntimeError("Failed to project sheet. Operation reverted.") + except Exception as e: + raise AEDTRuntimeError(f"Failed to project sheet: {e}") from e if not keep_originals: self.cleanup_objects() @@ -6111,14 +6091,12 @@ def heal_objects( Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. """ if not assignment: - self.logger.error("Provide an object name or a list of object names as a string.") - return False + raise ValueError("Provide an object name or a list of object names as a string.") elif not isinstance(assignment, str): - self.logger.error("Provide an object name or a list of object names as a string.") - return False + raise ValueError("Provide an object name or a list of object names as a string.") elif "," in assignment: assignment = assignment.strip() if ", " in assignment: @@ -6127,15 +6105,13 @@ def heal_objects( input_objects_list_split = assignment.split(",") for obj in input_objects_list_split: if obj not in self.object_names: - self.logger.error("Provide an object name or a list of object names that exists in current design.") - return False + raise ValueError("Provide an object name or a list of object names that exists in current design.") objects_selection = ",".join(input_objects_list_split) else: objects_selection = assignment if simplify_type not in [0, 1, 2]: - self.logger.error("Invalid simplify type.") - return False + raise ValueError("Invalid simplify type.") selections_args = ["NAME:Selections", "Selections:=", objects_selection, "NewPartsModelFlag:=", "Model"] healing_parameters = [ @@ -6255,14 +6231,12 @@ def simplify_objects( Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. """ if not assignment: - self.logger.error("Provide an object name or a list of object names as a string.") - return False + raise ValueError("Provide an object name or a list of object names as a string.") elif not isinstance(assignment, str): - self.logger.error("Provide an object name or a list of object names as a string.") - return False + raise ValueError("Provide an object name or a list of object names as a string.") elif "," in assignment: assignment = assignment.strip() if ", " in assignment: @@ -6271,19 +6245,16 @@ def simplify_objects( input_objects_list_split = assignment.split(",") for obj in input_objects_list_split: if obj not in self.object_names: - self.logger.error("Provide an object name or a list of object names that exists in current design.") - return False + raise ValueError("Provide an object name or a list of object names that exists in current design.") objects_selection = ",".join(input_objects_list_split) else: objects_selection = assignment if simplify_type not in ["Polygon Fit", "Primitive Fit", "Bounding Box"]: - self.logger.error("Invalid simplify type.") - return False + raise ValueError("Invalid simplify type.") if extrusion_axis not in ["Auto", "X", "Y", "Z"]: - self.logger.error("Invalid extrusion axis.") - return False + raise ValueError("Invalid extrusion axis.") selections_args = ["NAME:Selections", "Selections:=", objects_selection, "NewPartsModelFlag:=", "Model"] simplify_parameters = [ @@ -6312,12 +6283,11 @@ def simplify_objects( try: self.oeditor.Simplify(selections_args, simplify_parameters, groups_for_new_object) return True - except Exception: # pragma: no cover - self.logger.error("Simplify objects failed.") - return False + except Exception as e: # pragma: no cover + raise AEDTRuntimeError(f"Simplify objects failed: {e}") from e @pyaedt_function_handler() - def get_face_by_id(self, assignment: int) -> FacePrimitive | bool: + def get_face_by_id(self, assignment: int) -> FacePrimitive | None: """Get the face object given its ID. Parameters @@ -6336,7 +6306,7 @@ def get_face_by_id(self, assignment: int) -> FacePrimitive | bool: face_obj = [face for face in obj[0].faces if face.id == assignment][0] return face_obj else: - return False + return None @pyaedt_function_handler() def create_point(self, position: list, name: str | None = None, color: str = "(143 175 143)") -> Point: @@ -6561,7 +6531,7 @@ def update_geometry_property(self, assignment: str | list, name: str | None = No Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. """ assignment = self.convert_to_selections(assignment, True) @@ -6683,7 +6653,7 @@ def does_object_exists(self, assignment: int | str | Object3d) -> bool: Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. """ if isinstance(assignment, int): return assignment in self.objects @@ -6752,7 +6722,7 @@ def reassign_subregion(self, region: Object3d, parts: list[str]) -> bool: Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -6765,7 +6735,7 @@ def reassign_subregion(self, region: Object3d, parts: list[str]) -> bool: self.oeditor.ReassignSubregion(arg, arg2) if self._create_object(region.name): return True - return False + raise AEDTRuntimeError("Reassign subregion failed.") @pyaedt_function_handler() def _parse_region_args(self, pad_value, pad_type, region_name, parts, region_type, is_percentage): @@ -7465,7 +7435,7 @@ def delete(self, assignment: list = None) -> bool: Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -7483,8 +7453,7 @@ def delete(self, assignment: list = None) -> bool: ): assignment.remove(el) if not assignment: - self.logger.warning("No objects to delete") - return False + raise ValueError("No objects to delete") slice = min(100, len(assignment)) num_objects = len(assignment) remaining = num_objects @@ -7521,7 +7490,7 @@ def delete_objects_containing(self, contained_string: str, case_sensitive: bool Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -7557,7 +7526,7 @@ def delete_all_points(self) -> bool: Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -8895,7 +8864,7 @@ def _get_model_objects(self, model: bool = True): """ list_objs = [] for id, obj in self.objects.items(): - if obj.model == model: + if obj.is_model == model: list_objs.append(obj.name) return list_objs @@ -9445,16 +9414,14 @@ def create(self) -> list: if self.coordinate_systems: cs_flag = self._create_coordinate_system() if not cs_flag: # pragma: no cover - self.logger.error("Wrong coordinate system is defined.") - return False + raise AEDTRuntimeError("Wrong coordinate system is defined.") cs_names = [cs.name for cs in self._app.modeler.coordinate_systems] for instance_data in self.instances: name = instance_data.get("Name") if not name: # pragma: no cover - self.logger.error("``Name`` parameter is not defined.") - return False + raise AEDTRuntimeError("Wrong coordinate system is defined.") cs = instance_data.get("Coordinate System") if not cs: @@ -9464,8 +9431,7 @@ def create(self) -> list: elif ( instance_data["Coordinate System"] != "Global" and instance_data["Coordinate System"] not in cs_names ): # pragma: no cover - self.logger.error(f"Coordinate system {cs} does not exist.") - return False + raise AEDTRuntimeError(f"Coordinate system {cs} does not exist.") origin = instance_data.get("Origin") if not origin: diff --git a/src/ansys/aedt/core/modeler/cad/primitives_2d.py b/src/ansys/aedt/core/modeler/cad/primitives_2d.py index 46afb1e173b1..4ff3ff969523 100644 --- a/src/ansys/aedt/core/modeler/cad/primitives_2d.py +++ b/src/ansys/aedt/core/modeler/cad/primitives_2d.py @@ -322,7 +322,6 @@ def create_regular_polygon( Additional keyword arguments may be passed when creating the primitive to set properties. See ``ansys.aedt.core.modeler.cad.object_3d.Object3d`` for more details. - Returns ------- ansys.aedt.core.modeler.cad.object_3d.Object3d @@ -343,8 +342,7 @@ def create_regular_polygon( n_sides = int(num_sides) if n_sides < 3: - self.logger.error("Number of sides must be an integer >= 3.") - return False + raise ValueError("Number of sides must be an integer >= 3.") arg_1 = [ "NAME:RegularPolygonParameters", @@ -421,15 +419,13 @@ def create_region( 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 + raise ValueError("Wrong padding list provided. Four values have to be provided.") pad_value = [pad_value[0], pad_value[2], pad_value[1], pad_value[3], 0, 0] else: 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 + raise ValueError("Wrong padding list provided. Three values have to be provided for RZ geometry.") pad_value = [pad_value[0], 0, 0, 0, pad_value[1], pad_value[2]] return self._create_region(pad_value, pad_type, name, region_type="Region") diff --git a/src/ansys/aedt/core/modeler/calculators.py b/src/ansys/aedt/core/modeler/calculators.py index 0a344fe297c7..ef6da1542bae 100644 --- a/src/ansys/aedt/core/modeler/calculators.py +++ b/src/ansys/aedt/core/modeler/calculators.py @@ -324,7 +324,7 @@ def waveguide_list(self) -> list: return self.wg.keys() @pyaedt_function_handler() - def get_waveguide_dimensions(self, name: str, units: str = "mm") -> list | bool: + def get_waveguide_dimensions(self, name: str, units: str = "mm") -> list: """Strip line calculator. Parameters @@ -345,7 +345,7 @@ def get_waveguide_dimensions(self, name: str, units: str = "mm") -> list | bool: wg_dim.append(constants.unit_converter(dbl, "Length", "in", units)) return wg_dim else: - return False + raise ValueError("Waveguide dimension not found.") @pyaedt_function_handler() def find_waveguide(self, freq: float, units: str = "GHz") -> str | None: # pragma: no cover diff --git a/src/ansys/aedt/core/modeler/circuits/object_3d_circuit.py b/src/ansys/aedt/core/modeler/circuits/object_3d_circuit.py index e4f5c7ec9246..b10ceb966091 100644 --- a/src/ansys/aedt/core/modeler/circuits/object_3d_circuit.py +++ b/src/ansys/aedt/core/modeler/circuits/object_3d_circuit.py @@ -32,6 +32,7 @@ from ansys.aedt.core.generic.general_methods import pyaedt_function_handler from ansys.aedt.core.generic.numbers_utils import decompose_variable_value from ansys.aedt.core.generic.settings import settings +from ansys.aedt.core.internal.errors import AEDTRuntimeError from ansys.aedt.core.modeler.geometry_operators import GeometryOperators from ansys.aedt.core.modeler.geometry_operators import GeometryOperators as go @@ -184,7 +185,7 @@ def connect_to_component( clearance_units: int = 1, page_port_angle: int = None, offset: float = 0.00254, - ) -> bool: + ) -> bool | tuple: """Connect schematic components. Parameters @@ -211,7 +212,7 @@ def connect_to_component( Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -350,6 +351,8 @@ def connect_to_component( ) if offset != 0: self._circuit_comp._circuit_components.create_wire([self.location, location], page=local_page) + + ret2 = None for cmp in assignment: location = [ cmp.location[0] - offset * math.cos(cmp.total_angle * math.pi / 180), @@ -366,7 +369,7 @@ def connect_to_component( if ret1 and ret2: return True, ret1, ret2 else: - return False + raise AEDTRuntimeError("Circuit components not connected.") class ComponentParameters(dict): @@ -1102,7 +1105,7 @@ def change_symbol_pin_locations(self, pin_locations: dict, keep_original_size: b Returns ------- bool - ``True`` if pin locations were successfully changed, ``False`` otherwise. + ``True`` if pin locations were successfully changed. References ---------- @@ -1138,10 +1141,9 @@ def change_symbol_pin_locations(self, pin_locations: dict, keep_original_size: b # Ensure the total number of pins matches the symbol pin names if (right_pins_length + left_pins_length) != len(symbol_pin_name_list): - self._circuit_components._app.logger.error( + raise ValueError( "The number of pins in the input pin_locations does not match the number of pins in the Symbol." ) - return False x_factor = int(pin_name_str_max_length / 3) diff --git a/src/ansys/aedt/core/modeler/modeler_3d.py b/src/ansys/aedt/core/modeler/modeler_3d.py index 1bb21d29db57..f3527237adc9 100644 --- a/src/ansys/aedt/core/modeler/modeler_3d.py +++ b/src/ansys/aedt/core/modeler/modeler_3d.py @@ -39,6 +39,7 @@ from ansys.aedt.core.generic.file_utils import open_file from ansys.aedt.core.generic.general_methods import pyaedt_function_handler from ansys.aedt.core.internal.checks import install_message +from ansys.aedt.core.internal.errors import AEDTRuntimeError from ansys.aedt.core.internal.errors import GrpcApiError from ansys.aedt.core.modeler.cad.primitives_3d import Primitives3D from ansys.aedt.core.modeler.geometry_operators import GeometryOperators @@ -179,11 +180,11 @@ def create_3dcomponent( name = self._app.design_name.replace(" ", "_") dt_string = datetime.datetime.now().strftime("%H:%M:%S %p %b %d, %Y") if password_type not in ["UserSuppliedPassword", "InternalPassword"]: - self.logger.error("Password type must be 'UserSuppliedPassword' or 'InternalPassword'") - return False + raise ValueError( + f"Invalid password_type '{password_type}'. Must be 'UserSuppliedPassword' or 'InternalPassword'." + ) if component_outline not in ["BoundingBox", "None"]: - self.logger.error("Component outline must be 'BoundingBox' or 'None'") - return False + raise ValueError(f"Invalid component_outline '{component_outline}'. Must be 'BoundingBox' or 'None'.") if password is None: password = os.getenv("PYAEDT_ENCRYPTED_PASSWORD", "") if not edit_password: @@ -397,8 +398,7 @@ def create_3dcomponent( input_path.parent.mkdir(parents=True, exist_ok=True) self.logger.warning(f"Created folder '{input_path.parent}'") else: - self.logger.warning("Unable to create 3D Component: '" + input_file + "'") - return False + raise FileNotFoundError(f"Unable to create 3D Component: folder '{input_path.parent}' does not exist.") self.oeditor.Create3DComponent(arg, arg2, input_file, arg3) return True @@ -649,7 +649,7 @@ def create_waveguide( parametrize_h: bool = False, create_sheets_on_openings: bool = False, name: str = None, - ) -> tuple["Object3d", "Object3d"]: + ) -> tuple[Object3d, int | Object3d | list, int | Object3d | list] | None: """Create a standard waveguide and optionally parametrize `W` and `H`. Available models are WG0.0, WG0, WG1, WG2, WG3, WG4, WG5, WG6, @@ -818,6 +818,7 @@ def create_waveguide( self.model_units = original_model_units return wgbox, p1, p2 else: + self.logger.warning("Waveguide model not available.") return None @pyaedt_function_handler() @@ -879,23 +880,17 @@ def create_conical_rings( """ if bottom_radius <= top_radius: - self.logger.error("the ``bottom_radius`` argument must must be bigger than ``top_radius``.") - return False + raise ValueError("The 'bottom_radius' argument must be bigger than 'top_radius'.") if isinstance(bottom_radius, (int, float)) and bottom_radius < 0: - self.logger.error("The ``bottom_radius`` argument must be greater than 0.") - return False + raise ValueError("The 'bottom_radius' argument must be greater than 0.") if isinstance(top_radius, (int, float)) and top_radius < 0: - self.logger.error("The ``top_radius`` argument must be greater than 0.") - return False + raise ValueError("The 'top_radius' argument must be greater than 0.") if isinstance(cone_height, (int, float)) and cone_height <= 0: - self.logger.error("The ``cone_height`` argument must be greater than 0.") - return False + raise ValueError("The 'cone_height' argument must be greater than 0.") if isinstance(ring_height, (int, float)) and ring_height <= 0: - self.logger.error("The ``ring_height`` argument must be greater than 0.") - return False + raise ValueError("The 'ring_height' argument must be greater than 0.") if len(origin) != 3: - self.logger.error("The ``origin`` argument must be a valid three-element list.") - return False + raise ValueError("The 'origin' argument must be a valid three-element list.") if not name: name = generate_unique_name("ring_cone") @@ -1359,7 +1354,7 @@ def objects_segmentation( segments: int = None, apply_mesh_sheets: bool = False, mesh_sheets: int = 2, - ) -> dict | tuple | bool: + ) -> dict | tuple: """Get segmentation of an object given the segmentation thickness or number of segments. Parameters @@ -1393,14 +1388,11 @@ def objects_segmentation( :class:`ansys.aedt.core.modeler.cad.object_3d.Object3d` class. If mesh sheets are not applied the method returns only the dictionary of segments that the object has been divided into. - ``False`` is returned if the method fails. """ if not segmentation_thickness and not segments: - self.logger.error("Provide at least one option to segment the objects in the list.") - return False + raise ValueError("Provide at least one option to segment the objects in the list.") elif segmentation_thickness and segments: - self.logger.error("Only one segmentation option can be selected.") - return False + raise ValueError("Only one segmentation option can be selected.") assignment = self.convert_to_selections(assignment, True) @@ -1470,7 +1462,7 @@ def change_region_padding( Returns ------- bool - ``True`` if successful, else ``None``. + ``True`` if successful. Examples -------- @@ -1508,7 +1500,7 @@ def change_region_padding( region = self._app.get_oo_object(self._app.oeditor, region_name) if not region: self.logger.error(f"{region} does not exist.") - return False + raise ValueError(f"Region '{region}' does not exist.") create_region_name = region.GetChildNames()[0] self.oeditor.ChangeProperty( list( @@ -1533,11 +1525,10 @@ def change_region_padding( if validation_errors: message = ",".join(validation_errors) - self.logger.error(f"Settings update failed. {message}") - return False + raise AEDTRuntimeError(f"Settings update failed. {message}") return True - except (GrpcApiError, SystemExit): - return False + except (GrpcApiError, SystemExit) as e: + raise AEDTRuntimeError(f"Failed to change region padding: {e}") from e @pyaedt_function_handler() def change_region_coordinate_system(self, assignment: str = "Global", name: str = "Region") -> bool: @@ -1554,7 +1545,7 @@ def change_region_coordinate_system(self, assignment: str = "Global", name: str Returns ------- bool - ``True`` if successful, else ``None``. + ``True`` if successful. Examples -------- @@ -1566,6 +1557,11 @@ def change_region_coordinate_system(self, assignment: str = "Global", name: str try: create_region_name = self._app.get_oo_object(self._app.oeditor, name).GetChildNames()[0] create_region = self._app.get_oo_object(self._app.oeditor, name + "/" + create_region_name) - return create_region.SetPropValue("Coordinate System", assignment) - except (GrpcApiError, SystemExit): - return False + set_value = create_region.SetPropValue("Coordinate System", assignment) + if set_value: + return set_value + else: + raise AEDTRuntimeError("Failed to change region coordinate system.") + + except (GrpcApiError, SystemExit) as e: # pragma: no cover + raise AEDTRuntimeError(f"Failed to change region coordinate system: {e}") from e diff --git a/src/ansys/aedt/core/modeler/modeler_pcb.py b/src/ansys/aedt/core/modeler/modeler_pcb.py index dc3497047ff8..dec18c39f861 100644 --- a/src/ansys/aedt/core/modeler/modeler_pcb.py +++ b/src/ansys/aedt/core/modeler/modeler_pcb.py @@ -33,6 +33,7 @@ from ansys.aedt.core.generic.general_methods import inside_desktop_ironpython_console from ansys.aedt.core.generic.general_methods import pyaedt_function_handler from ansys.aedt.core.generic.settings import settings +from ansys.aedt.core.internal.errors import AEDTRuntimeError from ansys.aedt.core.modeler.cad.modeler import Modeler from ansys.aedt.core.modeler.pcb.object_3d_layout import ComponentsSubCircuit3DLayout from ansys.aedt.core.modeler.pcb.primitives_3d_layout import Primitives3DLayout @@ -296,7 +297,7 @@ def merge_design( y: str = "0.0", z: str = "0.0", rotation: str = "0.0", - ) -> ComponentsSubCircuit3DLayout | bool: + ) -> ComponentsSubCircuit3DLayout: """Merge a design into another. Parameters @@ -330,7 +331,7 @@ def merge_design( except Exception: self.logger.debug(f"Couldn't get component name from component {i}") if not comp_name: - return False + raise AEDTRuntimeError(f"Failed to merge design '{des_name}'. Component not found after paste.") comp = ComponentsSubCircuit3DLayout(self, comp_name) self.components_3d[comp_name] = comp comp.is_3d_placement = True @@ -654,8 +655,7 @@ def unite(self, assignment: str | list) -> bool: self.oeditor.Unite(vArg1) return self.cleanup_objects() else: - self.logger.error("Input list must contain at least two elements.") - return False + raise ValueError("Input list must contain at least two elements.") @pyaedt_function_handler() def intersect(self, assignment: str | list) -> bool: @@ -685,8 +685,7 @@ def intersect(self, assignment: str | list) -> bool: self.oeditor.Intersect(vArg1) return self.cleanup_objects() else: - self.logger.error("Input list must contain at least two elements.") - return False + raise ValueError("Input list must contain at least two elements.") @pyaedt_function_handler() def duplicate(self, assignment: str | list, count: int, vector: list) -> tuple: @@ -772,7 +771,7 @@ def set_temperature_dependence( Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -795,9 +794,8 @@ def set_temperature_dependence( ] try: self._odesign.SetTemperatureSettings(vargs1) - except Exception: - self.logger.error("Failed to enable the temperature dependence.") - return False + except Exception as e: + raise AEDTRuntimeError(f"Failed to enable the temperature dependence: {e}") from e else: self.logger.info("Assigned Objects Temperature") return True @@ -1293,5 +1291,4 @@ def geometry_check_and_fix_all( self.logger.info("Geometry check succeed") return True except Exception: - self.logger.error("Geometry check Failed.") - return False + raise AEDTRuntimeError("Geometry check Failed.") diff --git a/src/ansys/aedt/core/modeler/pcb/object_3d_layout.py b/src/ansys/aedt/core/modeler/pcb/object_3d_layout.py index 5df394a9b753..7a73a854d8a5 100644 --- a/src/ansys/aedt/core/modeler/pcb/object_3d_layout.py +++ b/src/ansys/aedt/core/modeler/pcb/object_3d_layout.py @@ -265,8 +265,7 @@ def create_clearance_on_component(self, extra_soldermask_clearance: float = 5e-3 bool """ if self.prim_type != "component": - self.logger.error("Clearance applies only to components.") - return False + raise ValueError("Clearance applies only to components.") bbox = self.bounding_box start_points = [bbox[0] - extra_soldermask_clearance, bbox[1] - extra_soldermask_clearance] diff --git a/src/ansys/aedt/core/modeler/schematic.py b/src/ansys/aedt/core/modeler/schematic.py index 74333560c62c..66d4a33f4711 100644 --- a/src/ansys/aedt/core/modeler/schematic.py +++ b/src/ansys/aedt/core/modeler/schematic.py @@ -29,6 +29,7 @@ from ansys.aedt.core.generic.constants import AEDT_UNITS from ansys.aedt.core.generic.general_methods import is_linux from ansys.aedt.core.generic.general_methods import pyaedt_function_handler +from ansys.aedt.core.internal.errors import AEDTRuntimeError from ansys.aedt.core.modeler.cad.modeler import Modeler from ansys.aedt.core.modeler.circuits.object_3d_circuit import CircuitComponent from ansys.aedt.core.modeler.circuits.object_3d_circuit import Wire @@ -150,7 +151,7 @@ def connect_schematic_components( Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. References ---------- @@ -171,9 +172,8 @@ def connect_schematic_components( for pstart, pend in zip(pin_starting, pin_ending): try: start[pstart].connect_to_component(end[pend], use_wire=use_wire) - except Exception: - self.logger.error(f"Failed to connect pin {pstart} with {pend}") - return False + except Exception: # pragma: no cover + raise AEDTRuntimeError(f"Failed to connect pin {pstart} with {pend}") return True @pyaedt_function_handler() @@ -285,7 +285,7 @@ def create_text( "Y:=", y_origin, "Size:=", - 12, + text_size, "Angle:=", 0, "Text:=", @@ -345,8 +345,8 @@ def create_text( self.change_text_property(str(text_id), "Rectangle BorderColor", [r3, g3, b3]) self.change_text_property(str(text_id), "Rectangle FillStyle", fill[rect_fill]) return text_out - except Exception: - return False + except Exception as e: + raise AEDTRuntimeError(f"Failed to create text: {e}") from e @pyaedt_function_handler() def change_text_property(self, assignment: str, name: str, value) -> bool: @@ -373,12 +373,10 @@ def change_text_property(self, assignment: str, name: str, value) -> bool: """ graphics_id = [id.split("@")[1] for id in self.oeditor.GetAllGraphics()] if assignment not in graphics_id: - self.logger.error("Invalid id.") - return False + raise ValueError(f"Invalid id '{assignment}'.") if isinstance(value, list) and len(value) == 3: if not isinstance(value[0], int) or not isinstance(value[1], int) or not isinstance(value[2], int): - self.logger.error("Invalid RGB values for color") - return False + raise ValueError("Invalid RGB values for color. All values must be integers.") self.oeditor.ChangeProperty( [ "NAME:AllTabs", @@ -436,8 +434,7 @@ def change_text_property(self, assignment: str, name: str, value) -> bool: ] ) else: - self.logger.error("Wrong Property Value") - return False + raise ValueError(f"Wrong property value for '{name}'.") self.logger.debug(f"Property {name} Changed correctly.") return True @@ -563,7 +560,7 @@ def rename_page(self, page: str | int, name: str) -> bool: self._page_names = [] self._pages = 0 return True - return False + raise ValueError(f"Page '{page}' not found in the schematic.") @property def edb(self) -> "Edb": @@ -631,12 +628,10 @@ def move(self, assignment: list, offset: list, units: str = None) -> bool: """ # TODO: Remove this once https://github.com/ansys/pyaedt/issues/6333 is fixed if is_linux and self._app.desktop_class.non_graphical: - self.logger.error("Move is not supported in non-graphical mode on Linux.") - return False + raise AEDTRuntimeError("Move is not supported in non-graphical mode on Linux.") sels = self._get_components_selections(assignment) if not sels: - self.logger.error("No Component Found.") - return False + raise ValueError("No component found for the given assignment.") if units: x_location = AEDT_UNITS["Length"][units] * float(offset[0]) y_location = AEDT_UNITS["Length"][units] * float(offset[1]) @@ -681,8 +676,7 @@ def rotate(self, assignment: list, degrees: int = 90) -> bool: """ sels = self._get_components_selections(assignment) if not sels: - self.logger.error("No Component Found.") - return False + raise ValueError("No component found for the given assignment.") self.oeditor.Rotate( ["NAME:Selections", "Selections:=", sels], @@ -714,15 +708,6 @@ def __init__(self, app) -> None: self._components = TwinBuilderComponents(self) self.logger.info("ModelerTwinBuilder class has been initialized!") - @property - def components(self) -> TwinBuilderComponents: - """ - .. deprecated:: 0.4.13 - Use :func:`TwinBuilder.modeler.schematic` instead. - - """ - return self._components - @property def schematic(self) -> TwinBuilderComponents: """Schematic Object. diff --git a/src/ansys/aedt/core/modules/mesh_icepak.py b/src/ansys/aedt/core/modules/mesh_icepak.py index 0b5b440a8868..526e495e4882 100644 --- a/src/ansys/aedt/core/modules/mesh_icepak.py +++ b/src/ansys/aedt/core/modules/mesh_icepak.py @@ -1267,14 +1267,14 @@ def assign_priorities(self, assignment: list[list[Object3d | UserDefinedComponen obj_3d = [ o for o in objects - if (isinstance(o, Object3d) and o.is3d) - or (isinstance(o, UserDefinedComponent) and any(p.is3d for p in o.parts.values())) + if (isinstance(o, Object3d) and o.is_3d) + or (isinstance(o, UserDefinedComponent) and any(p.is_3d for p in o.parts.values())) ] obj_2d = [ o for o in objects - if (isinstance(o, Object3d) and not o.is3d) - or (isinstance(o, UserDefinedComponent) and any(not p.is3d for p in o.parts.values())) + if (isinstance(o, Object3d) and not o.is_3d) + or (isinstance(o, UserDefinedComponent) and any(not p.is_3d for p in o.parts.values())) ] if obj_3d: level_3d = { diff --git a/src/ansys/aedt/core/modules/solve_setup.py b/src/ansys/aedt/core/modules/solve_setup.py index 6c73bde0c623..3812d8bb3467 100644 --- a/src/ansys/aedt/core/modules/solve_setup.py +++ b/src/ansys/aedt/core/modules/solve_setup.py @@ -334,6 +334,7 @@ def is_solved(self) -> bool: sol = self._app.post.reports_by_category.standard(expressions=expressions[0], setup=self.name) if identify_setup(self.props): sol.domain = "Time" + return True if sol.get_solution_data() else False @property @@ -374,7 +375,7 @@ def get_solution_data( polyline_points: int = 1001, math_formula: str = None, sweep: str = None, - ) -> "SolutionData": + ) -> "SolutionData" | None: """Get a simulation result from a solved setup and cast it in a ``SolutionData`` object. Data to be retrieved from Electronics Desktop are any simulation results available in that @@ -1720,7 +1721,7 @@ def get_solution_data( polyline_points: int = 1001, math_formula: str = None, sweep: str = None, - ) -> "SolutionData": + ) -> "SolutionData" | None: """Get a simulation result from a solved setup and cast it in a ``SolutionData`` object. Data to be retrieved from Electronics Desktop are any simulation results available in that @@ -1771,7 +1772,7 @@ def get_solution_data( Returns ------- - :class:`ansys.aedt.core.visualization.post.solution_data.SolutionData` + :class:`ansys.aedt.core.visualization.post.solution_data.SolutionData` or ``None`` Solution Data object. References @@ -1988,6 +1989,7 @@ def is_solved(self) -> bool: sol = self._app.post.reports_by_category.standard(expressions=expressions[0], setup=self.name) if identify_setup(props): sol.domain = "Time" + return True if sol.get_solution_data() else False @property diff --git a/src/ansys/aedt/core/modules/solve_sweeps.py b/src/ansys/aedt/core/modules/solve_sweeps.py index 15faccf9b82c..47c53e9fca00 100644 --- a/src/ansys/aedt/core/modules/solve_sweeps.py +++ b/src/ansys/aedt/core/modules/solve_sweeps.py @@ -157,6 +157,7 @@ def is_solved(self) -> bool: sol = self._app._app.post.reports_by_category.standard(setup=f"{self.setup_name} : {self.name}") if identify_setup(self.props): sol.domain = "Time" + return True if sol.get_solution_data() else False @property @@ -440,6 +441,7 @@ def is_solved(self) -> bool: sol = self._app._app.post.reports_by_category.standard(expressions=expressions[0], setup=self.combined_name) if identify_setup(self.props): sol.domain = "Time" + return True if sol.get_solution_data() else False @pyaedt_function_handler() @@ -692,6 +694,7 @@ def is_solved(self) -> bool: `True` if solutions are available. """ sol = self._app._app.post.reports_by_category.standard(setup=f"{self.setup_name} : {self.name}") + return True if sol.get_solution_data() else False @property @@ -925,6 +928,7 @@ def is_solved(self) -> bool: ) if identify_setup(self.props): sol.domain = "Time" + return True if sol.get_solution_data() else False @property diff --git a/src/ansys/aedt/core/q3d.py b/src/ansys/aedt/core/q3d.py index 83d9fcf7d2a5..4ba194ca01ec 100644 --- a/src/ansys/aedt/core/q3d.py +++ b/src/ansys/aedt/core/q3d.py @@ -31,14 +31,12 @@ from ansys.aedt.core.application.analysis_3d import FieldAnalysis3D from ansys.aedt.core.base import PyAedtBase from ansys.aedt.core.generic.file_utils import generate_unique_name -from ansys.aedt.core.generic.general_methods import deprecate_argument from ansys.aedt.core.generic.general_methods import pyaedt_function_handler from ansys.aedt.core.generic.numbers_utils import decompose_variable_value from ansys.aedt.core.generic.settings import settings from ansys.aedt.core.internal.checks import min_aedt_version from ansys.aedt.core.internal.errors import AEDTRuntimeError from ansys.aedt.core.mixins import CreateBoundaryMixin -from ansys.aedt.core.modeler.cad.object_3d import Object3d from ansys.aedt.core.modeler.geometry_operators import GeometryOperators as go from ansys.aedt.core.modules.boundary.common import BoundaryObject from ansys.aedt.core.modules.boundary.hfss_boundary import NearFieldSetup @@ -132,14 +130,14 @@ def __init__( solution_type: str | None = None, setup: str | None = None, version: str | None = None, - non_graphical: bool | None = False, - new_desktop: bool | None = False, - close_on_exit: bool | None = False, - student_version: bool | None = False, - machine: str | None = "", - port: int | None = 0, + non_graphical: bool = False, + new_desktop: bool = False, + close_on_exit: bool = False, + student_version: bool = False, + machine: str = "", + port: int = 0, aedt_process_id: int | None = None, - remove_lock: bool | None = False, + remove_lock: bool = False, ) -> None: FieldAnalysis3D.__init__( self, @@ -364,7 +362,7 @@ def edit_sources( Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. Examples -------- @@ -396,8 +394,7 @@ def edit_sources( for key, vals in cg.items(): if key not in self.excitation_names: - self.logger.error("Not existing net " + key) - return False + raise ValueError(f"Net '{key}' does not exist in excitation names.") source_list.append(key) if isinstance(vals, str): @@ -426,8 +423,7 @@ def edit_sources( for key, vals in acrl.items(): if key not in sources: - self.logger.error("Not existing source " + key) - return False + raise ValueError(f"Source '{key}' does not exist.") source_list.append(key) if isinstance(vals, str): @@ -458,8 +454,7 @@ def edit_sources( for key, vals in dcrl.items(): if key not in sources: # pragma: no cover - self.logger.error("Not existing source " + key) - return False + raise ValueError(f"Source '{key}' does not exist.") source_list.append(key) if isinstance(vals, str): @@ -481,13 +476,11 @@ def edit_sources( for key, vals in harmonic_loss.items(): if key not in sources and key not in self.get_all_sources(): - self.logger.error("Not existing source " + key) - return False + raise ValueError(f"Source '{key}' does not exist.") source_list.append(key) if not isinstance(vals, (tuple, list)): - self.logger.error("Real and Imag part of current must be provided") - return False + raise ValueError("Real and Imag part of current must be provided as a tuple or list.") else: source_real_dataset_names.append(vals[0]) source_imag_dataset_names.append(vals[1]) @@ -597,11 +590,10 @@ def export_matrix_data( Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` when successful. """ if Path(file_name).suffix not in [".m", ".lvl", ".csv", ".txt"]: - self.logger.error("Extension is invalid. Possible extensions are *.m, *.lvl, *.csv, and *.txt.") - return False + raise ValueError("Extension is invalid. Possible extensions are *.m, *.lvl, *.csv, and *.txt.") if not self.modeler._is3d: if problem_type is None: @@ -611,8 +603,7 @@ def export_matrix_data( else: matrix_type_array = matrix_type.split(", ") if not [x for x in matrix_type_array if x in ["Maxwell", "Spice", "Couple"]]: - self.logger.error("Invalid input matrix type. Possible values are Maxwell, Spice, and Couple.") - return False + raise ValueError("Invalid input matrix type. Possible values are Maxwell, Spice, and Couple.") else: problem_type_array = problem_type.split(", ") if [x for x in problem_type_array if x in ["CG", "RL"]]: @@ -625,11 +616,9 @@ def export_matrix_data( else: matrix_type_array = matrix_type.split(", ") if [x for x in matrix_type_array if x == "Spice"]: - self.logger.error("Spice can't be a matrix type if problem type is RL.") - return False + raise ValueError("Spice can't be a matrix type if problem type is RL.") else: - self.logger.error("Invalid problem type. Possible values are CG and RL.") - return False + raise ValueError("Invalid problem type. Possible values are CG and RL.") else: if problem_type is None: @@ -639,8 +628,7 @@ def export_matrix_data( else: matrix_type_array = matrix_type.split(", ") if not [x for x in matrix_type_array if x in ["Maxwell", "Spice", "Couple"]]: - self.logger.error("Invalid input matrix type. Possible values are Maxwell, Spice, and Couple.") - return False + raise ValueError("Invalid input matrix type. Possible values are Maxwell, Spice, and Couple.") else: problem_type_array = problem_type.split(", ") if [x for x in problem_type_array if x in ["C", "AC RL", "DC RL"]]: @@ -653,11 +641,9 @@ def export_matrix_data( else: matrix_type_array = matrix_type.split(", ") if [x for x in matrix_type_array if x == "Spice"]: - self.logger.error("Spice can't be a matrix type if problem type is AC RL or DC RL.") - return False + raise ValueError("Spice can't be a matrix type if problem type is AC RL or DC RL.") else: - self.logger.error("Invalid problem type. Possible values are C, AC RL, and DC RL.") - return False + raise ValueError("Invalid problem type. Possible values are C, AC RL, and DC RL.") if variations is None: nominal_values = self.available_variations.nominal_variation(dependent_params=False) @@ -673,15 +659,13 @@ def export_matrix_data( if setup is None: setup = self.active_setup elif setup != self.active_setup: - self.logger.error("Setup named: %s is invalid. Provide a valid analysis setup name.", setup) - return False + raise ValueError(f"Setup named: '{setup}' is invalid. Provide a valid analysis setup name.") if sweep is None: sweep = self.design_solutions.default_adaptive else: sweep_array = [x.split(": ")[1] for x in self.existing_analysis_sweeps] if sweep.replace(" ", "") not in sweep_array: - self.logger.error("Sweep is invalid. Provide a valid sweep.") - return False + raise ValueError("Sweep is invalid. Provide a valid sweep.") analysis_setup = setup + " : " + sweep.replace(" ", "") if reduce_matrix is None: @@ -689,26 +673,21 @@ def export_matrix_data( else: if self.matrices: if not [matrix for matrix in self.matrices if matrix.name == reduce_matrix]: - self.logger.error("Matrix doesn't exist. Provide an existing matrix.") - return False + raise ValueError("Matrix doesn't exist. Provide an existing matrix.") else: # pragma: no cover - self.logger.error("List of matrix parameters is empty. Cannot export a valid matrix.") - return False + raise ValueError("List of matrix parameters is empty. Cannot export a valid matrix.") if r_unit is None: r_unit = "ohm" else: if not r_unit.endswith("ohm"): - self.logger.error("Provide a valid unit for resistor.") - return False + raise ValueError("Provide a valid unit for resistor.") if not l_unit.endswith("H"): - self.logger.error("Provide a valid unit for inductor.") - return False + raise ValueError("Provide a valid unit for inductor.") if c_unit not in ["fF", "pF", "nF", "uF", "mF", "farad"]: - self.logger.error("Provide a valid unit for capacitance.") - return False + raise ValueError("Provide a valid unit for capacitance.") if g_unit is None: g_unit = "mho" @@ -726,8 +705,7 @@ def export_matrix_data( "perohm", "apV", ]: - self.logger.error("Provide a valid unit for conductance.") - return False + raise ValueError("Provide a valid unit for conductance.") if freq is None: freq = ( @@ -746,15 +724,13 @@ def export_matrix_data( precision = 15 else: if not isinstance(precision, int): - self.logger.error("Precision type must be integer.") - return False + raise ValueError("Precision type must be integer.") if field_width is None: field_width = 20 else: if not isinstance(field_width, int): - self.logger.error("Field width type must be integer.") - return False + raise ValueError("Field width type must be integer.") if use_sci_notation is None: use_sci_notation = 1 @@ -766,8 +742,7 @@ def export_matrix_data( if not self.modeler._is3d: if length_setting not in ["Distributed", "Lumped"]: - self.logger.error("Length setting is invalid.") - return False + raise ValueError("Length setting is invalid.") if length is None: length = "1meter" else: @@ -791,8 +766,7 @@ def export_matrix_data( "uin", "yd", ]: - self.logger.error("Unit length is invalid.") - return False + raise ValueError("Unit length is invalid.") try: self.odesign.ExportMatrixData( str(file_name), @@ -814,9 +788,8 @@ def export_matrix_data( use_sci_notation, ) return True - except Exception: # pragma: no cover - self.logger.error("Export of matrix data was unsuccessful.") - return False + except Exception as e: # pragma: no cover + raise AEDTRuntimeError(f"Export of matrix data was unsuccessful: {e}") from e else: try: self.odesign.ExportMatrixData( @@ -838,9 +811,8 @@ def export_matrix_data( use_sci_notation, ) return True - except Exception: # pragma: no cover - self.logger.error("Export of matrix data was unsuccessful.") - return False + except Exception as e: # pragma: no cover + raise AEDTRuntimeError(f"Export of matrix data was unsuccessful: {e}") from e @pyaedt_function_handler() def export_equivalent_circuit( @@ -1402,14 +1374,14 @@ def __init__( solution_type: str | None = None, setup: str | None = None, version: str | None = None, - non_graphical: bool | None = False, - new_desktop: bool | None = False, - close_on_exit: bool | None = False, - student_version: bool | None = False, - machine: str | None = "", - port: int | None = 0, + non_graphical: bool = False, + new_desktop: bool = False, + close_on_exit: bool = False, + student_version: bool = False, + machine: str = "", + port: int = 0, aedt_process_id: int | None = None, - remove_lock: bool | None = False, + remove_lock: bool = False, ) -> None: self.is3d = True QExtractor.__init__( @@ -1799,7 +1771,7 @@ def assign_net( @pyaedt_function_handler() def source( self, - assignment: str | int | list | Object3d | None = None, + assignment: "str | int | list | Object3d | None" = None, direction: int | None = 0, name: str | None = None, net_name: str | None = None, @@ -1837,7 +1809,7 @@ def source( @pyaedt_function_handler() def sink( self, - assignment: str | int | list | Object3d | None = None, + assignment: "str | int | list | Object3d | None" = None, direction: int | None = 0, name: str | None = None, net_name: str | None = None, @@ -2006,7 +1978,7 @@ def create_setup(self, name: str | None = "MySetupAuto", **kwargs) -> SetupQ3D: @pyaedt_function_handler() def assign_thin_conductor( self, - assignment: str | int | list | Object3d | None = None, + assignment: "str | int | list | Object3d | None" = None, material: str | None = "copper", thickness: float | str | int | None = 1, name: str | None = "", @@ -2569,14 +2541,14 @@ def __init__( solution_type: str | None = None, setup: str | None = None, version: str | None = None, - non_graphical: bool | None = False, - new_desktop: bool | None = False, - close_on_exit: bool | None = False, - student_version: bool | None = False, - machine: str | None = "", - port: int | None = 0, + non_graphical: bool = False, + new_desktop: bool = False, + close_on_exit: bool = False, + student_version: bool = False, + machine: str = "", + port: int = 0, aedt_process_id: int | None = None, - remove_lock: bool | None = False, + remove_lock: bool = False, ) -> None: self.is3d = False QExtractor.__init__( @@ -2601,7 +2573,9 @@ def _init_from_design(self, *args, **kwargs) -> None: self.__init__(*args, **kwargs) @pyaedt_function_handler() - def create_rectangle(self, origin: list, sizes: list, name: str | None = "", material: str | None = "") -> Object3d: + def create_rectangle( + self, origin: list, sizes: list, name: str | None = "", material: str | None = "" + ) -> "Object3d": """Create a rectangle. Parameters @@ -2767,18 +2741,11 @@ def auto_assign_conductors(self) -> bool: return True @pyaedt_function_handler() - @deprecate_argument( - arg_name="analyze", - message="The ``analyze`` argument will be removed in future versions. Analyze before exporting results.", - ) - def export_w_elements(self, analyze: bool = False, export_folder: str | Path | None = None) -> list: + def export_w_elements(self, export_folder: str | Path | None = None) -> list: """Export all W-elements to files. Parameters ---------- - analyze : bool, optional - Whether to analyze before export. Solutions must be present for the design. - The default is ``False``. export_folder : str or :class:`pathlib.Path`, optional Full path to the folder to export files to. The default is ``None``, in which case the working directory is used. @@ -2793,8 +2760,6 @@ def export_w_elements(self, analyze: bool = False, export_folder: str | Path | N export_folder = self.working_directory if not Path(export_folder).exists(): Path(export_folder).mkdir() - if analyze: - self.analyze() setups = self.oanalysis.GetSetups() for s in setups: diff --git a/src/ansys/aedt/core/rmxprt.py b/src/ansys/aedt/core/rmxprt.py index 85dbc7b9a968..daf2095a3d1a 100644 --- a/src/ansys/aedt/core/rmxprt.py +++ b/src/ansys/aedt/core/rmxprt.py @@ -227,14 +227,14 @@ def __init__( model_units: str | None = None, setup: str | None = None, version: str | None = None, - non_graphical: bool | None = False, - new_desktop: bool | None = False, - close_on_exit: bool | None = False, - student_version: bool | None = False, - machine: str | None = "", - port: int | None = 0, + non_graphical: bool = False, + new_desktop: bool = False, + close_on_exit: bool = False, + student_version: bool = False, + machine: str = "", + port: int = 0, aedt_process_id: int | None = None, - remove_lock: bool | None = False, + remove_lock: bool = False, ) -> None: FieldAnalysisRMxprt.__init__( self, diff --git a/src/ansys/aedt/core/twinbuilder.py b/src/ansys/aedt/core/twinbuilder.py index e0d50c6fb34b..bff2459d51af 100644 --- a/src/ansys/aedt/core/twinbuilder.py +++ b/src/ansys/aedt/core/twinbuilder.py @@ -128,14 +128,14 @@ def __init__( solution_type: str | None = None, setup: str | None = None, version: str | None = None, - non_graphical: bool | None = False, - new_desktop: bool | None = False, - close_on_exit: bool | None = False, - student_version: bool | None = False, - machine: str | None = "", - port: int | None = 0, + non_graphical: bool = False, + new_desktop: bool = False, + close_on_exit: bool = False, + student_version: bool = False, + machine: str = "", + port: int = 0, aedt_process_id: int | None = None, - remove_lock: bool | None = False, + remove_lock: bool = False, ) -> None: """Constructor.""" AnalysisTwinBuilder.__init__( @@ -735,8 +735,7 @@ def add_excitation_model( project_name = "$PROJECTDIR/{}.aedt".format(project) maxwell_app = dkp[[project, design]] else: - self.logger.error("Invalid project name or path is provided.") - return False + raise ValueError("Invalid project name or path is provided.") if not setup: setup = self.setups[0] @@ -790,14 +789,12 @@ def add_excitation_model( grid_data = ["NAME:GridData"] maxwell_excitations = {} if not maxwell_app.excitations_by_type["Winding Group"]: - self.logger.error("No voltage or current excitations detected in the design.") - return False + raise ValueError("No voltage or current excitations detected in the design.") elif excitations: if [ e for e in excitations if e not in [me.name for me in maxwell_app.excitations_by_type["Winding Group"]] ]: - self.logger.error("Excitation does not exist in Maxwell design.") - return False + raise ValueError("Excitation does not exist in Maxwell design.") for k in excitations.keys(): if ( not isinstance(excitations[k][0], str) @@ -805,8 +802,7 @@ def add_excitation_model( or excitations[k][2].lower() not in ["current", "voltage"] or not isinstance(excitations[k][3], bool) ): - self.logger.error("Excitation values are not correct or could have a wrong type.") - return False + raise ValueError("Excitation values are not correct or could have a wrong type.") grid_data.append("{}:=".format(k)) grid_data.append(excitations[k]) else: diff --git a/src/ansys/aedt/core/visualization/post/common.py b/src/ansys/aedt/core/visualization/post/common.py index 923d853b2df0..2043677155b9 100644 --- a/src/ansys/aedt/core/visualization/post/common.py +++ b/src/ansys/aedt/core/visualization/post/common.py @@ -1686,7 +1686,7 @@ def get_solution_data( subdesign_id: int | None = None, polyline_points: int = 1001, math_formula: str | None = None, - ) -> "SolutionData": + ) -> "SolutionData" | None: """Get a simulation result from a solved setup and cast it in a ``SolutionData`` object. Data to be retrieved from Electronics Desktop are any simulation results available in that @@ -1746,7 +1746,7 @@ def get_solution_data( Returns ------- - :class:`ansys.aedt.core.visualization.post.solution_data.SolutionData` + :class:`ansys.aedt.core.visualization.post.solution_data.SolutionData` or ``None`` Solution Data object. References diff --git a/src/ansys/aedt/core/visualization/post/farfield_exporter.py b/src/ansys/aedt/core/visualization/post/farfield_exporter.py index d06910aed4ab..b43fc3e282cb 100644 --- a/src/ansys/aedt/core/visualization/post/farfield_exporter.py +++ b/src/ansys/aedt/core/visualization/post/farfield_exporter.py @@ -28,6 +28,7 @@ from ansys.aedt.core.application.analysis_hf import ScatteringMethods from ansys.aedt.core.base import PyAedtBase +from ansys.aedt.core.generic.constants import SolutionsHfss from ansys.aedt.core.generic.constants import unit_converter from ansys.aedt.core.generic.data_handlers import variation_string_to_dict from ansys.aedt.core.generic.file_utils import check_and_download_folder @@ -122,7 +123,9 @@ def __init__( self.__farfield_data = None self.__metadata_file = "" - if self.__app.desktop_class.is_grpc_api and set_phase_center_per_port: + if self.__app.solution_type == SolutionsHfss.SBR and set_phase_center_per_port: + self.__app.logger.debug("In SBR+ phase center can not be modified.") + elif self.__app.desktop_class.is_grpc_api and set_phase_center_per_port: self.__app.set_phase_center_per_port() else: # pragma: no cover self.__app.logger.warning("Set phase center in port location manually.") diff --git a/src/ansys/aedt/core/visualization/post/post_common_3d.py b/src/ansys/aedt/core/visualization/post/post_common_3d.py index 3c9d87ed83e1..1e8b03c2dcca 100644 --- a/src/ansys/aedt/core/visualization/post/post_common_3d.py +++ b/src/ansys/aedt/core/visualization/post/post_common_3d.py @@ -1707,10 +1707,10 @@ def export_mesh_obj( for el in obj_list: object3d = self._app.modeler[el] if on_surfaces: - if not object3d.is3d or (not export_air_objects and object3d.material_name not in ["vacuum", "air"]): + if not object3d.is_3d or (not export_air_objects and object3d.material_name not in ["vacuum", "air"]): mesh_list += [i.id for i in object3d.faces] else: - if not object3d.is3d or (not export_air_objects and object3d.material_name not in ["vacuum", "air"]): + if not object3d.is_3d or (not export_air_objects and object3d.material_name not in ["vacuum", "air"]): mesh_list.append(el) if on_surfaces: plot = self.create_fieldplot_surface(mesh_list, "Mesh", setup, intrinsics) diff --git a/src/ansys/aedt/core/visualization/post/solution_data.py b/src/ansys/aedt/core/visualization/post/solution_data.py index cf168b01491f..8416308d0ae3 100644 --- a/src/ansys/aedt/core/visualization/post/solution_data.py +++ b/src/ansys/aedt/core/visualization/post/solution_data.py @@ -25,7 +25,6 @@ import math import os from typing import TYPE_CHECKING -import warnings import numpy as np @@ -624,30 +623,6 @@ def get_expression_data( sol = sol * np.pi / 180 return x_axis, sol - @pyaedt_function_handler() - def data_real(self, expression: str = None, convert_to_SI: bool = False) -> list: - """Retrieve the real part of the data for an expression. - - .. deprecated:: 0.20.0 - Use :func:`get_expression_data` property instead. - - Parameters - ---------- - expression : str, None - Name of the expression. The default is ``None``, - in which case the active expression is used. - convert_to_SI : bool, optional - Whether to convert the data to the SI unit system. - The default is ``False``. - - Returns - ------- - list - List of the real data for the expression. - """ - warnings.warn("Method `data_real` is deprecated. Use :func:`get_expression_data` property instead.") - return self.get_expression_data(expression, convert_to_SI=convert_to_SI)[1] - @pyaedt_function_handler() def is_real_only(self, expression: str = None) -> bool: """Check if the expression has only real values or not. diff --git a/src/ansys/aedt/core/visualization/report/common.py b/src/ansys/aedt/core/visualization/report/common.py index c530d7c0c0bd..81ccb5dd8cae 100644 --- a/src/ansys/aedt/core/visualization/report/common.py +++ b/src/ansys/aedt/core/visualization/report/common.py @@ -1415,7 +1415,12 @@ def create(self, name: str = None) -> bool: Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` if successful. + + Raises + ------ + AEDTRuntimeError + If there is an error creating the report. """ self._is_created = False if not name: @@ -1427,8 +1432,8 @@ def create(self, name: str = None) -> bool: and "AdaptivePass" not in self.setup and " : Table" not in self.setup ): - self._app.logger.error("Setup doesn't exist in this design.") - return False + raise AEDTRuntimeError("Setup doesn't exist in this design.") + self._post.oreportsetup.CreateReport( self.plot_name, self.report_category, @@ -1741,13 +1746,18 @@ def export_config(self, output_file: str) -> bool: return write_configuration_file(output_dict, output_file) @pyaedt_function_handler() - def get_solution_data(self) -> "SolutionData": + def get_solution_data(self) -> "SolutionData" | None: """Get the report solution data. Returns ------- - :class:`ansys.aedt.core.visualization.post.solution_data.SolutionData` + :class:`ansys.aedt.core.visualization.post.solution_data.SolutionData` or ``None`` Solution data object. + + Raises + ------ + AEDTRuntimeError + If there is an error retrieving the solution data. """ if self._is_created: expr = [i.name for i in self.traces] @@ -1758,13 +1768,13 @@ def get_solution_data(self) -> "SolutionData": expr = [i for i in self.expressions] if not expr: self._app.logger.warning("No Expressions Available. Check inputs") - return False + return None solution_data = self._post.get_solution_data_per_variation( self.report_category, self.setup, self._context, self.variations, expr ) if not solution_data: self._app.logger.warning("No Data Available. Check inputs") - return False + return None if self.primary_sweep: solution_data.primary_sweep = self.primary_sweep return solution_data @@ -1773,7 +1783,9 @@ def get_solution_data(self) -> "SolutionData": def add_limit_line_from_points( self, x_list: list, y_list: list, x_units: str = "", y_units: str = "", y_axis: str = "Y1" ) -> bool: # pragma: no cover - """Add a Cartesian limit line from point lists. This method works only in graphical mode. + """Add a Cartesian limit line from point lists. + + This method works only in graphical mode. Parameters ---------- @@ -1791,37 +1803,44 @@ def add_limit_line_from_points( Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` if successful. + + Raises + ------ + AEDTRuntimeError + If the plot is not created or has no name. """ + self.__check_plot_state() + x_list = [GeometryOperators.parse_dim_arg(str(i) + x_units) for i in x_list] y_list = [GeometryOperators.parse_dim_arg(str(i) + y_units) for i in y_list] - if self.plot_name and self._is_created: - xvals = ["NAME:XValues"] - xvals.extend(x_list) - yvals = ["NAME:YValues"] - yvals.extend(y_list) - self._post.oreportsetup.AddCartesianLimitLine( - self.plot_name, - [ - "NAME:CartesianLimitLine", - xvals, - "XUnits:=", - x_units, - yvals, - "YUnits:=", - y_units, - "YAxis:=", - y_axis, - ], - ) - return True - return False + xvals = ["NAME:XValues"] + xvals.extend(x_list) + yvals = ["NAME:YValues"] + yvals.extend(y_list) + self._post.oreportsetup.AddCartesianLimitLine( + self.plot_name, + [ + "NAME:CartesianLimitLine", + xvals, + "XUnits:=", + x_units, + yvals, + "YUnits:=", + y_units, + "YAxis:=", + y_axis, + ], + ) + return True @pyaedt_function_handler() def add_limit_line_from_equation( self, start_x: float, stop_x: float, step: float, equation: str = "x", units: str = "GHz", y_axis: int = 1 ) -> bool: # pragma: no cover - """Add a Cartesian limit line from point lists. This method works only in graphical mode. + """Add a Cartesian limit line from point lists. + + This method works only in graphical mode. Parameters ---------- @@ -1841,27 +1860,32 @@ def add_limit_line_from_equation( Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` if successful. + + Raises + ------ + AEDTRuntimeError + If the plot is not created or has no name. """ - if self.plot_name and self._is_created: - self._post.oreportsetup.AddCartesianLimitLineFromEquation( - self.plot_name, - [ - "NAME:CartesianLimitLineFromEquation", - "YAxis:=", - int(str(y_axis).replace("Y", "")), - "Start:=", - self._app.value_with_units(start_x, units), - "Stop:=", - self._app.value_with_units(stop_x, units), - "Step:=", - self._app.value_with_units(step, units), - "Equation:=", - equation, - ], - ) - return True - return False + self.__check_plot_state() + + self._post.oreportsetup.AddCartesianLimitLineFromEquation( + self.plot_name, + [ + "NAME:CartesianLimitLineFromEquation", + "YAxis:=", + int(str(y_axis).replace("Y", "")), + "Start:=", + self._app.value_with_units(start_x, units), + "Stop:=", + self._app.value_with_units(stop_x, units), + "Step:=", + self._app.value_with_units(step, units), + "Equation:=", + equation, + ], + ) + return True @pyaedt_function_handler() def add_note(self, text: str, x_position: float = 0.0, y_position: float = 0.0) -> bool: # pragma: no cover @@ -1879,31 +1903,36 @@ def add_note(self, text: str, x_position: float = 0.0, y_position: float = 0.0) Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` if successful. + + Raises + ------ + AEDTRuntimeError + If the plot is not created or has no name. """ + self.__check_plot_state() + note_name = generate_unique_name("Note", n=3) - if self.plot_name and self._is_created: - self._post.oreportsetup.AddNote( - self.plot_name, + self._post.oreportsetup.AddNote( + self.plot_name, + [ + "NAME:NoteDataSource", [ "NAME:NoteDataSource", - [ - "NAME:NoteDataSource", - "SourceName:=", - note_name, - "HaveDefaultPos:=", - True, - "DefaultXPos:=", - x_position, - "DefaultYPos:=", - y_position, - "String:=", - text, - ], + "SourceName:=", + note_name, + "HaveDefaultPos:=", + True, + "DefaultXPos:=", + x_position, + "DefaultYPos:=", + y_position, + "String:=", + text, ], - ) - return True - return False + ], + ) + return True @pyaedt_function_handler() def add_cartesian_x_marker(self, value: str, name: str | None = None) -> str: # pragma: no cover @@ -1961,9 +1990,9 @@ def add_cartesian_y_marker(self, value: str, name: str | None = None, y_axis: in @pyaedt_function_handler() def _change_property(self, tab_name, property_name, property_val) -> bool: - if not self._is_created: - self._app.logger.error("Plot has not been created. Create it and then change the properties.") - return False + """Change a property value in the plot properties.""" + self.__check_plot_state() + arg = [ "NAME:AllTabs", ["NAME:" + tab_name, ["NAME:PropServers", f"{self.plot_name}:{property_name}"], property_val], @@ -2218,7 +2247,12 @@ def hide_legend( Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` if successful. + + Raises + ------ + AEDTRuntimeError + If the legend cannot be hidden. """ try: oo = self._app.get_oo_object(self._post.oreportsetup, self.plot_name) @@ -2229,9 +2263,8 @@ def hide_legend( legend.SetPropValue("Font/Height", font_size) legend.SetPropValue("Header Row Font/Height", font_size) return True - except Exception: - self._app.logger.error("Failed to hide legend.") - return False + except Exception as e: + raise AEDTRuntimeError(f"Failed to hide legend. Error: {str(e)}") from e @pyaedt_function_handler() def edit_y_axis( @@ -2561,7 +2594,16 @@ def import_traces(self, input_file: str, plot_name: str) -> bool: Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` if successful. + + Raises + ------ + FileExistsError + If the input file does not exist. + ValueError + If the plot name is not provided or does not exist in the current report. + AEDTRuntimeError + If there is an error importing the traces. """ if not os.path.exists(input_file): msg = "File does not exist." @@ -2590,8 +2632,8 @@ def import_traces(self, input_file: str, plot_name: str) -> bool: else: self._post.oreportsetup.ImportIntoReport(self.plot_name, input_file) return True - except Exception: - return False + except Exception as e: + raise AEDTRuntimeError(f"Failed to import traces. Error: {str(e)}") from e @pyaedt_function_handler() def delete_traces(self, plot_name: str, traces_list: list) -> bool: @@ -2607,7 +2649,14 @@ def delete_traces(self, plot_name: str, traces_list: list) -> bool: Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` if successful. + + Raises + ------ + ValueError + If the plot does not exist in the current project or if a trace does not exist in the selected plot. + AEDTRuntimeError + If there is an error deleting the traces. """ if plot_name not in self._post.all_report_names: raise ValueError("Plot does not exist in current project.") @@ -2621,8 +2670,8 @@ def delete_traces(self, plot_name: str, traces_list: list) -> bool: self._post.oreportsetup.DeleteTraces(props) self._initialize_tree_node() return True - except Exception: - return False + except Exception as e: + raise AEDTRuntimeError(f"Failed to delete traces. Error: {str(e)}") from e @pyaedt_function_handler() def add_trace_to_report( @@ -2646,7 +2695,12 @@ def add_trace_to_report( Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` if successful. + + Raises + ------ + AEDTRuntimeError + If there is an error adding the trace to the report. """ try: self._post.oreportsetup.AddTraces( @@ -2658,8 +2712,8 @@ def add_trace_to_report( ) self._initialize_tree_node() return True - except Exception: - return False + except Exception as e: + raise AEDTRuntimeError(f"Failed to add trace to report. Error: {str(e)}") from e @pyaedt_function_handler() def update_trace_in_report( @@ -2681,7 +2735,12 @@ def update_trace_in_report( Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` if successful. + + Raises + ------ + AEDTRuntimeError + If there is an error updating the trace in the report. """ expr = copy.deepcopy(self.expressions) self.expressions = traces @@ -2696,8 +2755,8 @@ def update_trace_in_report( self._trace_info(), ) return True - except Exception: - return False + except Exception as e: + raise AEDTRuntimeError(f"Failed to update trace in report. Error: {str(e)}") from e finally: self.expressions = expr @@ -2718,30 +2777,34 @@ def apply_report_template(self, input_file: str, property_type: str = "Graphical Returns ------- bool - ``True`` when successful, ``False`` when failed. + ``True`` if successful. + + Raises + ------ + FileExistsError + If the input file does not exist. + ValueError + If the value for `property_type` is invalid. + AEDTRuntimeError + If the extension of the input file is not supported. References ---------- >>> oModule.ApplyReportTemplate """ if not os.path.exists(input_file): # pragma: no cover - msg = "File does not exist." - self._post.logger.error(msg) - return False + raise FileExistsError("File does not exist.") split_path = os.path.splitext(input_file) extension = split_path[1] supported_ext = [".rpt"] if extension not in supported_ext: # pragma: no cover - msg = f"Extension {extension} is not supported." - self._post.logger.error(msg) - return False + raise AEDTRuntimeError(f"Extension {extension} is not supported.") if property_type not in ["Graphical", "Data", "All"]: # pragma: no cover - msg = "Invalid value for `property_type`. The value must be 'Graphical', 'Data', or 'All'." - self._post.logger.error(msg) - return False + raise ValueError("Invalid value for `property_type`. The value must be 'Graphical', 'Data', or 'All'.") + self._post.oreportsetup.ApplyReportTemplate(self.plot_name, input_file, property_type) return True @@ -2811,3 +2874,8 @@ def export_table_to_file(self, plot_name: str, output_file: str, table_type: str def __props_with_default(dict_in, key, default_value=None): """Update dictionary value.""" return dict_in[key] if dict_in.get(key, None) is not None else default_value + + def __check_plot_state(self): + """Check if the plot is created and has a name.""" + if not self._is_created or not self.plot_name: + raise AEDTRuntimeError("Plot has not been created. Create it for further operations.") diff --git a/tests/system/general/test_2d_modeler.py b/tests/system/general/test_2d_modeler.py index b766ab6dae84..224d8c6056c1 100644 --- a/tests/system/general/test_2d_modeler.py +++ b/tests/system/general/test_2d_modeler.py @@ -214,6 +214,11 @@ def test_create_regular_polygon(aedt_app) -> None: assert pg2.is_conductor assert is_close(pg2.faces[0].area, 5.196152422706631) + with pytest.raises(ValueError): + aedt_app.modeler.create_regular_polygon( + origin=[0, 0, 0], start_point=[0, 2, 0], num_sides=1, name="MyPolygon", material="Copper" + ) + @pytest.mark.skipif(is_linux or sys.version_info < (3, 8), reason="Not running in ironpython") def test_plot(aedt_app, test_tmp_dir) -> None: diff --git a/tests/system/general/test_3d_modeler.py b/tests/system/general/test_3d_modeler.py index a3606970e222..992b921805df 100644 --- a/tests/system/general/test_3d_modeler.py +++ b/tests/system/general/test_3d_modeler.py @@ -34,6 +34,7 @@ from ansys.aedt.core.generic.math_utils import MathUtils from ansys.aedt.core.generic.numbers_utils import decompose_variable_value from ansys.aedt.core.generic.quaternion import Quaternion +from ansys.aedt.core.internal.errors import AEDTRuntimeError from ansys.aedt.core.modeler.cad.elements_3d import FacePrimitive from ansys.aedt.core.modeler.cad.elements_3d import VertexPrimitive from ansys.aedt.core.modeler.cad.modeler import FaceCoordinateSystem @@ -117,7 +118,8 @@ def test_split(aedt_app) -> None: assert isinstance(split, list) assert isinstance(split[0], str) obj_split = [obj for obj in aedt_app.modeler.object_list if obj.name == split[1]][0] - assert not aedt_app.modeler.split(assignment=obj_split) + with pytest.raises(ValueError): + aedt_app.modeler.split(assignment=obj_split) box4 = aedt_app.modeler.create_box([20, 20, 20], [20, 20, 20], "box_to_split4") poly2 = aedt_app.modeler.create_polyline(points=[[35, 16, 30], [30, 25, 30], [30, 45, 30]], segment_type="Arc") split = aedt_app.modeler.split(assignment=box4, sides="Both", tool=poly2.name) @@ -343,7 +345,8 @@ def test_create_face_list(coaxial) -> None: assert coaxial.modeler.create_face_list(fl, "my_face_list") == fl2 assert coaxial.modeler.create_face_list(fl) assert coaxial.modeler.create_face_list([str(fl[0])]) - assert not coaxial.modeler.create_face_list(["outer2"]) + with pytest.raises(AEDTRuntimeError): + coaxial.modeler.create_face_list(["outer2"]) def test_create_object_list(coaxial) -> None: @@ -362,7 +365,8 @@ def test_create_object_list(coaxial) -> None: assert coaxial.modeler.user_lists[-1].rename("new_list") assert coaxial.modeler.user_lists[-1].delete() assert coaxial.modeler.create_object_list(["Core", "outer"]) - assert not coaxial.modeler.create_object_list(["Core2", "Core3"]) + with pytest.raises(AEDTRuntimeError): + coaxial.modeler.create_object_list(["Core2", "Core3"]) def test_create_outer_face_list(aedt_app) -> None: @@ -1117,25 +1121,28 @@ def test_region_property(aedt_app) -> None: def test_region_property_failing(aedt_app) -> None: aedt_app.modeler.create_air_region() - assert not aedt_app.modeler.change_region_coordinate_system(assignment="NoCS") - assert not aedt_app.modeler.change_region_padding( - "10mm", padding_type="Absolute Offset", direction="-X", region_name="NoRegion" - ) + with pytest.raises(AEDTRuntimeError): + aedt_app.modeler.change_region_coordinate_system(assignment="NoCS") + with pytest.raises(ValueError): + aedt_app.modeler.change_region_padding( + "10mm", padding_type="Absolute Offset", direction="-X", region_name="NoRegion" + ) with pytest.raises(Exception, match="Check ``axes`` input."): aedt_app.modeler.change_region_padding("10mm", padding_type="Absolute Offset", direction="X") with pytest.raises(Exception, match="Check ``padding_type`` input."): aedt_app.modeler.change_region_padding("10mm", padding_type="Partial Offset", direction="+X") - assert not aedt_app.modeler.change_region_padding( - ["1mm", "-2mm", "3mm", "-4mm", "5mm", "-6mm"], - padding_type=[ - "Absolute Position", - "Percentage Offset", - "Absolute Position", - "Absolute Position", - "Absolute Position", - "Absolute Position", - ], - ) + with pytest.raises(AEDTRuntimeError): + aedt_app.modeler.change_region_padding( + ["1mm", "-2mm", "3mm", "-4mm", "5mm", "-6mm"], + padding_type=[ + "Absolute Position", + "Percentage Offset", + "Absolute Position", + "Absolute Position", + "Absolute Position", + "Absolute Position", + ], + ) def test_sweep_along_normal(coaxial) -> None: @@ -1211,12 +1218,18 @@ def test_create_conical_rings(aedt_app) -> None: assert isinstance(rings2, list) rings3 = aedt_app.modeler.create_conical_rings("Y", position, 20, 10, 20, 1) assert isinstance(rings3, list) - assert not aedt_app.modeler.create_conical_rings("Y", position, 10, 20, 20, 1) - assert not aedt_app.modeler.create_conical_rings("Z", position, -20, 10, 20, 1) - assert not aedt_app.modeler.create_conical_rings("Z", position, 20, -10, 20, 1) - assert not aedt_app.modeler.create_conical_rings("Z", position, 20, 10, 0, 1) - assert not aedt_app.modeler.create_conical_rings("Z", position, 20, 10, 20, 0) - assert not aedt_app.modeler.create_conical_rings("Z", [0], 20, 10, 20, 0) + with pytest.raises(ValueError): + aedt_app.modeler.create_conical_rings("Y", position, 10, 20, 20, 1) + with pytest.raises(ValueError): + aedt_app.modeler.create_conical_rings("Z", position, -20, 10, 20, 1) + with pytest.raises(ValueError): + aedt_app.modeler.create_conical_rings("Z", position, 20, -10, 20, 1) + with pytest.raises(ValueError): + aedt_app.modeler.create_conical_rings("Z", position, 20, 10, 0, 1) + with pytest.raises(ValueError): + aedt_app.modeler.create_conical_rings("Z", position, 20, 10, 20, 0) + with pytest.raises(ValueError): + aedt_app.modeler.create_conical_rings("Z", [0], 20, 10, 20, 0) def test_get_group_bounding_box_with_non_existing_group_name(aedt_app) -> None: @@ -1361,7 +1374,8 @@ def test_project_sheet_failure(aedt_app) -> None: rect = aedt_app.modeler.create_rectangle(Plane.XY, [-5, -5, 15], [10, 20], "sheet_project_operation") box_0 = aedt_app.modeler.create_box([-10, -10, -10], [20, 20, 20], "box_project_operation_0") - assert not aedt_app.modeler.project_sheet(rect, box_0, 5, "10deg") + with pytest.raises(AEDTRuntimeError): + aedt_app.modeler.project_sheet(rect, box_0, 5, "10deg") aedt_app.modeler.delete(aedt_app.modeler.object_names) diff --git a/tests/system/general/test_circuit.py b/tests/system/general/test_circuit.py index e9b5c312d634..a97119b3283c 100644 --- a/tests/system/general/test_circuit.py +++ b/tests/system/general/test_circuit.py @@ -600,6 +600,9 @@ def test_netlist_data_block(aedt_app, test_tmp_dir) -> None: lna.props["SweepDefinition"]["Data"] = "LINC 0Hz 1GHz 101" assert aedt_app.analyze() + with pytest.raises(FileNotFoundError): + aedt_app.add_netlist_datablock(test_tmp_dir / "invented.net") + def test_create_voltage_probe(aedt_app) -> None: myprobe = aedt_app.modeler.schematic.create_voltage_probe(name="voltage_probe") @@ -784,6 +787,12 @@ def test_assign_sources(aedt_app, test_tmp_dir) -> None: c.sources["freq_pyaedt"].delete() assert len(c.source_objects) == 5 + with pytest.raises(ValueError): + c.create_source(source_type="PowerSin", name=c.source_names[0]) + + with pytest.raises(ValueError): + c.create_source(source_type="Invented") + def test_assign_excitations(aedt_app) -> None: c = aedt_app @@ -912,7 +921,6 @@ def test_create_and_change_prop_text(aedt_app) -> None: assert aedt_app.modeler.create_text("text test", "1000mil", "-2000mil") -@pytest.mark.skipif(NON_GRAPHICAL, reason="Change property doesn't work in non-graphical mode.") @pytest.mark.skipif(is_linux and DESKTOP_VERSION == "2024.1", reason="Schematic has to be closed.") def test_change_text_property(aedt_app) -> None: _ = aedt_app.modeler.create_text("text test") @@ -920,11 +928,14 @@ def test_change_text_property(aedt_app) -> None: assert aedt_app.modeler.change_text_property(text_id, "Font", "Calibri") assert aedt_app.modeler.change_text_property(text_id, "DisplayRectangle", True) assert aedt_app.modeler.change_text_property(text_id, "Color", [255, 120, 0]) - assert not aedt_app.modeler.change_text_property(text_id, "Color", ["255", 120, 0]) + with pytest.raises(ValueError): + aedt_app.modeler.change_text_property(text_id, "Color", ["255", 120, 0]) assert aedt_app.modeler.change_text_property(text_id, "Location", ["-5000mil", "2000mil"]) assert aedt_app.modeler.change_text_property(text_id, "Location", [5000, 2000]) - assert not aedt_app.modeler.change_text_property(1, "Color", [255, 120, 0]) - assert not aedt_app.modeler.change_text_property(text_id, "Invalid", {}) + with pytest.raises(ValueError): + aedt_app.modeler.change_text_property(1, "Color", [255, 120, 0]) + with pytest.raises(ValueError): + aedt_app.modeler.change_text_property(text_id, "Invalid", {}) # TODO: enable test when 'cutout_multizone_layout' method is fixed. @@ -988,12 +999,10 @@ def test_automatic_lna(aedt_app, test_tmp_dir) -> None: auto_assign_diff_pairs=True, separation=".", pattern=["component", "pin", "net"], - analyze=False, ) assert status -@pytest.mark.skipif(NON_GRAPHICAL and is_linux, reason="Method is not working in Linux and non-graphical mode.") def test_automatic_tdr(aedt_app, test_tmp_dir) -> None: touchstone_1 = shutil.copy2(TOUCHSTONE_FILE_CUSTOM, test_tmp_dir / TOUCHSTONE_CUSTOM) result = aedt_app.create_tdr_schematic_from_snp( @@ -1030,7 +1039,6 @@ def test_automatic_tdr(aedt_app, test_tmp_dir) -> None: assert isinstance(result, list) -@pytest.mark.skipif(NON_GRAPHICAL and is_linux, reason="Method not working in Linux and Non graphical.") def test_automatic_ami(aedt_app, test_tmp_dir) -> None: touchstone_1 = shutil.copy2(TOUCHSTONE_FILE_CUSTOM, test_tmp_dir / TOUCHSTONE_CUSTOM) @@ -1054,7 +1062,6 @@ def test_automatic_ami(aedt_app, test_tmp_dir) -> None: bit_pattern="random_bit_count=2.5e3 random_seed=1", unit_interval="31.25ps", use_convolution=True, - analyze=False, design_name="AMI", ) assert result @@ -1073,13 +1080,11 @@ def test_automatic_ami(aedt_app, test_tmp_dir) -> None: bit_pattern="random_bit_count=2.5e3 random_seed=1", unit_interval="31.25ps", use_convolution=True, - analyze=False, design_name="AMI_Differential", ) assert result -@pytest.mark.skipif(NON_GRAPHICAL and is_linux, reason="Method not working in Linux and Non graphical.") def test_automatic_ibis(aedt_app, test_tmp_dir) -> None: touchstone_1 = shutil.copy2(TOUCHSTONE_FILE_CUSTOM, test_tmp_dir / TOUCHSTONE_CUSTOM) ibis_file_o = TESTS_GENERAL_PATH / "example_models" / "T15" / "ansys_ddr4.ibs" @@ -1096,12 +1101,24 @@ def test_automatic_ibis(aedt_app, test_tmp_dir) -> None: bit_pattern="random_bit_count=2.5e3 random_seed=1", unit_interval="31.25ps", use_convolution=True, - analyze=False, design_name="AMI", ) assert result +def test_automatic_ibis_no_component_raises(aedt_app) -> None: + ibis_file_o = TESTS_GENERAL_PATH / "example_models" / "T15" / "ansys_ddr4.ibs" + with pytest.raises(AEDTRuntimeError): + aedt_app.create_ibis_schematic_from_pins( + ibis_tx_file=str(ibis_file_o), + tx_buffer_name="ansys_ddr4_odt34", + rx_buffer_name="ansys_ddr4_odt40", + tx_schematic_pins=["fake_pin"], + rx_schematic_pins=["fake_pin"], + differential=False, + ) + + def test_enforce_touchstone_passive(aedt_app, test_tmp_dir) -> None: aedt_app.modeler.schematic_units = "mil" touchstone_1 = shutil.copy2(TOUCHSTONE_FILE_CUSTOM, test_tmp_dir / TOUCHSTONE_CUSTOM) @@ -1129,7 +1146,8 @@ def test_change_symbol_pin_location(aedt_app, test_tmp_dir) -> None: } assert ts_component.change_symbol_pin_locations(pin_locations) pin_locations = {"left": [pins[0].name, pins[1].name, pins[2].name], "right": [pins[5].name]} - assert not ts_component.change_symbol_pin_locations(pin_locations) + with pytest.raises(ValueError): + ts_component.change_symbol_pin_locations(pin_locations) def test_import_asc(aedt_app, test_tmp_dir) -> None: @@ -1150,13 +1168,17 @@ def test_import_table(aedt_app) -> None: file_header = TESTS_GENERAL_PATH / "example_models" / TEST_SUBFOLDER / "table_header.csv" file_invented = "invented.csv" - assert not aedt_app.import_table(file_header, column_separator="dummy") - assert not aedt_app.import_table(file_invented) + with pytest.raises(ValueError): + aedt_app.import_table(file_header, column_separator="dummy") + + with pytest.raises(FileNotFoundError): + aedt_app.import_table(file_invented) table = aedt_app.import_table(file_header) assert table in aedt_app.existing_analysis_sweeps - assert not aedt_app.delete_imported_data("invented") + with pytest.raises(ValueError): + aedt_app.delete_imported_data("invented") assert aedt_app.delete_imported_data(table) assert table not in aedt_app.existing_analysis_sweeps diff --git a/tests/system/general/test_hfss.py b/tests/system/general/test_hfss.py index 1822ed51377d..75b1cd7913c3 100644 --- a/tests/system/general/test_hfss.py +++ b/tests/system/general/test_hfss.py @@ -338,6 +338,15 @@ def test_create_linear_count_sweep(aedt_app) -> None: assert "der_var" in setup3.get_derivative_variables() setup3.delete() + with pytest.raises(AEDTRuntimeError): + aedt_app.create_linear_count_sweep( + setup="invented", + unit="MHz", + start_frequency=1.1e3, + stop_frequency=1200.1, + num_of_freq_points=1234, + ) + def test_setup_exists(aedt_app) -> None: aedt_app.create_setup("MySetup", Frequency="1GHz") @@ -400,6 +409,16 @@ def test_create_linear_step_sweep(aedt_app) -> None: == "Invalid value for 'sweep_type'. The value must be 'Discrete', 'Interpolating', or 'Fast'." ) + with pytest.raises(AEDTRuntimeError): + aedt_app.create_linear_step_sweep( + setup="invented", + name="StepFast", + unit=units, + start_frequency=freq_start, + stop_frequency=freq_stop, + step_size=step_size, + ) + def test_create_single_point_sweep(aedt_app) -> None: setup = aedt_app.create_setup("MySetup", Frequency="1GHz", BasisOrder=2) @@ -440,6 +459,11 @@ def test_create_single_point_sweep(aedt_app) -> None: setup="MySetup", unit="GHz", freq=[1, 2e2, 3.4], save_single_field=[True, False] ) + with pytest.raises(AEDTRuntimeError): + aedt_app.create_single_point_sweep( + setup="invented", unit="GHz", freq=[1, 2e2, 3.4], save_single_field=[True, False] + ) + def test_delete_setup(aedt_app) -> None: setup_name = "SetupToDelete" @@ -1510,7 +1534,9 @@ def test_set_differential_pair(diff_pairs_app) -> None: active=True, matched=False, ) - assert not diff_pairs_app.set_differential_pair(assignment="P2_T1", reference="P2_T3") + with pytest.raises(AEDTRuntimeError): + diff_pairs_app.set_differential_pair(assignment="P2_T1", reference="P2_T3") + diff_pairs_app.set_active_design(TRANSIENT_PROJECT) assert diff_pairs_app.set_differential_pair( assignment="P2_T1", @@ -1521,7 +1547,9 @@ def test_set_differential_pair(diff_pairs_app) -> None: active=True, matched=False, ) - assert not diff_pairs_app.set_differential_pair(assignment="P2_T1", reference="P2_T3") + + with pytest.raises(AEDTRuntimeError): + diff_pairs_app.set_differential_pair(assignment="P2_T1", reference="P2_T3") @pytest.mark.skipif( @@ -1868,8 +1896,11 @@ def test_set_phase_center_per_port(aedt_app) -> None: assert not aedt_app.set_phase_center_per_port() assert not aedt_app.set_phase_center_per_port(["Global", "Global"]) - assert not aedt_app.set_phase_center_per_port(["Global"]) - assert not aedt_app.set_phase_center_per_port("Global") + with pytest.raises(ValueError): + aedt_app.set_phase_center_per_port(["Global"]) + + with pytest.raises(TypeError): + aedt_app.set_phase_center_per_port("Global") @pytest.mark.skipif( diff --git a/tests/system/general/test_maxwell_3d.py b/tests/system/general/test_maxwell_3d.py index db2c1a9a2463..3c66bfde8eef 100644 --- a/tests/system/general/test_maxwell_3d.py +++ b/tests/system/general/test_maxwell_3d.py @@ -971,10 +971,12 @@ def test_objects_segmentation(m3d_app) -> None: / segmentation_thickness ) assert len(sheets[0][cylinder.name]) == segments_number - 1 - assert not m3d_app.modeler.objects_segmentation(cylinder.name) - assert not m3d_app.modeler.objects_segmentation( - cylinder.name, segmentation_thickness=segmentation_thickness, segments=segments_number - ) + with pytest.raises(ValueError): + m3d_app.modeler.objects_segmentation(cylinder.name) + with pytest.raises(ValueError): + m3d_app.modeler.objects_segmentation( + cylinder.name, segmentation_thickness=segmentation_thickness, segments=segments_number + ) cylinder = m3d_app.modeler.create_cylinder(Axis.Z, [3, 0, 0], 5, 10, 0, "cyl") segments_number = 10 diff --git a/tests/system/general/test_maxwell_circuit.py b/tests/system/general/test_maxwell_circuit.py index d952479472e6..80ba67757afd 100644 --- a/tests/system/general/test_maxwell_circuit.py +++ b/tests/system/general/test_maxwell_circuit.py @@ -93,7 +93,8 @@ def test_export_netlist(aedt_app, add_app, test_tmp_dir) -> None: assert aedt_app.export_netlist_from_schematic(str(netlist_file)) == str(netlist_file) assert netlist_file.exists() netlist_file_invalid = test_tmp_dir / "export_netlist.sh" - assert not aedt_app.export_netlist_from_schematic(str(netlist_file_invalid)) + with pytest.raises(ValueError): + aedt_app.export_netlist_from_schematic(str(netlist_file_invalid)) m2d = add_app(design="test", application=Maxwell2d, project=aedt_app.project_name, close_projects=False) m2d.solution_type = SolutionsMaxwell2D.TransientZ m2d.modeler.create_circle([0, 0, 0], 10, name="Circle_inner") diff --git a/tests/system/general/test_primitives_2d.py b/tests/system/general/test_primitives_2d.py index ccb7e363b907..e3aa42133041 100644 --- a/tests/system/general/test_primitives_2d.py +++ b/tests/system/general/test_primitives_2d.py @@ -126,8 +126,8 @@ def test_create_region(aedt_app) -> None: assert region.object_type == "Sheet" assert region.solve_inside - region = aedt_app.modeler.create_region([100, 100, 100, 100, 100, 100]) - assert not region + with pytest.raises(ValueError): + aedt_app.modeler.create_region([100, 100, 100, 100, 100, 100]) def test_create_region_Z(axisymmetrical_app) -> None: @@ -150,6 +150,9 @@ def test_create_region_Z(axisymmetrical_app) -> None: assert axisymmetrical_app.modeler.create_region("10mm", False) axisymmetrical_app.modeler["Region"].delete() + with pytest.raises(ValueError): + axisymmetrical_app.modeler.create_region([100, 50, 20, 10]) + def test_assign_material_ceramic(aedt_app) -> None: material = "Ceramic_material" diff --git a/tests/system/general/test_primitives_3d.py b/tests/system/general/test_primitives_3d.py index 503918e1296e..7a687b9f05fc 100644 --- a/tests/system/general/test_primitives_3d.py +++ b/tests/system/general/test_primitives_3d.py @@ -97,7 +97,7 @@ def encrypted_app(add_app_example): def create_copper_box(app, name: str = "MyBox"): """Create a copper box.""" - if app.modeler[name]: + if name in app.modeler.object_list: app.modeler.delete(name) new_object = app.modeler.create_box([0, 0, 0], [10, 10, 5], name, "Copper") return new_object @@ -105,7 +105,7 @@ def create_copper_box(app, name: str = "MyBox"): def create_copper_cylinder(app, name: str = "MyCyl"): """Create a copper cylinder.""" - if app.modeler[name]: + if name in app.modeler.object_list: app.modeler.delete(name) new_object = app.modeler.create_cylinder( orientation="Y", origin=[20, 20, 0], radius=5, height=20, num_sides=8, name=name, material="Copper" @@ -115,7 +115,7 @@ def create_copper_cylinder(app, name: str = "MyCyl"): def create_rectangle(app, name: str = "MyRectangle"): """Create a rectangle.""" - if app.modeler[name]: + if name in app.modeler.object_list: app.modeler.delete(name) plane = Plane.XY new_object = app.modeler.create_rectangle(plane, [5, 3, 8], [4, 5], name=name) @@ -124,7 +124,7 @@ def create_rectangle(app, name: str = "MyRectangle"): def create_copper_torus(app, name: str = "MyTorus"): """Create a copper torus.""" - if app.modeler[name]: + if name in app.modeler.object_list: app.modeler.delete(name) new_object = app.modeler.create_torus( [30, 30, 0], major_radius=1.2, minor_radius=0.5, axis="Z", name=name, material="Copper" @@ -587,7 +587,7 @@ def test_create_polyline_with_crosssection(aedt_app) -> None: assert isinstance(polyline, Polyline) assert aedt_app.modeler[polyline.id].object_type == "Solid" - assert aedt_app.modeler[polyline.id].is3d + assert aedt_app.modeler[polyline.id].is_3d def test_sweep_along_path_with_single_assignment(aedt_app) -> None: @@ -946,9 +946,16 @@ def test_get_model_objects(aedt_app) -> None: def test_create_rect_sheet_to_ground_with_ground_name(aedt_app) -> None: """Test create rectangle sheet to ground.""" - create_copper_box(aedt_app, name="MyBox_to_gnd") + new = create_copper_box(aedt_app, name="MyBox_to_gnd") - ground_plane = aedt_app.modeler.create_sheet_to_ground("MyBox_to_gnd") + # Not ground created + with pytest.raises(AEDTRuntimeError): + aedt_app.modeler.create_sheet_to_ground(new.name) + + # Create a ground plane below the box (larger and at a lower position on the Z axis) + aedt_app.modeler.create_rectangle(Plane.XY, [-5, -5, -2], [20, 20], name="GroundPlane_to_gnd") + + ground_plane = aedt_app.modeler.create_sheet_to_ground(new.name) assert isinstance(ground_plane, Object3d) assert ground_plane.id > 0 @@ -1523,7 +1530,8 @@ def test_create_3dcomponent(aedt_app, test_tmp_dir) -> None: input_file = test_tmp_dir / "new" / COMPONENT_3D_FILE # Folder doesn't exist. Cannot create component. - assert not aedt_app.modeler.create_3dcomponent(str(input_file), create_folder=False) + with pytest.raises(FileNotFoundError): + aedt_app.modeler.create_3dcomponent(str(input_file), create_folder=False) # By default, the new folder is created. assert aedt_app.modeler.create_3dcomponent(str(input_file)) @@ -1564,20 +1572,22 @@ def test_create_3d_component_encrypted(aedt_app, test_tmp_dir) -> None: password="password_test", hide_contents=["Solid"], ) - assert not aedt_app.modeler.create_3dcomponent( - str(input_file), - coordinate_systems="Global", - is_encrypted=True, - password="password_test", - password_type="Invalid", - ) - assert not aedt_app.modeler.create_3dcomponent( - str(input_file), - coordinate_systems="Global", - is_encrypted=True, - password="password_test", - component_outline="Invalid", - ) + with pytest.raises(ValueError): + aedt_app.modeler.create_3dcomponent( + str(input_file), + coordinate_systems="Global", + is_encrypted=True, + password="password_test", + password_type="Invalid", + ) + with pytest.raises(ValueError): + aedt_app.modeler.create_3dcomponent( + str(input_file), + coordinate_systems="Global", + is_encrypted=True, + password="password_test", + component_outline="Invalid", + ) def test_create_equationbased_curve(aedt_app) -> None: @@ -1707,7 +1717,7 @@ def test_create_torus(aedt_app) -> None: assert torus.id > 0 assert torus.name.startswith("MyTorus") assert torus.object_type == "Solid" - assert torus.is3d is True + assert torus.is_3d is True def test_create_torus_exceptions(aedt_app) -> None: diff --git a/tests/system/general/test_q2d.py b/tests/system/general/test_q2d.py index 92a52995cde6..ebab59677bb0 100644 --- a/tests/system/general/test_q2d.py +++ b/tests/system/general/test_q2d.py @@ -164,7 +164,8 @@ def test_edit_sources(q2d_matrix) -> None: sources_ac = {"Circle3": ("100A", "5deg")} assert q2d_matrix.edit_sources(sources_cg, sources_ac) sources_ac = {"Circle5": "40A"} - assert not q2d_matrix.edit_sources(sources_cg, sources_ac) + with pytest.raises(ValueError): + q2d_matrix.edit_sources(sources_cg, sources_ac) def test_get_all_conductors(aedt_app) -> None: @@ -185,11 +186,12 @@ def test_export_matrix_data(q2d_solved, test_tmp_dir) -> None: problem_type="CG", matrix_type="Maxwell, Spice, Couple", ) - assert not q2d_solved.export_matrix_data( - file_path, - problem_type="RL", - matrix_type="Maxwell, Spice, Couple", - ) + with pytest.raises(ValueError): + q2d_solved.export_matrix_data( + file_path, + problem_type="RL", + matrix_type="Maxwell, Spice, Couple", + ) assert q2d_solved.export_matrix_data(file_path, problem_type="RL", matrix_type="Maxwell, Couple") assert q2d_solved.export_matrix_data(file_path, problem_type="CG", setup="Setup1", sweep="Sweep1") assert q2d_solved.export_matrix_data( @@ -200,20 +202,26 @@ def test_export_matrix_data(q2d_solved, test_tmp_dir) -> None: ) assert q2d_solved.export_matrix_data(file_path, problem_type="CG", reduce_matrix="Test1") assert q2d_solved.export_matrix_data(file_path, problem_type="CG", reduce_matrix="Test3") - assert not q2d_solved.export_matrix_data(file_path, problem_type="CG", reduce_matrix="Test4") + with pytest.raises(ValueError): + q2d_solved.export_matrix_data(file_path, problem_type="CG", reduce_matrix="Test4") assert q2d_solved.export_matrix_data(file_path, precision=16, field_width=22) - assert not q2d_solved.export_matrix_data(file_path, precision=16.2) + with pytest.raises(ValueError): + q2d_solved.export_matrix_data(file_path, precision=16.2) assert q2d_solved.export_matrix_data(file_path, freq="3", freq_unit="Hz") assert q2d_solved.export_matrix_data(file_path, use_sci_notation=True) assert q2d_solved.export_matrix_data(file_path, use_sci_notation=False) assert q2d_solved.export_matrix_data(file_path, r_unit="mohm") - assert not q2d_solved.export_matrix_data(file_path, r_unit="A") + with pytest.raises(ValueError): + q2d_solved.export_matrix_data(file_path, r_unit="A") assert q2d_solved.export_matrix_data(file_path, l_unit="nH") - assert not q2d_solved.export_matrix_data(file_path, l_unit="A") + with pytest.raises(ValueError): + q2d_solved.export_matrix_data(file_path, l_unit="A") assert q2d_solved.export_matrix_data(file_path, c_unit="farad") - assert not q2d_solved.export_matrix_data(file_path, c_unit="H") + with pytest.raises(ValueError): + q2d_solved.export_matrix_data(file_path, c_unit="H") assert q2d_solved.export_matrix_data(file_path, g_unit="fSie") - assert not q2d_solved.export_matrix_data(file_path, g_unit="A") + with pytest.raises(ValueError): + q2d_solved.export_matrix_data(file_path, g_unit="A") def test_export_equivalent_circuit(q2d_solved, test_tmp_dir) -> None: @@ -310,7 +318,7 @@ def test_export_equivalent_circuit(q2d_solved, test_tmp_dir) -> None: def test_export_results(q2d_solved) -> None: - exported_files = q2d_solved.export_results(analyze=False) + exported_files = q2d_solved.export_results() assert len(exported_files) > 0 @@ -324,7 +332,7 @@ def test_import_dxf(aedt_app) -> None: def test_export_w_elements_from_sweep(q2d_solved_sweep_app, test_tmp_dir) -> None: export_folder = test_tmp_dir / "export_folder" - files = q2d_solved_sweep_app.export_w_elements(False, export_folder) + files = q2d_solved_sweep_app.export_w_elements(export_folder) assert len(files) == 3 for file in files: ext = Path(file).suffix @@ -334,14 +342,14 @@ def test_export_w_elements_from_sweep(q2d_solved_sweep_app, test_tmp_dir) -> Non def test_export_w_elements_from_nominal(q2d_solved_nominal_app, test_tmp_dir) -> None: export_folder = test_tmp_dir / "export_folder" - files = q2d_solved_nominal_app.export_w_elements(False, export_folder) + files = q2d_solved_nominal_app.export_w_elements(export_folder) assert len(files) == 1 for file in files: ext = Path(file).suffix assert ext == ".sp" assert Path(file).is_file() - files = q2d_solved_nominal_app.export_w_elements(False) + files = q2d_solved_nominal_app.export_w_elements() assert len(files) == 1 for file in files: ext = Path(file).suffix diff --git a/tests/system/general/test_sbr.py b/tests/system/general/test_sbr.py index 1cf14acfda25..eb6da4e7cf27 100644 --- a/tests/system/general/test_sbr.py +++ b/tests/system/general/test_sbr.py @@ -305,6 +305,10 @@ def test_read_hdm(aedt_sbr, test_tmp_dir): plotter.plot_rays(str(bounce2_path)) assert bounce2_path.exists() + with pytest.raises(FileNotFoundError): + hdm_invented = test_tmp_dir / "invented.hdm" + aedt_sbr.parse_hdm_file(str(hdm_invented)) + def test_boundary_perfect_e(aedt_sbr) -> None: b = aedt_sbr.modeler.create_box([0, 0, 0], [10, 20, 30]) diff --git a/tests/system/general/test_twinbuilder.py b/tests/system/general/test_twinbuilder.py index 4be917bd762f..82111e5bd8f6 100644 --- a/tests/system/general/test_twinbuilder.py +++ b/tests/system/general/test_twinbuilder.py @@ -111,7 +111,7 @@ def test_set_end_time(aedt_app) -> None: @pytest.mark.skipif(is_linux, reason="Twinbuilder is only available in Windows OS.") def test_catalog(aedt_app) -> None: - comp_catalog = aedt_app.modeler.components.components_catalog + comp_catalog = aedt_app.modeler.schematic.components_catalog assert not comp_catalog["Capacitors"] assert comp_catalog["Aircraft Electrical VHDLAMS\\Basic:lowpass_filter"].props assert comp_catalog["Aircraft Electrical VHDLAMS\\Basic:lowpass_filter"].place("LP1") @@ -241,15 +241,19 @@ def test_add_excitation_model(add_app, test_tmp_dir) -> None: dkp = tb.desktop_class maxwell_app = dkp[[project_name, "1 maxwell busbar"]] - assert not tb.add_excitation_model(project="invalid", design="1 maxwell busbar") - assert not tb.add_excitation_model(project=tb.project_path, design="1 maxwell busbar") - assert not tb.add_excitation_model(project=project_name, design="1 maxwell busbar", excitations={"a": []}) + with pytest.raises(ValueError): + tb.add_excitation_model(project="invalid", design="1 maxwell busbar") + with pytest.raises(ValueError): + tb.add_excitation_model(project=tb.project_path, design="1 maxwell busbar") + with pytest.raises(ValueError): + tb.add_excitation_model(project=project_name, design="1 maxwell busbar", excitations={"a": []}) excitations = {} for e in maxwell_app.excitations_by_type["Winding Group"]: excitations[e.name] = [1, True, e.props["Type"], False] - assert not tb.add_excitation_model(project=project_name, design="1 maxwell busbar", excitations=excitations) + with pytest.raises(ValueError): + tb.add_excitation_model(project=project_name, design="1 maxwell busbar", excitations=excitations) excitations = {} for e in maxwell_app.excitations_by_type["Winding Group"]: diff --git a/tests/system/layout/test_3dlayout_dcir.py b/tests/system/layout/test_3dlayout_dcir.py index a39f55a20fba..7ca3d0e2e737 100644 --- a/tests/system/layout/test_3dlayout_dcir.py +++ b/tests/system/layout/test_3dlayout_dcir.py @@ -43,7 +43,7 @@ def dcir_example_project(add_app_example): @pytest.mark.skipif(is_linux, reason="Not Supported on Linux.") -@pytest.mark.skipif(DESKTOP_VERSION == "2025.2", reason="WAITING BUG FIX") +@pytest.mark.skipif(DESKTOP_VERSION == "2025.2", reason="AEDT bug") def test_dcir(dcir_example_project) -> None: import pandas as pd @@ -52,6 +52,9 @@ def test_dcir(dcir_example_project) -> None: assert dcir_example_project.get_dcir_solution_data("SIwaveDCIR1", "RL", "Path Resistance") assert dcir_example_project.get_dcir_solution_data("SIwaveDCIR1", "Vias", "Current") assert dcir_example_project.get_dcir_solution_data("SIwaveDCIR1", "Sources", "Voltage") + with pytest.raises(ValueError): + dcir_example_project.get_dcir_solution_data("SIwaveDCIR1", "Sources", "invented") + assert dcir_example_project.post.available_report_quantities(is_siwave_dc=True, context="") assert dcir_example_project.post.create_report( dcir_example_project.post.available_report_quantities(is_siwave_dc=True, context="Vias")[0], diff --git a/tests/system/layout/test_3dlayout_edb.py b/tests/system/layout/test_3dlayout_edb.py index ea008a3faff3..8feb105adfac 100644 --- a/tests/system/layout/test_3dlayout_edb.py +++ b/tests/system/layout/test_3dlayout_edb.py @@ -30,6 +30,7 @@ from ansys.aedt.core import Hfss3dLayout from ansys.aedt.core.generic.settings import is_linux +from ansys.aedt.core.internal.errors import AEDTRuntimeError from ansys.aedt.core.modeler.pcb.object_3d_layout import Components3DLayout from tests import TESTS_LAYOUT_PATH from tests.conftest import DESKTOP_VERSION @@ -79,6 +80,10 @@ def test_get_components(aedt_app) -> None: assert comp["L10"].part_type == "Inductor" assert comp["L10"].set_property_value("Angle", "0deg") assert comp["L10"].create_clearance_on_component(1e-6) + # Test that clearance raises on non-component primitives + line = aedt_app.modeler.geometries["line_209"] + with pytest.raises(ValueError): + line.create_clearance_on_component() assert comp["L10"].absolute_angle == 0.0 comp["L10"].enabled = False assert not comp["L10"].enabled @@ -390,6 +395,9 @@ def test_differential_ports(aedt_app) -> None: assert aedt_app.create_differential_port(pins[0], pins[1], "test_differential", deembed=True) assert "test_differential" in aedt_app.port_list + with pytest.raises(ValueError): + aedt_app.create_differential_port(pins[0], pins[1], name=aedt_app.port_list[0]) + def test_ports_on_components_nets(aedt_app) -> None: component = aedt_app.modeler.components["J1"] @@ -420,13 +428,15 @@ def test_set_variable(aedt_app) -> None: def test_change_options(aedt_app) -> None: assert aedt_app.change_options() assert aedt_app.change_options(color_by_net=False) - assert not aedt_app.change_options(color_by_net=None) + with pytest.raises(AEDTRuntimeError): + aedt_app.change_options(color_by_net=None) def test_show_extent(aedt_app) -> None: assert aedt_app.show_extent() assert aedt_app.show_extent(show=False) - assert not aedt_app.show_extent(show=None) + with pytest.raises(AEDTRuntimeError): + aedt_app.show_extent(show=None) def test_change_design_settings(aedt_app) -> None: @@ -487,13 +497,17 @@ def test_import_table(aedt_app) -> None: file_header = TESTS_LAYOUT_PATH / "example_models" / TEST_SUBFOLDER / "table_header.csv" file_invented = "invented.csv" - assert not aedt_app.import_table(file_header, column_separator="dummy") - assert not aedt_app.import_table(file_invented) + with pytest.raises(FileNotFoundError): + aedt_app.import_table(file_invented) + + with pytest.raises(ValueError): + aedt_app.import_table(file_header, column_separator="dummy") table = aedt_app.import_table(file_header) assert table in aedt_app.existing_analysis_sweeps - assert not aedt_app.delete_imported_data("invented") + with pytest.raises(ValueError): + aedt_app.delete_imported_data("invented") assert aedt_app.delete_imported_data(table) assert table not in aedt_app.existing_analysis_sweeps diff --git a/tests/system/layout/test_3dlayout_modeler.py b/tests/system/layout/test_3dlayout_modeler.py index d62943202668..6b63c6a32e3a 100644 --- a/tests/system/layout/test_3dlayout_modeler.py +++ b/tests/system/layout/test_3dlayout_modeler.py @@ -440,6 +440,19 @@ def test_create_edge_port(aedt_app) -> None: data_format="Voltage", ) assert aedt_app.boundaries[0].properties["Magnitude"] != "1V" + + +def test_create_wave_port_from_two_conductors(aedt_app) -> None: + aedt_app.modeler.layers.add_layer( + layer="Signal", layer_type="signal", thickness="0.035mm", elevation="0mm", material="copper" + ) + aedt_app.modeler.create_line("Signal", [[0, 0], [10, 0]], lw=1, name="conductor1", net="NET1") + aedt_app.modeler.create_line("Signal", [[0, 2], [10, 2]], lw=1, name="conductor2", net="NET2") + + port = aedt_app.create_wave_port_from_two_conductors(assignment=["conductor1", "conductor2"], edge_numbers=[0, 0]) + assert port + assert port.name in aedt_app.port_list + assert aedt_app.delete_port(port.name) aedt_app.boundaries[0].properties["Boundary Type"] = "PEC" assert aedt_app.boundaries[0].properties["Boundary Type"] == "PEC" assert list(aedt_app.oboundary.GetAllBoundariesList())[0] == aedt_app.boundaries[0].name @@ -457,6 +470,10 @@ def test_create_coaxial_port(aedt_app) -> None: port = aedt_app.create_coax_port("port_via", 0.5, "Top", "Lower") assert port.name == "Port1" # First port when test runs independently assert port.props["Radial Extent Factor"] == "0.5" + + with pytest.raises(ValueError): + aedt_app.create_coax_port(aedt_app.port_list[0], 0.5, "Top", "Lower") + aedt_app.delete_port(name=port.name, remove_geometry=False) assert len(aedt_app.port_list) == 0 aedt_app.odesign.Undo() @@ -584,6 +601,25 @@ def test_create_linear_count_sweep(aedt_app) -> None: ) assert sweep2.props["Sweeps"]["Data"] == "LINC 1GHz 10GHz 12" + with pytest.raises(AttributeError): + aedt_app.create_linear_count_sweep( + setup=setup_name, + unit="GHz", + start_frequency=1, + stop_frequency=10, + num_of_freq_points=12, + sweep_type="Invented", + ) + + with pytest.raises(ValueError): + aedt_app.create_linear_count_sweep( + setup="invented", + unit="GHz", + start_frequency=1, + stop_frequency=10, + num_of_freq_points=12, + ) + def test_create_linear_step_sweep(aedt_app) -> None: setup_name = "RF_create_linear_step" @@ -629,8 +665,7 @@ def test_create_linear_step_sweep(aedt_app) -> None: assert sweep5.props["Sweeps"]["Data"] == "LIN 1GHz 10GHz 0.12GHz" assert sweep5.props["FreqSweepType"] == "kBroadbandFast" - # Create a linear step sweep with the incorrect sweep type. - with pytest.raises(AttributeError) as execinfo: + with pytest.raises(AttributeError): aedt_app.create_linear_step_sweep( setup=setup_name, unit="GHz", @@ -638,12 +673,17 @@ def test_create_linear_step_sweep(aedt_app) -> None: stop_frequency=10, step_size=0.12, name="RFBoardSweep4", - sweep_type="Incorrect", - save_fields=True, + sweep_type="Invented", ) - assert ( - execinfo.args[0] == "Invalid value for 'sweep_type'. The value must be 'Discrete', " - "'Interpolating', or 'Fast'." + + with pytest.raises(ValueError): + aedt_app.create_linear_step_sweep( + setup="invented", + unit="GHz", + start_frequency=1, + stop_frequency=10, + step_size=0.12, + name="RFBoardSweep4", ) @@ -667,7 +707,7 @@ def test_create_single_point_sweep(aedt_app) -> None: ) assert sweep6.props["Sweeps"]["Data"] == "1GHz 2GHz 3GHz 4GHz" - with pytest.raises(AttributeError) as execinfo: + with pytest.raises(AttributeError): aedt_app.create_single_point_sweep( setup=setup_name, unit="GHz", @@ -675,7 +715,15 @@ def test_create_single_point_sweep(aedt_app) -> None: name="RFBoardSingle", save_fields=False, ) - assert execinfo.args[0] == "Frequency list is empty. Specify at least one frequency point." + + with pytest.raises(ValueError): + aedt_app.create_single_point_sweep( + setup="invented", + unit="GHz", + freq=[1, 2, 3, 4], + name="RFBoardSingle", + save_fields=False, + ) def test_delete_setup(aedt_app) -> None: @@ -945,7 +993,8 @@ def test_heal(aedt_app) -> None: def test_cosim_simulation(aedt_app) -> None: assert aedt_app.edit_cosim_options() - assert not aedt_app.edit_cosim_options(interpolation_algorithm="auto1") + with pytest.raises(ValueError): + aedt_app.edit_cosim_options(interpolation_algorithm="auto1") def test_set_temperature_dependence(aedt_app) -> None: @@ -1011,6 +1060,9 @@ def test_import_gerber(aedt_app, test_tmp_dir) -> None: aedt_app.close_project(save=False) aedt_app.desktop_class.active_project(active_project) + with pytest.raises(ValueError): + aedt_app._import_cad(str(gerber_file), cad_format="invented") + @pytest.mark.skipif(is_linux, reason="Fails in linux") def test_import_gds(aedt_app, test_tmp_dir) -> None: diff --git a/tests/system/solvers/sequential/test_circuit_dynamic_link.py b/tests/system/solvers/sequential/test_circuit_dynamic_link.py index d727ee4cfe85..af80bf32a90b 100644 --- a/tests/system/solvers/sequential/test_circuit_dynamic_link.py +++ b/tests/system/solvers/sequential/test_circuit_dynamic_link.py @@ -99,6 +99,9 @@ def test_pin_names(usb_app, add_app): assert len(pin_names) == 4 assert "usb_P_pcb" in pin_names + with pytest.raises(ValueError): + app.get_source_pin_names(SRC_USB, SRC_PROJECT_NAME, port_selector=4) + @pytest.mark.skipif(SKIP_CIRCUITS, reason="Skipped because Desktop is crashing") def test_add_subcircuits_3dlayout(circuit_app): @@ -139,15 +142,22 @@ def test_assign_excitations(add_app): app.modeler.schematic.create_interface_port("Excitation_2", ["500mil", 0]) filepath = TESTS_SEQUENTIAL_PATH / "example_models" / TEST_SUBFOLDER / "frequency_dependent_source.fds" ports_list = ["Excitation_1", "Excitation_2"] - assert app.assign_voltage_frequency_dependent_excitation_to_ports(ports_list, str(filepath)) + assert app.assign_voltage_frequency_dependent_excitation_to_ports(ports_list, filepath) filepath = TESTS_SEQUENTIAL_PATH / "example_models" / TEST_SUBFOLDER / "frequency_dependent_source1.fds" ports_list = ["Excitation_1", "Excitation_2"] - assert not app.assign_voltage_frequency_dependent_excitation_to_ports(ports_list, str(filepath)) + with pytest.raises(FileNotFoundError): + app.assign_voltage_frequency_dependent_excitation_to_ports(ports_list, filepath) + + filepath = TESTS_SEQUENTIAL_PATH / "example_models" / TEST_SUBFOLDER / "siwave_syz.siw" + ports_list = ["Excitation_1", "Excitation_2"] + with pytest.raises(ValueError): + app.assign_voltage_frequency_dependent_excitation_to_ports(ports_list, filepath) filepath = TESTS_SEQUENTIAL_PATH / "example_models" / TEST_SUBFOLDER / "frequency_dependent_source.fds" ports_list = ["Excitation_1", "Excitation_3"] - assert not app.assign_voltage_frequency_dependent_excitation_to_ports(ports_list, str(filepath)) + with pytest.raises(ValueError): + app.assign_voltage_frequency_dependent_excitation_to_ports(ports_list, filepath) ports_list = ["Excitation_1"] assert app.assign_voltage_sinusoidal_excitation_to_ports(ports_list) diff --git a/tests/system/solvers/sequential/test_mechanical.py b/tests/system/solvers/sequential/test_mechanical.py index 5731bb1d8a81..f48ec36db6f1 100644 --- a/tests/system/solvers/sequential/test_mechanical.py +++ b/tests/system/solvers/sequential/test_mechanical.py @@ -82,10 +82,13 @@ def test_assign_load(aedt_app, add_app) -> None: def test_create_setup(aedt_app) -> None: - assert not aedt_app.assign_2way_coupling() mysetup = aedt_app.create_setup() mysetup.props["Solver"] = "Direct" assert mysetup.update() + + with pytest.raises(AEDTRuntimeError): + aedt_app.assign_2way_coupling() + assert aedt_app.assign_2way_coupling() diff --git a/tests/system/solvers/test_analyze.py b/tests/system/solvers/test_analyze.py index 61f2b9fe106e..4c046bf93cd0 100644 --- a/tests/system/solvers/test_analyze.py +++ b/tests/system/solvers/test_analyze.py @@ -851,13 +851,14 @@ def test_change_property(m3d_app) -> None: property_value=True, ) - assert not m3d_app.change_property( - aedt_object=m3d_app.odesign, - tab_name="LocalVariableTab", - property_object="LocalVariables", - property_name="a", - property_value={"test": 1}, - ) + with pytest.raises(ValueError): + m3d_app.change_property( + aedt_object=m3d_app.odesign, + tab_name="LocalVariableTab", + property_object="LocalVariables", + property_name="a", + property_value={"test": 1}, + ) with pytest.raises(ValueError): m3d_app.change_properties( diff --git a/tests/system/solvers/test_q3d.py b/tests/system/solvers/test_q3d.py index 287f3a602fa5..fe1895e15489 100644 --- a/tests/system/solvers/test_q3d.py +++ b/tests/system/solvers/test_q3d.py @@ -339,11 +339,14 @@ def test_edit_sources(q3d_solved) -> None: assert q3d_solved.edit_sources(sources_cg, sources_ac) assert q3d_solved.edit_sources() sources_cg = {"Box2": "2V"} - assert not q3d_solved.edit_sources(sources_cg) + with pytest.raises(ValueError): + q3d_solved.edit_sources(sources_cg) sources_ac = {"Box1:Source2": "2V"} - assert not q3d_solved.edit_sources(sources_ac) + with pytest.raises(ValueError): + q3d_solved.edit_sources(sources_ac) sources_dc = {"Box1:Source2": "2V"} - assert not q3d_solved.edit_sources(sources_dc) + with pytest.raises(ValueError): + q3d_solved.edit_sources(sources_dc) sources = q3d_solved.get_all_sources() assert sources[0] == "Box1:Source1" sources_dc = {"Box1:Source1": "20v"} @@ -353,9 +356,11 @@ def test_edit_sources(q3d_solved) -> None: harmonic_loss = {"Box1:Source1": (real_dataset, imag_dataset)} assert q3d_solved.edit_sources(harmonic_loss=harmonic_loss) harmonic_loss = {"invalid": (real_dataset, imag_dataset)} - assert not q3d_solved.edit_sources(harmonic_loss=harmonic_loss) + with pytest.raises(ValueError): + q3d_solved.edit_sources(harmonic_loss=harmonic_loss) harmonic_loss = {"Box1:Source1": real_dataset} - assert not q3d_solved.edit_sources(harmonic_loss=harmonic_loss) + with pytest.raises(ValueError): + q3d_solved.edit_sources(harmonic_loss=harmonic_loss) def test_export_matrix_data(q3d_solved, test_tmp_dir) -> None: @@ -364,8 +369,10 @@ def test_export_matrix_data(q3d_solved, test_tmp_dir) -> None: assert len(sweep.frequencies) > 0 assert sweep.basis_frequencies == [] assert q3d_solved.export_matrix_data(file_path) - assert not q3d_solved.export_matrix_data(test_tmp_dir / "test.pdf") - assert not q3d_solved.export_matrix_data(file_name=file_path, matrix_type="Test") + with pytest.raises(ValueError): + q3d_solved.export_matrix_data(test_tmp_dir / "test.pdf") + with pytest.raises(ValueError): + q3d_solved.export_matrix_data(file_name=file_path, matrix_type="Test") assert q3d_solved.export_matrix_data( file_name=file_path, problem_type="C", @@ -377,25 +384,30 @@ def test_export_matrix_data(q3d_solved, test_tmp_dir) -> None: matrix_type="Maxwell, Spice, Couple", ) assert q3d_solved.export_matrix_data(file_name=file_path, problem_type="C") - assert not q3d_solved.export_matrix_data( - file_name=file_path, - problem_type="AC RL, DC RL", - matrix_type="Maxwell, Spice, Couple", - ) + with pytest.raises(ValueError): + q3d_solved.export_matrix_data( + file_name=file_path, + problem_type="AC RL, DC RL", + matrix_type="Maxwell, Spice, Couple", + ) assert q3d_solved.export_matrix_data(file_name=file_path, problem_type="AC RL, DC RL") assert q3d_solved.export_matrix_data( file_name=file_path, problem_type="AC RL, DC RL", matrix_type="Maxwell, Couple", ) - assert not q3d_solved.export_matrix_data(file_name=file_path, problem_type="AC") + with pytest.raises(ValueError): + q3d_solved.export_matrix_data(file_name=file_path, problem_type="AC") assert q3d_solved.export_matrix_data(file_name=file_path, setup="Setup1", sweep="LastAdaptive") assert q3d_solved.export_matrix_data(file_name=file_path, setup="Setup1", sweep="Last Adaptive") - assert not q3d_solved.export_matrix_data(file_name=file_path, setup="Setup", sweep="LastAdaptive") - assert not q3d_solved.export_matrix_data(file_name=file_path, setup="Setup1", sweep="Last Adaptive Invented") + with pytest.raises(ValueError): + q3d_solved.export_matrix_data(file_name=file_path, setup="Setup", sweep="LastAdaptive") + with pytest.raises(ValueError): + q3d_solved.export_matrix_data(file_name=file_path, setup="Setup1", sweep="Last Adaptive Invented") assert q3d_solved.export_matrix_data(file_name=file_path, reduce_matrix="Original") assert q3d_solved.export_matrix_data(file_name=file_path, reduce_matrix="JointTest") - assert not q3d_solved.export_matrix_data(file_name=file_path, reduce_matrix="JointTest4") + with pytest.raises(ValueError): + q3d_solved.export_matrix_data(file_name=file_path, reduce_matrix="JointTest4") assert q3d_solved.export_matrix_data(file_name=file_path, setup="Setup1", sweep="LastAdaptive", freq=1) assert q3d_solved.export_matrix_data( file_name=file_path, @@ -405,17 +417,22 @@ def test_export_matrix_data(q3d_solved, test_tmp_dir) -> None: freq_unit="kHz", ) assert q3d_solved.export_matrix_data(file_name=file_path, precision=16, field_width=22) - assert not q3d_solved.export_matrix_data(file_name=file_path, precision=16.2) + with pytest.raises(ValueError): + q3d_solved.export_matrix_data(file_name=file_path, precision=16.2) assert q3d_solved.export_matrix_data(file_name=file_path, use_sci_notation=True) assert q3d_solved.export_matrix_data(file_name=file_path, use_sci_notation=False) assert q3d_solved.export_matrix_data(file_name=file_path, r_unit="mohm") - assert not q3d_solved.export_matrix_data(file_name=file_path, r_unit="A") + with pytest.raises(ValueError): + q3d_solved.export_matrix_data(file_name=file_path, r_unit="A") assert q3d_solved.export_matrix_data(file_name=file_path, l_unit="nH") - assert not q3d_solved.export_matrix_data(file_name=file_path, l_unit="A") + with pytest.raises(ValueError): + q3d_solved.export_matrix_data(file_name=file_path, l_unit="A") assert q3d_solved.export_matrix_data(file_name=file_path, c_unit="farad") - assert not q3d_solved.export_matrix_data(file_name=file_path, c_unit="H") + with pytest.raises(ValueError): + q3d_solved.export_matrix_data(file_name=file_path, c_unit="H") assert q3d_solved.export_matrix_data(file_name=file_path, g_unit="fSie") - assert not q3d_solved.export_matrix_data(file_name=file_path, g_unit="A") + with pytest.raises(ValueError): + q3d_solved.export_matrix_data(file_name=file_path, g_unit="A") def test_equivalent_circuit(q3d_solved2, test_tmp_dir) -> None: diff --git a/tests/system/visualization/test_postprocessing_1.py b/tests/system/visualization/test_postprocessing_1.py index af409a0787ce..fac4321ffc1a 100644 --- a/tests/system/visualization/test_postprocessing_1.py +++ b/tests/system/visualization/test_postprocessing_1.py @@ -604,7 +604,8 @@ def test_import_traces(aedt_app, test_tmp_dir) -> None: my_data = aedt_app.post.get_solution_data(expressions=trace_names, variations=families) output_csv = test_tmp_dir / "output.csv" my_data.export_data_to_csv(str(output_csv)) - assert not new_report.import_traces(str(output_csv), plot_name) + with pytest.raises(AEDTRuntimeError): + new_report.import_traces(str(output_csv), plot_name) # test import with correct inputs from csv assert new_report.import_traces(csv_file_path, plot_name) diff --git a/tests/unit/test_geometry_modeler.py b/tests/unit/test_geometry_modeler.py index 58180ff84a2b..e25d4b6e78f6 100644 --- a/tests/unit/test_geometry_modeler.py +++ b/tests/unit/test_geometry_modeler.py @@ -30,6 +30,7 @@ import pytest from ansys.aedt.core import Hfss +from ansys.aedt.core.internal.errors import AEDTRuntimeError from ansys.aedt.core.modeler.cad.primitives import GeometryModeler @@ -49,11 +50,8 @@ def mock_hfss_app(): def test_project_object_failure(mock_unclassified_objects, mock_hfss_app, caplog: pytest.LogCaptureFixture) -> None: mock_unclassified_objects.side_effect = [[], [MagicMock()]] gm = GeometryModeler(mock_hfss_app) - - assert not gm.project_sheet("rect", "box", 1) - assert any( - "Failed to Project Sheet. Reverting to original objects." in record.getMessage() for record in caplog.records - ) + with pytest.raises(AEDTRuntimeError): + gm.project_sheet("rect", "box", 1) def test_delete_all_points_failure(mock_hfss_app, caplog: pytest.LogCaptureFixture) -> None: diff --git a/tests/unit/test_geometry_operators.py b/tests/unit/test_geometry_operators.py index cb4ada6aad7b..55150e6d3e47 100644 --- a/tests/unit/test_geometry_operators.py +++ b/tests/unit/test_geometry_operators.py @@ -527,6 +527,8 @@ def test_wg() -> None: assert len(wg_calc.get_waveguide_dimensions("WR-75", "in")) == 3 for f in range(1, 200): assert isinstance(wg_calc.find_waveguide(f), str) + with pytest.raises(ValueError): + wg_calc.get_waveguide_dimensions("invented", "in") def test_is_vector_equal() -> None: