Skip to content

Commit

Permalink
Merge branch 'main' into release/0.9
Browse files Browse the repository at this point in the history
  • Loading branch information
Samuelopez-ansys committed Jun 28, 2024
2 parents 815d83d + 11f03cc commit 8e73ceb
Show file tree
Hide file tree
Showing 19 changed files with 355 additions and 30 deletions.
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ repos:

# validate GitHub workflow files
- repo: https://github.com/python-jsonschema/check-jsonschema
rev: 0.28.5
rev: 0.28.6
hooks:
- id: check-github-workflows

Expand Down
Binary file added _unittest/example_models/T98/cylinder_mesh.msh
Binary file not shown.
Binary file not shown.
18 changes: 17 additions & 1 deletion _unittest/test_27_Maxwell2D.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@
ctrl_prg = "TimeStepCtrl"
ctrl_prg_file = "timestep_only.py"

m2d_fields = "maxwell_e_line_export_field"


@pytest.fixture(scope="class")
def aedtapp(add_app):
Expand All @@ -63,11 +65,18 @@ def m2d_ctrl_prg(add_app):
return app


@pytest.fixture(scope="class")
def m2d_field_export(add_app):
app = add_app(application=Maxwell2d, project_name=m2d_fields, subfolder=test_subfolder)
return app


class TestClass:
@pytest.fixture(autouse=True)
def init(self, aedtapp, m2d_ctrl_prg, local_scratch):
def init(self, aedtapp, m2d_ctrl_prg, m2d_field_export, local_scratch):
self.aedtapp = aedtapp
self.m2d_ctrl_prg = m2d_ctrl_prg
self.m2d_field_export = m2d_field_export
self.local_scratch = local_scratch

def test_03_assign_initial_mesh_from_slider(self):
Expand Down Expand Up @@ -583,3 +592,10 @@ def test_37_boundaries_by_type(self):
wdg_group = self.aedtapp.boundaries_by_type["Winding Group"]
assert wdg_group
assert len(wdg_group) == len([bound for bound in self.aedtapp.boundaries if bound.type == "Winding Group"])

def test_38_export_fields_calc(self):
output_file = os.path.join(self.local_scratch.path, "e_tang_field.fld")
assert self.m2d_field_export.post.export_field_file(
quantity="E_Line", output_dir=output_file, assignment="Poly1", objects_type="Line"
)
assert os.path.exists(output_file)
57 changes: 56 additions & 1 deletion _unittest/test_98_Icepak.py
Original file line number Diff line number Diff line change
Expand Up @@ -347,8 +347,11 @@ def test_12a_AssignMeshOperation(self):
mesh_level_Filter = "2"
component_name = ["RadioBoard1_1"]
mesh_level_RadioPCB = "1"
test = self.aedtapp.mesh.assign_mesh_level_to_group(mesh_level_Filter, group_name)
assert self.aedtapp.mesh.assign_mesh_level_to_group(mesh_level_Filter, group_name)
test = self.aedtapp.mesh.assign_mesh_level_to_group(mesh_level_Filter, group_name, name="Test")
assert test
test2 = self.aedtapp.mesh.assign_mesh_level_to_group(mesh_level_Filter, group_name, name="Test")
assert test.name != test2.name
# assert self.aedtapp.mesh.assignMeshLevel2Component(mesh_level_RadioPCB, component_name)
test = self.aedtapp.mesh.assign_mesh_region(component_name, mesh_level_RadioPCB, is_submodel=True)
assert test
Expand Down Expand Up @@ -1741,3 +1744,55 @@ def test_78_restart_solution(self):
"test_78-1", "{} : SteadyState".format(s1.name), project="FakeFolder123"
)
assert not s2.start_continue_from_previous_setup("test_78-12", "{} : SteadyState".format(s1.name))

