Skip to content

Commit

Permalink
Merge branch 'main' into release/0.13
Browse files Browse the repository at this point in the history
  • Loading branch information
Samuelopez-ansys committed Jan 31, 2025
2 parents 2f407dd + 10b9f89 commit 576e82a
Show file tree
Hide file tree
Showing 124 changed files with 46,889 additions and 170,860 deletions.
3 changes: 1 addition & 2 deletions .github/workflows/ci_cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -400,8 +400,7 @@ jobs:
uses: ansys/actions/release-pypi-public@v8
with:
library-name: ${{ env.PACKAGE_NAME }}
twine-username: "__token__"
twine-token: ${{ secrets.PYPI_TOKEN }}
use-trusted-publisher: true

- name: Release to GitHub
uses: ansys/actions/release-github@v8
Expand Down
17 changes: 17 additions & 0 deletions doc/source/Getting_started/Troubleshooting.rst
Original file line number Diff line number Diff line change
Expand Up @@ -199,3 +199,20 @@ gRPC calls on the client where the Python script is to be run.
Now run the PyAEDT script, (making sure it connects to the same port as the gRPC server - 50051).
Capture the output in a file. For example *client.txt*. Then send all the logs
to `Ansys Support <https://www.ansys.com/it-solutions/contacting-technical-support>`_.


Numpy compatibility
-------------------
If you use Numpy 2.Y.Z, you may encounter compatibility issues with PyAEDT or PyEDB.

This kind of problem can occur when a user is in a Linux environment and wants to use .NET.
If you encounter such issue, you can try patching it by importing PyAEDT or PyEDB before any import of Numpy as below

.. code-block:: python
import ansys.aedt.core
import numpy
.. note::

If you use gRPC or previous Numpy releases, you shouldn't be impacted with this issue.
51 changes: 51 additions & 0 deletions doc/source/User_guide/pyaedt_extensions_doc/hfss/shielding.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
Shielding Effectiveness
=======================

The **Shielding Effectiveness** extension computes the shielding effectiveness of an enclosure.
It calculates the attenuation of an electromagnetic field inside the enclosure due to the presence of a shield.

The extension provides a graphical user interface (GUI) for configuration,
or it can be used in batch mode via command line arguments.

The following image shows the extension GUI:

.. image:: ../../../_static/extensions/shielding_ui.png
:width: 800
:alt: Shielding Effectiveness GUI


Features
--------

- Configure input parameters including source sphere radius, polarization, start and stop frequency and dipole type.
- Automatic HFSS setup.
- Switch between light and dark themes in the GUI.


Using the extension
-------------------

1. Open the **Automation** tab in the HFSS interface.
2. Locate and click the **Shielding Effectiveness** icon under the Extension Manager.
3. In the GUI, users can interact with the following elements:
- **Source sphere radius**: Source sphere radius in meters. It must fit inside the shielding.
- **Polarization**: X, Y, Z polarization component.
- **Frequency**: Start and stop frequency and the number of steps to analyze.
- **Electric dipole**: Activate electric dipole. Electric or magnetic dipole are available.
- **Cores**: Number of cores for the simulation.
- Toggle between light and dark themes.
4. Click on **Launch** to start the automated workflow.


Command line
------------

The extension can also be used directly via the command line for batch processing.


Use the following syntax to run the extension:

.. toctree::
:maxdepth: 2

../commandline
Binary file added doc/source/_static/extensions/shielding_ui.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion doc/styles/config/vocabularies/ANSYS/accept.txt
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ namespaces
Nastran
netlist
Nexxim
numpy
[Nn]umpy
numpydoc
openssl
[Oo]ptimetrics
Expand Down
8 changes: 1 addition & 7 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ dependencies = [
"rpyc>=6.0.0,<6.1",
"pyyaml",
"defusedxml>=0.7,<8.0",
"attrs!=24.3.0",
"attrs<24.3.0",
"referencing<0.36.0",
]