def test_79_mesh_reuse(self):
self.aedtapp.insert_design("test_79")
self.aedtapp.set_active_design("test_79")
cylinder = self.aedtapp.modeler.create_cylinder(1, [0, 0, 0], 5, 30)
assert not self.aedtapp.mesh.assign_mesh_reuse(
cylinder.name,
os.path.join(local_path, "../_unittest/example_models", test_subfolder, "nonexistent_cylinder_mesh.msh"),
)
assert self.aedtapp.mesh.assign_mesh_reuse(
cylinder.name, os.path.join(local_path, "../_unittest/example_models", test_subfolder, "cylinder_mesh.msh")
)
assert self.aedtapp.mesh.assign_mesh_reuse(
cylinder.name,
os.path.join(local_path, "../_unittest/example_models", test_subfolder, "cylinder_mesh.msh"),
"name_reuse",
)
assert self.aedtapp.mesh.assign_mesh_reuse(
cylinder.name,
os.path.join(local_path, "../_unittest/example_models", test_subfolder, "cylinder_mesh.msh"),
"name_reuse",
)

def test_80_global_mesh_region(self):
self.aedtapp.insert_design("test_80")
self.aedtapp.set_active_design("test_80")
g_m_r = self.aedtapp.mesh.global_mesh_region
assert g_m_r
assert g_m_r.global_region.object.name == "Region"
assert g_m_r.global_region.padding_values == ["50", "50", "50", "50", "50", "50"]
assert g_m_r.global_region.padding_types == [
"Percentage Offset",
"Percentage Offset",
"Percentage Offset",
"Percentage Offset",
"Percentage Offset",
"Percentage Offset",
]
g_m_r.global_region.positive_z_padding_type = "Absolute Offset"
g_m_r.global_region.positive_z_padding = "5 mm"
assert g_m_r.global_region.padding_types[-2] == "Absolute Offset"
assert g_m_r.global_region.padding_values[-2] == "5mm"
g_m_r.settings["MeshRegionResolution"] = 3
g_m_r.update()
assert g_m_r.settings["MeshRegionResolution"] == 3
g_m_r.manual_settings = True
with pytest.raises(KeyError):
g_m_r.settings["MeshRegionResolution"]
g_m_r.settings["MaxElementSizeX"] = "500um"
g_m_r.update()
g_m_r.global_region.object.material_name = "Carbon Monoxide"
assert g_m_r.global_region.object.material_name == "Carbon Monoxide"
19 changes: 18 additions & 1 deletion doc/source/API/Mesh.rst
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,23 @@ They are accessible through the mesh property:
close_on_exit=True, student_version=False)
# This call returns the Mesh class
my_mesh = app.mesh
# This call executes a Mesh method and creates an object to control the mesh operation
# This call executes a ``Mesh`` method and creates an object to control the mesh operation
mesh_operation_object = my_mesh.assign_surface_mesh("MyBox", 2)
...
Icepak mesh
~~~~~~~~~~~~~~~

These objects are relevant objects while using the ``MeshIcepak`` class:

.. currentmodule:: pyaedt.modules.MeshIcepak

.. autosummary::
:toctree: _autosummary
:nosignatures:


Region
SubRegion
MeshRegion
GlobalMeshRegion
3 changes: 3 additions & 0 deletions doc/source/Getting_started/Installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ The user can select the AEDT application to install the specific workflow.
:width: 400
:alt: PyAEDT toolkit manager 2

For additional information about AEDT extensions,
see `Extensions <https://aedt.docs.pyansys.com/version/stable/User_guide/extensions.html>`_.


Install on CPython from PyPI
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified doc/source/Resources/toolkits_ribbon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
36 changes: 36 additions & 0 deletions doc/source/User_guide/extensions.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
Extensions
==========

Extensions provide a simplified interface to perform automated workflows in AEDT.
In AEDT, you can use the Extension Manager to add or remove extensions.
For more information, see `Extension Manager <https://aedt.docs.pyansys.com/version/stable/Getting_started/Installation.html#extension-manager>`_.

Extensions are generally tool-specific and are therefore only accessible given the appropriate context. The following sections provide further clarification.

You can launch extensions in standalone mode from the console or a Python script.

Project extensions
==================

Project extension apply to all extensions that are applicable for all AEDT applications.

.. grid:: 2

.. grid-item-card:: Import Nastran
:link: pyaedt_extensions_doc/project
:link-type: doc

Import a Nastran or STL file in any 3D modeler application.

.. toctree::
:hidden:
:maxdepth: 2

pyaedt_extensions_doc/project

HFSS extensions
===============


HFSS 3D Layout extensions
=========================
8 changes: 8 additions & 0 deletions doc/source/User_guide/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ For end-to-end examples, see `Examples <https://aedt.docs.pyansys.com/version/st

How to launch AEDT and create a project.

.. grid-item-card:: Extensions
:link: extensions
:link-type: doc
:margin: 2 2 0 0

How to use PyAEDT extensions.

.. grid-item-card:: Modeler
:link: modeler
:link-type: doc
Expand Down Expand Up @@ -72,6 +79,7 @@ For end-to-end examples, see `Examples <https://aedt.docs.pyansys.com/version/st
:maxdepth: 2

intro
extensions
modeler
mesh
setup
Expand Down
108 changes: 92 additions & 16 deletions doc/source/User_guide/mesh.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,32 +20,108 @@ All mesh operations are conveniently listed within the mesh object:
:width: 800
:alt: Mesh object List

Mesh in Icepak
--------------

Icepak has a different approach to the mesh operations.
Those are managed through mesh regions and can be edited directly from the pyaedt object.
Icepak employs a unique approach to mesh operations, managed through mesh regions, which can be edited directly from the PyAEDT object.

**Global mesh region**

This code accesses the global mesh region object:

.. code:: python
glob_msh = ipk.mesh.global_mesh_region
This object allows for the editing of global mesh settings through its ``settings`` property, which behaves like a dictionary.

.. code:: python
glob_msh.settings["MeshRegionResolution"] = 3
The keys available depend on whether manual or automatic settings are used. You can use the ``manual_settings`` Boolean property of the global mesh region object to change the setting.