Expand Down Expand Up @@ -80,8 +80,6 @@ tests = [
# Never directly imported but required when loading ML related file see #4713
"scikit-learn>=1.0.0,<1.7",
"scikit-rf>=0.30.0,<1.6",
"SRTM.py",
"utm",
]
dotnet = [
"ansys-pythonnet>=3.1.0rc3",
Expand Down Expand Up @@ -117,8 +115,6 @@ all = [
# Never directly imported but required when loading ML related file see #4713
"scikit-learn>=1.0.0,<1.7",
"scikit-rf>=0.30.0,<1.6",
"SRTM.py",
"utm",
]
installer = [
"matplotlib>=3.5.0,<3.11",
Expand All @@ -132,8 +128,6 @@ installer = [
# Never directly imported but required when loading ML related file see #4713
"scikit-learn>=1.0.0,<1.7",
"scikit-rf>=0.30.0,<1.6",
"SRTM.py",
"utm",
"jupyterlab>=3.6.0,<4.4",
"ipython>=7.30.0,<8.32",
"ipyvtklink>=0.2.0,<0.2.4",
Expand Down
2 changes: 1 addition & 1 deletion src/ansys/aedt/core/generic/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -867,7 +867,7 @@ class Circuit(object):
class Mechanical(object):
"""Provides Mechanical solution types."""

(Thermal, Structural, Modal) = ("Thermal", "Structural", "Modal")
(Thermal, Structural, Modal, SteadyStateThermal) = ("Thermal", "Structural", "Modal", "Steady-State Thermal")


class SETUPS(object):
Expand Down
4 changes: 2 additions & 2 deletions src/ansys/aedt/core/generic/data_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@

from decimal import Decimal
import math
import random
import re
import secrets
import string
import unicodedata

Expand Down Expand Up @@ -272,7 +272,7 @@ def random_string(length=6, only_digits=False, char_set=None):
char_set = string.digits
else:
char_set = string.ascii_uppercase + string.digits
random_str = "".join(random.choice(char_set) for _ in range(int(length)))
random_str = "".join(secrets.choice(char_set) for _ in range(int(length)))
return random_str


Expand Down
104 changes: 104 additions & 0 deletions src/ansys/aedt/core/hfss.py
Original file line number Diff line number Diff line change
Expand Up @@ -6766,6 +6766,110 @@ def plane_wave(

return self._create_boundary(name, inc_wave_args, "Plane Incident Wave")

@pyaedt_function_handler()
def hertzian_dipole_wave(
self,
assignment=None,
origin=None,
polarization=None,
is_electric=True,
radius="10mm",
name=None,
) -> BoundaryObject:
"""Create a hertzian dipole wave excitation.
The excitation is assigned in the assigned sphere. Inside this sphere, the field magnitude
is equal to the field magnitude calculated on the surface of the sphere.
Parameters
----------
assignment : str or list, optional
One or more objects or faces to assign finite conductivity to. The default is ``None``, in which
case the excitation is assigned to anything.
origin : list, optional
Excitation location. The default is ``["0mm", "0mm", "0mm"]``.
polarization : list, optional
Electric field polarization vector.
The default is ``[0, 0, 1]``.
is_electric : bool, optional
Type of dipole. Electric dipole if ``True``, magnetic dipole if ``False``. The default is ``True``.
radius : str or float, optional
Radius of surrounding sphere. The default is "10mm".
name : str, optional
Name of the boundary.
Returns
-------
:class:`pyaedt.modules.Boundary.BoundaryObject`
Port object.
References
----------
>>> oModule.AssignHertzianDipoleWave
Examples
--------
Create a hertzian dipole wave excitation.
>>> from ansys.aedt.core import Hfss
>>> hfss = Hfss()
>>> sphere = hfss.modeler.primitives.create_sphere([0, 0, 0], 10)
>>> port1 = hfss.hertzian_dipole_wave(assignment=sphere, radius=10)
"""
userlst = self.modeler.convert_to_selections(assignment, True)
lstobj = []
lstface = []
for selection in userlst:
if selection in self.modeler.model_objects:
lstobj.append(selection)
elif isinstance(selection, int) and self.modeler._find_object_from_face_id(selection):
lstface.append(selection)

props = {"Objects": [], "Faces": []}

if lstobj:
props["Objects"] = lstobj
if lstface:
props["Faces"] = lstface

if not origin:
origin = ["0mm", "0mm", "0mm"]
elif not isinstance(origin, list) or len(origin) != 3:
self.logger.error("Invalid value for `origin`.")
return False

x_origin, y_origin, z_origin = self.modeler._pos_with_arg(origin)

name = self._get_unique_source_name(name, "IncPWave")

hetzian_wave_args = {"OriginX": x_origin, "OriginY": y_origin, "OriginZ": z_origin}

if not polarization:
polarization = [0, 0, 1]
elif not isinstance(polarization, list) or len(polarization) != 3:
self.logger.error("Invalid value for `polarization`.")
return False

new_hertzian_args = {
"IsCartesian": True,
"EoX": polarization[0],
"EoY": polarization[1],
"EoZ": polarization[2],
"kX": polarization[0],
"kY": polarization[1],
"kZ": polarization[2],
}

hetzian_wave_args["IsElectricDipole"] = False
if is_electric:
hetzian_wave_args["IsElectricDipole"] = True

hetzian_wave_args["SphereRadius"] = radius
hetzian_wave_args.update(new_hertzian_args)
hetzian_wave_args.update(props)

return self._create_boundary(name, hetzian_wave_args, "Hertzian Dipole Wave")

@pyaedt_function_handler()
def set_radiated_power_calc_method(self, method="Auto"):
"""Set the radiated power calculation method in Hfss.
Expand Down
19 changes: 11 additions & 8 deletions src/ansys/aedt/core/icepak.py
Original file line number Diff line number Diff line change
Expand Up @@ -1129,13 +1129,13 @@ def assign_priority_on_intersections(self, component_prefix="COMP_"):
i += 1
return True

@pyaedt_function_handler()
def find_top(self, gravityDir):
@pyaedt_function_handler(gravityDir="gravity_dir")
def find_top(self, gravity_dir):
"""Find the top location of the layout given a gravity.
Parameters
----------
gravityDir :
gravity_dir :
Gravity direction from -X to +Z. Options are ``0`` to ``5``.
Returns
Expand All @@ -1160,10 +1160,10 @@ def find_top(self, gravityDir):
]
self.modeler.oeditor.ChangeProperty(args)
oBoundingBox = self.modeler.get_model_bounding_box()
if gravityDir < 3:
return oBoundingBox[gravityDir + 3]
if gravity_dir < 3:
return oBoundingBox[gravity_dir + 3]
else:
return oBoundingBox[gravityDir - 3]
return oBoundingBox[gravity_dir - 3]

@pyaedt_function_handler(matname="material")
def create_parametric_fin_heat_sink(
Expand Down Expand Up @@ -2596,6 +2596,7 @@ def copyGroupFrom(self, group_name, source_design, source_project_name=None, sou
>>> oEditor.Copy
>>> oeditor.Paste
"""
pj_names = self.project_list
if "groupName" in kwargs:
warnings.warn(
"The ``groupName`` parameter was deprecated in 0.6.43. Use the ``group_name`` parameter instead.",
Expand Down Expand Up @@ -2639,6 +2640,8 @@ def copyGroupFrom(self, group_name, source_design, source_project_name=None, sou
self.modeler.oeditor.Paste()
self.modeler.refresh_all_ids()
self.materials._load_from_project()
if not (source_project_name in pj_names or source_project_name is None):
active_project.close()
return True

@pyaedt_function_handler()
Expand Down Expand Up @@ -2902,9 +2905,9 @@ def generate_fluent_mesh(
meshtype : str, optional
Mesh type. Options are ``"tethraedral"`` or ``"hexcore"``.
min_size : float, optional
Minimum mesh size. Default is smallest edge of objects/20.
Minimum mesh size. Default is the smallest edge of objects/20.
max_size : float, optional
Maximum mesh size. Default is smallest edge of objects/5.
Maximum mesh size. Default is the smallest edge of objects/5.
inflation_layer_number : int, optional
Inflation layer number. Default is ``3``.
inflation_growth_rate : float, optional
Expand Down
Loading

0 comments on commit 576e82a

Please sign in to comment.