To modify the global region dimensions, access the '`global_region'` property and modify its attributes:

.. code:: python
glob_msh.global_region.positive_z_padding_type = "Absolute Offset"
glob_msh.global_region.positive_z_padding = "5 mm"
To modify the properties of the ``Region`` object (for example the gas inside the region), access the ``object`` property of the ``global_region`` object:

.. code:: python
icepak_b = Icepak()
glob_reg = glob_msh.global_region
glob_reg.object.material_name = "Carbon Monoxide"
This is a pointer to the same object accessible from ``ipk.modeler["Region"]``.

The following image summarizes these three objects:

.. image:: ../Resources/icepak_global_mesh_region_objects.png
:width: 80%
:alt: Global mesh objects and sub-objects

This code provides a complete example using the global mesh region:

.. code:: python
ipk = Icepak()
glob_msh = ipk.mesh.global_mesh_region
glob_msh.manual_settings = True
glob_msh.settings["MaxElementSizeX"] = "2mm"
glob_msh.settings["MaxElementSizeY"] = "3mm"
glob_msh.settings["MaxElementSizeZ"] = "4mm"
glob_msh.settings["MaxSizeRatio"] = 2
glob_msh.settings["UserSpecifiedSettings"] = True
glob_msh.settings["UniformMeshParametersType"] = "XYZ Max Sizes"
glob_msh.settings["MaxLevels"] = 2
glob_msh.settings["BufferLayers"] = 1
glob_msh.update()
**Local mesh regions**

To create a mesh region, use the ``assign_mesh_region()`` method:

.. code:: python
mesh_region = ipk.mesh.assign_mesh_region(name=object_name)
You can modify the settings of the returned object using the same approach as with the global mesh region object.

This code accesses the subregion that defines the local mesh region and modifies its dimensions:

.. code:: python
subregion = mesh_region.assignment
subregion.positive_z_padding_type = "Absolute Offset"
subregion.positive_z_padding = "5 mm"
This code accesses the parts included in the subregion:

.. code:: python
subregion.parts
AEDT 2024 R1 introduced a significant revamp of the mesh region paradigm, resulting in limited support for older versions. To use the same methods in older versions, you must define the region box first and pass it as the first argument of the ``assign_mesh_region()`` method.

**Mesh operations**

- To assign a mesh level to some objects, use the ``assign_mesh_level()`` method:

# Global mesh region
.. code:: python
icepak_b.mesh.global_mesh_region.MaxElementSizeX = "2mm"
icepak_b.mesh.global_mesh_region.MaxElementSizeY = "3mm"
icepak_b.mesh.global_mesh_region.MaxElementSizeZ = "4mm"
icepak_b.mesh.global_mesh_region.MaxSizeRatio = 2
icepak_b.mesh.global_mesh_region.UserSpecifiedSettings = True
icepak_b.mesh.global_mesh_region.UniformMeshParametersType = "XYZ Max Sizes"
icepak_b.mesh.global_mesh_region.MaxLevels = 2
icepak_b.mesh.global_mesh_region.BufferLayers = 1
icepak_b.mesh.global_mesh_region.update()
ipk.mesh.assign_mesh_level(mesh_order={"Box1": 2, "Cylinder1": 4})
box1 = icepak_b.modeler.create_box([0,0,0], [10,20,20])
- To assign a mesh file for reuse to some objects, use the ``assign_mesh_reuse()`` method:

# Local mesh region
.. code:: python
new_mesh_region = icepak_b.mesh.assign_mesh_region([box1.name])
ipk.mesh.assign_mesh_reuse(assignment=["Box1", "Cylinder1"], level=mesh_path)
Mesh in HFSS 3D Layout
----------------------

In HFSS 3D Layout, you add mesh operations to nets and layers like this:

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
51 changes: 51 additions & 0 deletions doc/source/User_guide/pyaedt_extensions_doc/project.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
Import Nastran
==============

You can import a Nastran or STL file in any 3D modeler. You can also preview the imported file and decimate it prior to import.

You can access the extension from the icon created on the **Automation** tab using the Extension Manager.

The following image shows the extension user interface:

.. image:: import_nastran_ui.png
:width: 800
:alt: Import Nastran UI

You can also launch the extension user interface from the terminal:

.. code::
SET PYAEDT_SCRIPT_PORT=50051
SET PYAEDT_SCRIPT_VERSION=2024.1
python.exe path/to/pyaedt/workflows/project/import_nastran.py
The available arguments are: ``file_path``, ``planar``, ``lightweight``, and ``decimate``.
You can obtain these arguments from the help with this command:

.. code::
python.exe path/to/pyaedt/workflows/project/import_nastran.py --help
This code shows how to pass the input file as an argument, which doesn't launch the user interface:

.. code::
export PYAEDT_SCRIPT_PORT=50051
export PYAEDT_SCRIPT_VERSION=2024.1
python.exe path/to/pyaedt/workflows/project/import_nastran.py --file_path="my_file.stl"
Finally, this code shows how you can run the extension directly from a Python script:

.. code:: python
import pyaedt
import os
from pyaedt.workflows.project.import_nastran import main
file_path = "my_file.stl"
hfss = pyaedt.Hfss()
# Specify the AEDT session to connect
os.environ["PYAEDT_SCRIPT_PORT"] = str(hfss.desktop_class.port)
os.environ["PYAEDT_SCRIPT_VERSION"] = hfss.desktop_class.aedt_version_id
# Launch extension
main({"file_path": file_path, "lightweight": True, "decimate": 0.0, "planar": True, "is_test": False})
2 changes: 0 additions & 2 deletions doc/source/create_documentation.bat

This file was deleted.

Loading

0 comments on commit 8e73ceb

Please sign in to comment.