diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml
index ebe924c3c71..3072d972192 100644
--- a/.github/workflows/ci_cd.yml
+++ b/.github/workflows/ci_cd.yml
@@ -54,7 +54,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
- python-version: ['3.7', '3.8', '3.9', '3.10', '3.11']
+ python-version: ['3.7', '3.8', '3.9', '3.10', '3.11', '3.12']
target: ['all', 'installer']
exclude:
- python-version: '3.7'
@@ -205,11 +205,11 @@ jobs:
.venv\Scripts\Activate.ps1
.\doc\make.bat pdf
- - name: Add assets to HTML docs
- run: |
- zip -r documentation-html.zip ./doc/_build/html
- mv documentation-html.zip ./doc/_build/html/_static/assets/download/
- cp doc/_build/latex/PyAEDT-Documentation-*.pdf ./doc/_build/html/_static/assets/download/pyaedt.pdf
+ # - name: Add assets to HTML docs
+ # run: |
+ # zip -r documentation-html.zip ./doc/_build/html
+ # mv documentation-html.zip ./doc/_build/html/_static/assets/download/
+ # cp doc/_build/latex/PyAEDT-Documentation-*.pdf ./doc/_build/html/_static/assets/download/pyaedt.pdf
- name: Upload HTML documentation with examples artifact
uses: actions/upload-artifact@v3
@@ -458,7 +458,7 @@ jobs:
command: |
export LD_LIBRARY_PATH=${{ env.ANSYSEM_ROOT241 }}/common/mono/Linux64/lib64:${{ env.ANSYSEM_ROOT241 }}/Delcross:$LD_LIBRARY_PATH
source .venv/bin/activate
- pytest -n 4 --dist loadfile --durations=50 -v --cov=pyaedt --cov-report=xml --cov-report=html --junitxml=junit/test-results.xml _unittest
+ pytest -n 2 --dist loadfile --durations=50 -v --cov=pyaedt --cov-report=xml --cov-report=html --junitxml=junit/test-results.xml _unittest
- uses: codecov/codecov-action@v4
with:
diff --git a/.github/workflows/nightly-docs.yml b/.github/workflows/nightly-docs.yml
index 463dbf16f16..4443fed81e1 100644
--- a/.github/workflows/nightly-docs.yml
+++ b/.github/workflows/nightly-docs.yml
@@ -10,6 +10,7 @@ env:
MAIN_PYTHON_VERSION: '3.10'
DOCUMENTATION_CNAME: 'aedt.docs.pyansys.com'
MEILISEARCH_API_KEY: ${{ secrets.MEILISEARCH_API_KEY }}
+ MEILISEARCH_HOST_URL: ${{ vars.MEILISEARCH_HOST_URL }}
MEILISEARCH_PUBLIC_API_KEY: ${{ secrets.MEILISEARCH_PUBLIC_API_KEY }}
concurrency:
@@ -83,11 +84,11 @@ jobs:
.venv\Scripts\Activate.ps1
.\doc\make.bat pdf
- - name: Add assets to HTML docs
- run: |
- zip -r documentation-html.zip ./doc/_build/html
- mv documentation-html.zip ./doc/_build/html/_static/assets/download/
- cp doc/_build/latex/PyAEDT-Documentation-*.pdf ./doc/_build/html/_static/assets/download/pyaedt.pdf
+ # - name: Add assets to HTML docs
+ # run: |
+ # zip -r documentation-html.zip ./doc/_build/html
+ # mv documentation-html.zip ./doc/_build/html/_static/assets/download/
+ # cp doc/_build/latex/PyAEDT-Documentation-*.pdf ./doc/_build/html/_static/assets/download/pyaedt.pdf
- name: Upload HTML documentation with examples artifact
uses: actions/upload-artifact@v3
@@ -103,72 +104,6 @@ jobs:
path: doc/_build/latex/PyAEDT-Documentation-*.pdf
retention-days: 7
- # doc-build-without-examples:
- # name: Documentation build without examples
- # runs-on: ubuntu-latest
- # steps:
- # - name: Install Git and checkout project
- # uses: actions/checkout@v4
-
- # - name: Setup Python
- # uses: actions/setup-python@v5
- # with:
- # python-version: ${{ env.MAIN_PYTHON_VERSION }}
-
- # - name: Update pip
- # run: |
- # pip install --upgrade pip
-
- # - name: Install pyaedt and documentation dependencies
- # run: |
- # pip install .[doc-no-examples]
-
- # - name: Retrieve PyAEDT version
- # id: version
- # run: |
- # echo "PYAEDT_VERSION=$(python -c 'from pyaedt import __version__; print(__version__)')" >> $GITHUB_OUTPUT
- # echo "PyAEDT version is: $(python -c "from pyaedt import __version__; print(__version__)")"
-
- # - name: Install doc build requirements
- # run: |
- # sudo apt update
- # sudo apt install graphviz texlive-latex-extra latexmk texlive-xetex texlive-fonts-extra -y
-
- # # TODO: Update this step once pyaedt-examples is ready
- # - name: Build HTML documentation without examples
- # run: |
- # make -C doc clean
- # make -C doc html-no-examples
-
- # # Verify that sphinx generates no warnings
- # - name: Check for warnings
- # run: |
- # python doc/print_errors.py
-
- # - name: Build PDF documentation without examples
- # run: |
- # make -C doc pdf-no-examples
-
- # - name: Add assets to HTML docs
- # run: |
- # zip -r documentation-html.zip ./doc/_build/html
- # mv documentation-html.zip ./doc/_build/html/_static/assets/download/
- # cp doc/_build/latex/PyAEDT-Documentation-*.pdf ./doc/_build/html/_static/assets/download/pyaedt.pdf
-
- # - name: Upload HTML documentation without examples artifact
- # uses: actions/upload-artifact@v3
- # with:
- # name: documentation-no-examples-html
- # path: doc/_build/html
- # retention-days: 7
-
- # - name: Upload PDF documentation without examples artifact
- # uses: actions/upload-artifact@v3
- # with:
- # name: documentation-pdf
- # path: doc/_build/latex/PyAEDT-Documentation-*.pdf
- # retention-days: 7
-
upload-dev-doc:
name: Upload dev documentation
runs-on: ubuntu-latest
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index d368033e733..a15b8612131 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -27,7 +27,7 @@ repos:
args: ['--force-single-line-imports', '--profile', 'black']
- repo: https://github.com/PyCQA/flake8
- rev: 7.0.0
+ rev: 7.1.0
hooks:
- id: flake8
args:
@@ -48,7 +48,7 @@ repos:
# validate GitHub workflow files
- repo: https://github.com/python-jsonschema/check-jsonschema
- rev: 0.28.4
+ rev: 0.28.6
hooks:
- id: check-github-workflows
@@ -64,6 +64,14 @@ repos:
hooks:
- id: check-pre-commit-ci-config
+- repo: https://github.com/ansys/pre-commit-hooks
+ rev: v0.3.1
+ hooks:
+ - id: add-license-headers
+ files: '(pyaedt|examples|_unittest|_unittest_ironpython|_unittest_solvers)/.*\.(py)'
+ args:
+ - --custom_template=mit_license.jinja2
+ - --start_year=2021
# - repo: https://github.com/numpy/numpydoc
# rev: v1.6.0
diff --git a/.reuse/templates/mit_license.jinja2 b/.reuse/templates/mit_license.jinja2
new file mode 100644
index 00000000000..06fc58439b5
--- /dev/null
+++ b/.reuse/templates/mit_license.jinja2
@@ -0,0 +1,29 @@
+-*- coding: utf-8 -*-
+
+{% for copyright_line in copyright_lines %}
+{{ copyright_line }}
+{% endfor %}
+{% for expression in spdx_expressions %}
+SPDX-License-Identifier: {{ expression }}
+{% endfor %}
+
+
+{% if "MIT" in spdx_expressions %}
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+{% endif %}
diff --git a/LICENSE b/LICENSE
index a9d9a2ef7eb..6a949e7fd8c 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,13 +1,13 @@
MIT License
-Copyright (c) 2021 ANSYS, Inc. All rights reserved.
+Copyright (c) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
diff --git a/README.md b/README.md
index 8cee89d3b48..e8a9e292391 100644
--- a/README.md
+++ b/README.md
@@ -4,8 +4,7 @@
*** PyAEDT README
-->
-
-# PyAEDT
+[](https://aedt.docs.pyansys.com)
English | 中文
diff --git a/_unittest/__init__.py b/_unittest/__init__.py
index e69de29bb2d..9c4476773da 100644
--- a/_unittest/__init__.py
+++ b/_unittest/__init__.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
diff --git a/_unittest/conftest.py b/_unittest/conftest.py
index c65f120585c..aa4dbb3f73a 100644
--- a/_unittest/conftest.py
+++ b/_unittest/conftest.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
"""
Unit Test Configuration Module
-------------------------------
@@ -175,10 +199,10 @@ def _method(
if not application:
application = Hfss
return application(
- projectname=test_project,
- designname=design_name,
+ project=test_project,
+ design=design_name,
solution_type=solution_type,
- specified_version=desktop_version,
+ version=desktop_version,
non_graphical=NONGRAPHICAL,
)
diff --git a/_unittest/example_models/T98/cylinder_mesh.msh b/_unittest/example_models/T98/cylinder_mesh.msh
new file mode 100644
index 00000000000..3481636c14e
Binary files /dev/null and b/_unittest/example_models/T98/cylinder_mesh.msh differ
diff --git a/_unittest/test_01_3dlayout_edb.py b/_unittest/test_01_3dlayout_edb.py
index 3bcab9a0c07..3feb99fe27c 100644
--- a/_unittest/test_01_3dlayout_edb.py
+++ b/_unittest/test_01_3dlayout_edb.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import os
from _unittest.conftest import config
@@ -5,7 +29,7 @@
import pytest
from pyaedt import Hfss3dLayout
-from pyaedt import is_linux
+from pyaedt.generic.settings import is_linux
test_subfolder = "T40"
original_project_name = "ANSYS-HSD_V1"
diff --git a/_unittest/test_01_Design.py b/_unittest/test_01_Design.py
index 6e72a2e8f4c..68a06aa48da 100644
--- a/_unittest/test_01_Design.py
+++ b/_unittest/test_01_Design.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import os
import tempfile
@@ -172,17 +196,17 @@ def test_15a_duplicate_design(self):
def test_15b_copy_design_from(self):
origin = os.path.join(self.local_scratch.path, "origin.aedt")
destin = os.path.join(self.local_scratch.path, "destin.aedt")
- self.aedtapp.save_project(project_file=origin)
+ self.aedtapp.save_project(file_name=origin)
self.aedtapp.duplicate_design("myduplicateddesign")
- self.aedtapp.save_project(project_file=origin, refresh_obj_ids_after_save=True)
+ self.aedtapp.save_project(file_name=origin, refresh_ids=True)
- self.aedtapp.save_project(project_file=destin)
+ self.aedtapp.save_project(file_name=destin)
new_design = self.aedtapp.copy_design_from(origin, "myduplicateddesign")
assert new_design in self.aedtapp.design_list
def test_16_renamedesign(self, add_app, test_project_file):
prj_file = test_project_file(test_project_name)
- self.aedtapp.load_project(project_file=prj_file, close_active_proj=True, design_name="myname")
+ self.aedtapp.load_project(file_name=prj_file, design="myname", close_active=True)
assert "myname" in [
design["Name"]
for design in self.aedtapp.project_properties["AnsoftProject"][model_names[self.aedtapp.design_type]]
@@ -221,6 +245,8 @@ def test_19_create_project_dataset(self):
assert self.aedtapp.dataset_exists("Test_DataSet", is_project_dataset=True)
assert ds2.delete()
assert not self.aedtapp.dataset_exists("Test_DataSet", is_project_dataset=True)
+ ds3 = self.aedtapp.create_dataset1d_project("Test_DataSet2", x, y, sort=False)
+ assert ds3.name == "$Test_DataSet2"
def test_19_create_3dproject_dataset(self):
x = [1, 100]
@@ -228,11 +254,14 @@ def test_19_create_3dproject_dataset(self):
z = [800, 200]
v = [10, 20]
vunits = "cel"
- ds3 = self.aedtapp.create_dataset3d("Test_DataSet3D", x, y, z, v, vunit=vunits)
+ ds3 = self.aedtapp.create_dataset3d("Test_DataSet3D", x, y, z, v, v_unit=vunits)
assert ds3.name == "$Test_DataSet3D"
- ds30 = self.aedtapp.create_dataset3d("Test_DataSet3D1", x, y, z, v, vunit=vunits, is_project_dataset=False)
+ ds3.sort = False
+ ds3.v = [50, 200]
+ assert ds3.update()
+ ds30 = self.aedtapp.create_dataset3d("Test_DataSet3D1", x, y, z, v, v_unit=vunits, is_project_dataset=False)
assert ds30.name == "$Test_DataSet3D1"
- ds31 = self.aedtapp.create_dataset3d("$Test_DataSet3D2", x, y, z, v, vunit=vunits, is_project_dataset=False)
+ ds31 = self.aedtapp.create_dataset3d("$Test_DataSet3D2", x, y, z, v, v_unit=vunits, is_project_dataset=False)
assert ds31.name == "$Test_DataSet3D2"
def test_19_edit_existing_dataset(self):
@@ -245,9 +274,9 @@ def test_19_import_dataset1d(self):
filename = os.path.join(local_path, "example_models", test_subfolder, "ds_1d.tab")
ds4 = self.aedtapp.import_dataset1d(filename)
assert ds4.name == "$ds_1d"
- ds5 = self.aedtapp.import_dataset1d(filename, dsname="dataset_test", is_project_dataset=False)
+ ds5 = self.aedtapp.import_dataset1d(filename, name="dataset_test", is_project_dataset=False)
assert ds5.name == "dataset_test"
- ds6 = self.aedtapp.import_dataset1d(filename, dsname="$dataset_test2")
+ ds6 = self.aedtapp.import_dataset1d(filename, name="$dataset_test2")
assert ds6.name == "$dataset_test2"
ds7 = self.aedtapp.import_dataset1d(filename)
assert not ds7
@@ -260,18 +289,18 @@ def test_19a_import_dataset3d(self):
ds8 = self.aedtapp.import_dataset3d(filename)
assert ds8.name == "$Dataset_3D"
filename = os.path.join(local_path, "example_models", test_subfolder, "Dataset_3D.csv")
- ds8 = self.aedtapp.import_dataset3d(filename, dsname="dataset_csv")
+ ds8 = self.aedtapp.import_dataset3d(filename, name="dataset_csv")
assert ds8.name == "$dataset_csv"
assert ds8.delete()
- ds10 = self.aedtapp.import_dataset3d(filename, dsname="$dataset_test")
+ ds10 = self.aedtapp.import_dataset3d(filename, name="$dataset_test")
assert ds10.zunit == "mm"
filename = os.path.join(local_path, "example_models", test_subfolder, "Dataset_3D.csv")
- ds8 = self.aedtapp.import_dataset3d(filename, encoding="utf-8-sig", dsname="dataset_csv")
+ ds8 = self.aedtapp.import_dataset3d(filename, name="dataset_csv", encoding="utf-8-sig")
assert ds8.name == "$dataset_csv"
def test_19b_import_dataset3d_xlsx(self):
filename = os.path.join(local_path, "example_models", test_subfolder, "Dataset_3D.xlsx")
- ds9 = self.aedtapp.import_dataset3d(filename, dsname="myExcel")
+ ds9 = self.aedtapp.import_dataset3d(filename, name="myExcel")
assert ds9.name == "$myExcel"
def test_20_get_3dComponents_properties(self):
@@ -361,7 +390,7 @@ def test_34_force_project_path_disable(self):
e = None
exception_raised = False
try:
- h = Hfss("c:/dummy/test.aedt", specified_version=desktop_version)
+ h = Hfss("c:/dummy/test.aedt", version=desktop_version)
except Exception as e:
exception_raised = True
assert e.args[0] == "Project doesn't exist. Check it and retry."
@@ -397,7 +426,7 @@ def test_36_test_load(self, add_app):
with open(file_name2_lock, "w") as f:
f.write(" ")
try:
- hfss = Hfss(projectname=file_name2, specified_version=desktop_version)
+ hfss = Hfss(project=file_name2, version=desktop_version)
except Exception:
assert True
try:
@@ -405,7 +434,7 @@ def test_36_test_load(self, add_app):
file_name3 = os.path.join(self.local_scratch.path, "test_36_2.aedb", "edb.def")
with open(file_name3, "w") as f:
f.write(" ")
- hfss = Hfss3dLayout(projectname=file_name3, specified_version=desktop_version)
+ hfss = Hfss3dLayout(project=file_name3, version=desktop_version)
except Exception:
assert True
@@ -432,7 +461,7 @@ def test_38_toolkit(self, desktop):
def test_39_load_project(self, desktop):
new_project = os.path.join(self.local_scratch.path, "new.aedt")
- self.aedtapp.save_project(project_file=new_project)
+ self.aedtapp.save_project(file_name=new_project)
self.aedtapp.close_project(name="new")
aedtapp = desktop.load_project(new_project)
assert aedtapp
diff --git a/_unittest/test_01_GeometryOperators.py b/_unittest/test_01_GeometryOperators.py
index cd1e88f3ec9..9ec435b2464 100644
--- a/_unittest/test_01_GeometryOperators.py
+++ b/_unittest/test_01_GeometryOperators.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import math
import pytest
diff --git a/_unittest/test_01_configuration_files.py b/_unittest/test_01_configuration_files.py
index 33e19fe4f6f..b2cbcf3e2d2 100644
--- a/_unittest/test_01_configuration_files.py
+++ b/_unittest/test_01_configuration_files.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
# standard imports
import json
import os
@@ -79,12 +103,12 @@ def test_01_hfss_export(self, aedtapp, add_app):
file_path = os.path.join(aedtapp.working_directory, filename + ".x_b")
aedtapp.export_3d_model(filename, aedtapp.working_directory, ".x_b", [], [])
app = add_app(project_name="new_proj", solution_type=aedtapp.solution_type, just_open=True)
- app.modeler.import_3d_cad(file_path)
+ app.import_3d_cad(file_path)
out = app.configurations.import_config(conf_file)
assert isinstance(out, dict)
assert app.configurations.validate(out)
assert app.configurations.results.global_import_success
- app.close_project(save_project=False)
+ app.close_project(save=False)
def test_02_q3d_export(self, q3dtest, add_app):
q3dtest.modeler.create_coordinate_system()
@@ -101,7 +125,7 @@ def test_02_q3d_export(self, q3dtest, add_app):
assert isinstance(out, dict)
assert app.configurations.validate(out)
assert app.configurations.results.global_import_success
- app.close_project(save_project=False)
+ app.close_project(save=False)
def test_03_q2d_export(self, q2dtest, add_app):
conf_file = q2dtest.configurations.export_config()
@@ -153,7 +177,7 @@ def test_03_q2d_export(self, q2dtest, add_app):
assert q2dtest.configurations.options.import_mesh_operations
assert q2dtest.configurations.options.import_object_properties
assert q2dtest.configurations.options.import_parametrics
- app.close_project(save_project=False)
+ app.close_project(save=False)
def test_04a_icepak(self, icepak_a, aedtapp, add_app):
box1 = icepak_a.modeler.create_box([0, 0, 0], [10, 10, 10])
@@ -184,13 +208,12 @@ def test_04a_icepak(self, icepak_a, aedtapp, add_app):
"test_dataset",
[1, 2, 3, 4],
[1, 2, 3, 4],
- zlist=None,
- vlist=None,
+ z=None,
+ v=None,
is_project_dataset=False,
- xunit="cel",
- yunit="W",
- zunit="",
- vunit="",
+ x_unit="cel",
+ y_unit="W",
+ v_unit="",
)
filename = icepak_a.design_name
icepak_a.export_3d_model(filename, icepak_a.working_directory, ".x_b", [], [])
@@ -235,7 +258,7 @@ def test_04a_icepak(self, icepak_a, aedtapp, add_app):
out = app.configurations.import_config(old_conf_file)
assert isinstance(out, dict)
assert app.configurations.results.global_import_success
- app.close_project(save_project=False)
+ app.close_project(save=False)
@pytest.mark.skipif(
config["desktopVersion"] < "2023.1" and config["use_grpc"],
@@ -269,13 +292,12 @@ def test_04b_icepak(self, icepak_b, add_app):
"test_dataset",
[1, 2, 3, 4],
[1, 2, 3, 4],
- zlist=None,
- vlist=None,
+ z=None,
+ v=None,
is_project_dataset=False,
- xunit="cel",
- yunit="W",
- zunit="",
- vunit="",
+ x_unit="cel",
+ y_unit="W",
+ v_unit="",
)
filename = icepak_b.design_name
icepak_b.export_3d_model(filename, icepak_b.working_directory, ".x_b", [], [])
diff --git a/_unittest/test_01_downloads.py b/_unittest/test_01_downloads.py
index f8d1b71a447..66f89601a2c 100644
--- a/_unittest/test_01_downloads.py
+++ b/_unittest/test_01_downloads.py
@@ -1,11 +1,35 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import os
import tempfile
import pytest
from pyaedt import downloads
-from pyaedt import is_linux
from pyaedt.generic.general_methods import generate_unique_name
+from pyaedt.generic.settings import is_linux
@pytest.fixture(scope="module", autouse=True)
diff --git a/_unittest/test_01_general_methods.py b/_unittest/test_01_general_methods.py
index 6b53e40f0ca..d8e3e5ab8f8 100644
--- a/_unittest/test_01_general_methods.py
+++ b/_unittest/test_01_general_methods.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import pytest
from pyaedt.generic.DataHandlers import str_to_bool
diff --git a/_unittest/test_01_report_file_parser.py b/_unittest/test_01_report_file_parser.py
index 5241f2f1c29..aa046f0f63e 100644
--- a/_unittest/test_01_report_file_parser.py
+++ b/_unittest/test_01_report_file_parser.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import os
import pytest
diff --git a/_unittest/test_01_toolkit_icons.py b/_unittest/test_01_toolkit_icons.py
index 99922aa102d..303eb3c23a8 100644
--- a/_unittest/test_01_toolkit_icons.py
+++ b/_unittest/test_01_toolkit_icons.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import os
import defusedxml.ElementTree as ET
diff --git a/_unittest/test_02_2D_modeler.py b/_unittest/test_02_2D_modeler.py
index ce1a6d1a416..49cb7175fb6 100644
--- a/_unittest/test_02_2D_modeler.py
+++ b/_unittest/test_02_2D_modeler.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
# standard imports
import filecmp
import math
diff --git a/_unittest/test_02_3D_modeler.py b/_unittest/test_02_3D_modeler.py
index e5004ff86a7..e9e4ef510ec 100644
--- a/_unittest/test_02_3D_modeler.py
+++ b/_unittest/test_02_3D_modeler.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import random
from _unittest.conftest import config
diff --git a/_unittest/test_03_Materials.py b/_unittest/test_03_Materials.py
index 6cece448949..3779bdae18d 100644
--- a/_unittest/test_03_Materials.py
+++ b/_unittest/test_03_Materials.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import os
from _unittest.conftest import config
diff --git a/_unittest/test_04_SBR.py b/_unittest/test_04_SBR.py
index 0bdf8a10593..7ef95e00347 100644
--- a/_unittest/test_04_SBR.py
+++ b/_unittest/test_04_SBR.py
@@ -1,7 +1,37 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+import builtins
import os
+import sys
+from unittest.mock import mock_open
+from mock import patch
import pytest
+from pyaedt.sbrplus.hdm_parser import Parser
+
try:
import osmnx
except ImportError:
@@ -10,7 +40,7 @@
from _unittest.conftest import desktop_version
from _unittest.conftest import local_path
-from pyaedt import is_linux
+from pyaedt.generic.settings import is_linux
if desktop_version > "2022.2":
test_project_name = "Cassegrain_231"
@@ -28,6 +58,28 @@
test_subfolder = "T17"
+CORRECT_HDM_HEADER = b"""
+# The binary data starts immediately after the '#header end' line.
+{
+ 'types':
+ {
+ 'Int32': {'type': 'int', 'size' : 4, },
+ 'Bundle': {'type': 'object', 'layout' : (
+ {'type': 'Int32', 'field_names': ('version', ), },
+ ),
+ },
+ },
+'message': {'type': 'Bundle'}
+}
+#header end
+"""
+INCORRECT_HDM_HEADER = b"""
+# The binary data starts immediately after the '#header end' line.
+{
+ 12
+#header end
+"""
+
@pytest.fixture(scope="class")
def aedtapp(add_app):
@@ -202,6 +254,7 @@ def test_12_import_map(self):
for part in parts_dict["parts"]:
assert os.path.exists(parts_dict["parts"][part]["file_name"])
+ @pytest.mark.skipif(sys.version_info > (3, 8), reason="Bug in VTK with 3.12")
@pytest.mark.skipif(is_linux, reason="feature supported in Cpython")
def test_16_read_hdm(self):
self.aedtapp.insert_design("hdm")
@@ -217,3 +270,24 @@ def test_16_read_hdm(self):
assert plotter
plotter.plot_rays(os.path.join(self.local_scratch.path, "bounce2.jpg"))
assert os.path.exists(os.path.join(self.local_scratch.path, "bounce2.jpg"))
+
+ @patch.object(builtins, "open", new_callable=mock_open, read_data=CORRECT_HDM_HEADER)
+ def test_hdm_parser_header_loading_success(self, mock_file_open):
+ """Test that HDM parser loads header correctly."""
+ expected_result = {
+ "message": {"type": "Bundle"},
+ "types": {
+ "Bundle": {"layout": ({"field_names": ("version",), "type": "Int32"},), "type": "object"},
+ "Int32": {"size": 4, "type": "int"},
+ },
+ }
+ hdm_parser = Parser("some path")
+
+ assert expected_result == hdm_parser.header
+
+ @patch.object(builtins, "open", new_callable=mock_open, read_data=INCORRECT_HDM_HEADER)
+ def test_hdm_parser_header_loading_failure(self, mock_file_open):
+ """Test that HDM parser fails to load header."""
+
+ with pytest.raises(SyntaxError):
+ Parser("some path")
diff --git a/_unittest/test_05_Mesh.py b/_unittest/test_05_Mesh.py
index fe73eb8ebce..03c6399ce62 100644
--- a/_unittest/test_05_Mesh.py
+++ b/_unittest/test_05_Mesh.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
from _unittest.conftest import config
from _unittest.conftest import desktop_version
import pytest
diff --git a/_unittest/test_06_MessageManager.py b/_unittest/test_06_MessageManager.py
index dbe9fda245d..c85d7c41082 100644
--- a/_unittest/test_06_MessageManager.py
+++ b/_unittest/test_06_MessageManager.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import logging
import os.path
diff --git a/_unittest/test_07_Object3D.py b/_unittest/test_07_Object3D.py
index 13d2e6a3011..1fe9aada249 100644
--- a/_unittest/test_07_Object3D.py
+++ b/_unittest/test_07_Object3D.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import math
import pytest
@@ -595,7 +619,7 @@ def test_27_get_object_history_properties(self):
assert box_clone_history.children["Rotate:1"].command == "Rotate"
assert box_clone_history.children["SplitEdit:1"].command == "SplitEdit"
project_path = self.aedtapp.project_file
- self.aedtapp.close_project(save_project=True)
+ self.aedtapp.close_project(save=True)
self.aedtapp.load_project(project_path)
subtract = self.aedtapp.modeler["box_history1"].history().children["Subtract:1"].children
assert len(subtract) == 1
diff --git a/_unittest/test_08_Primitives3D.py b/_unittest/test_08_Primitives3D.py
index d8c8dedb945..3d34aabf3fa 100644
--- a/_unittest/test_08_Primitives3D.py
+++ b/_unittest/test_08_Primitives3D.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import os
import sys
import time
@@ -9,8 +33,8 @@
from pyaedt import Icepak
from pyaedt import Q2d
from pyaedt import generate_unique_name
-from pyaedt import is_linux
from pyaedt.generic.constants import AXIS
+from pyaedt.generic.settings import is_linux
from pyaedt.modeler.cad.Primitives import PolylineSegment
from pyaedt.modeler.cad.components_3d import UserDefinedComponent
from pyaedt.modeler.cad.object3d import Object3d
@@ -1065,7 +1089,7 @@ def test_54b_open_and_load_a_polyline(self, add_app):
assert len(p3) == 3
assert len(s3) == 1
- aedtapp.close_project(save_project=False)
+ aedtapp.close_project(save=False)
def test_55_create_bond_wires(self):
self.aedtapp["$Ox"] = 0
@@ -1142,7 +1166,7 @@ def test_59_lines(self):
@pytest.mark.skipif("UNITTEST_CURRENT_TEST" in os.environ, reason="Issue in IronPython")
def test_60_get_edges_on_bounding_box(self):
- self.aedtapp.close_project(name=self.aedtapp.project_name, save_project=False)
+ self.aedtapp.close_project(name=self.aedtapp.project_name, save=False)
self.aedtapp.load_project(self.test_99_project)
edges = self.aedtapp.modeler.get_edges_on_bounding_box(["Port1", "Port2"], return_colinear=True, tolerance=1e-6)
assert len(edges) == 2
diff --git a/_unittest/test_09_Primitives2D.py b/_unittest/test_09_Primitives2D.py
index e448859e878..b688ede2849 100644
--- a/_unittest/test_09_Primitives2D.py
+++ b/_unittest/test_09_Primitives2D.py
@@ -1,4 +1,29 @@
#!/ekm/software/anaconda3/bin/python
+
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import pytest
from pyaedt import Maxwell2d
diff --git a/_unittest/test_09_VariableManager.py b/_unittest/test_09_VariableManager.py
index 7f934255478..23844f3a5c1 100644
--- a/_unittest/test_09_VariableManager.py
+++ b/_unittest/test_09_VariableManager.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
from __future__ import division # noreorder
import math
@@ -156,9 +180,9 @@ def test_04_set_variable(self):
assert self.aedtapp.variable_manager.set_variable("p1", expression="30mm")
assert self.aedtapp["p1"] == "30mm"
assert self.aedtapp.variable_manager.set_variable(
- variable_name="p2",
+ name="p2",
expression="10mm",
- readonly=True,
+ read_only=True,
hidden=True,
description="This is a description of this variable",
)
@@ -409,10 +433,10 @@ def test_12_decompose_variable_value(self):
assert decompose_variable_value("3.123456kgm2") == (3.123456, "kgm2")
def test_13_postprocessing(self):
- v1 = self.aedtapp.variable_manager.set_variable("test_post1", 10, postprocessing=True)
+ v1 = self.aedtapp.variable_manager.set_variable("test_post1", 10, is_post_processing=True)
assert v1
assert not self.aedtapp.variable_manager.set_variable("test2", "v1+1")
- assert self.aedtapp.variable_manager.set_variable("test2", "test_post1+1", postprocessing=True)
+ assert self.aedtapp.variable_manager.set_variable("test2", "test_post1+1", is_post_processing=True)
x1 = GeometryOperators.parse_dim_arg(
self.aedtapp.variable_manager["test2"].evaluated_value, variable_manager=self.aedtapp.variable_manager
)
@@ -435,7 +459,7 @@ def test_15_arrays(self):
assert self.aedtapp.variable_manager["getvalue2"].numeric_value == 1.0
def test_16_maxwell_circuit_variables(self):
- mc = MaxwellCircuit(specified_version=desktop_version)
+ mc = MaxwellCircuit(version=desktop_version)
mc["var2"] = "10mm"
assert mc["var2"] == "10mm"
v_circuit = mc.variable_manager
diff --git a/_unittest/test_11_Setup.py b/_unittest/test_11_Setup.py
index b97a6c8a584..5ac553f8e5f 100644
--- a/_unittest/test_11_Setup.py
+++ b/_unittest/test_11_Setup.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import os
from _unittest.conftest import desktop_version
@@ -77,7 +101,7 @@ def test_01c_create_hfss_setup_auto_open(self):
assert setup1.props["SolveType"] == "MultiFrequency"
def test_02_create_circuit_setup(self):
- circuit = Circuit(specified_version=desktop_version)
+ circuit = Circuit(version=desktop_version)
setup1 = circuit.create_setup("circuit", self.aedtapp.SETUPS.NexximLNA)
assert setup1.name == "circuit"
setup1.props["SweepDefinition"]["Data"] = "LINC 0GHz 4GHz 501"
diff --git a/_unittest/test_12_1_PostProcessing.py b/_unittest/test_12_1_PostProcessing.py
index 45382124944..6efb2d9ba49 100644
--- a/_unittest/test_12_1_PostProcessing.py
+++ b/_unittest/test_12_1_PostProcessing.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import os
import sys
import uuid
diff --git a/_unittest/test_12_PostProcessing.py b/_unittest/test_12_PostProcessing.py
index c3539714afc..0dfebc86637 100644
--- a/_unittest/test_12_PostProcessing.py
+++ b/_unittest/test_12_PostProcessing.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import os
import sys
@@ -194,10 +218,12 @@ def test_09_manipulate_report_C(self, field_test):
report_category="Far Fields",
context="3D",
)
- assert data.plot(snapshot_path=os.path.join(self.local_scratch.path, "reportC.jpg"))
- assert data.plot_3d(snapshot_path=os.path.join(self.local_scratch.path, "reportC_3D.jpg"))
+ assert data.plot(snapshot_path=os.path.join(self.local_scratch.path, "reportC.jpg"), show=False)
+ assert data.plot_3d(snapshot_path=os.path.join(self.local_scratch.path, "reportC_3D.jpg"), show=False)
assert field_test.post.create_3d_plot(
- data, snapshot_path=os.path.join(self.local_scratch.path, "reportC_3D_2.jpg")
+ data,
+ snapshot_path=os.path.join(self.local_scratch.path, "reportC_3D_2.jpg"),
+ show=False,
)
def test_09_manipulate_report_D(self, field_test):
@@ -215,7 +241,7 @@ def test_09_manipulate_report_D(self, field_test):
context=context,
)
assert field_test.post.create_3d_plot(
- data, snapshot_path=os.path.join(self.local_scratch.path, "reportD_3D_2.jpg")
+ data, snapshot_path=os.path.join(self.local_scratch.path, "reportD_3D_2.jpg"), show=False
)
assert data.primary_sweep == "Theta"
assert len(data.data_magnitude("GainTotal")) > 0
@@ -250,11 +276,12 @@ def test_09_manipulate_report_E(self, field_test):
assert field_test.post.get_far_field_data(
expressions="RealizedGainTotal", setup_sweep_name=field_test.nominal_adaptive, domain="3D"
)
- field_test.post.get_far_field_data(
+ data_farfield2 = field_test.post.get_far_field_data(
expressions="RealizedGainTotal",
setup_sweep_name=field_test.nominal_adaptive,
domain={"Context": "3D", "SourceContext": "1:1"},
)
+ assert data_farfield2.plot(formula="db20", is_polar=True, show=False)
assert field_test.post.reports_by_category.terminal_solution()
@@ -380,7 +407,9 @@ def test_18_diff_plot(self, diff_test):
data1.primary_sweep = "l1"
assert data1.primary_sweep == "l1"
assert len(data1.data_magnitude()) == 5
- assert data1.plot("S(Diff1, Diff1)", snapshot_path=os.path.join(self.local_scratch.path, "diff_pairs.jpg"))
+ assert data1.plot(
+ "S(Diff1, Diff1)", snapshot_path=os.path.join(self.local_scratch.path, "diff_pairs.jpg"), show=False
+ )
assert diff_test.create_touchstone_report(
name="Diff_plot", curves=["dB(S(Diff1, Diff1))"], solution="LinearFrequency", differential_pairs=True
@@ -621,6 +650,7 @@ def test_70_far_field_data(self):
)
assert isinstance(data_pyvista, Plotter)
+ @pytest.mark.skipif(sys.version_info > (3, 11), reason="Issues with VTK in Python 3.12")
@pytest.mark.skipif(is_linux or sys.version_info < (3, 8), reason="FarFieldSolution not supported by IronPython")
def test_71_antenna_plot(self, field_test):
ffdata = field_test.get_antenna_ffd_solution_data(frequencies=30e9, sphere="3D")
@@ -643,6 +673,7 @@ def test_71_antenna_plot(self, field_test):
secondary_sweep_value=[-180, -75, 75],
title="Azimuth at {}Hz".format(ffdata.frequency),
image_path=os.path.join(self.local_scratch.path, "2d1.jpg"),
+ show=False,
)
assert os.path.exists(os.path.join(self.local_scratch.path, "2d1.jpg"))
ffdata.plot_2d_cut(
@@ -651,12 +682,16 @@ def test_71_antenna_plot(self, field_test):
secondary_sweep_value=30,
title="Azimuth at {}Hz".format(ffdata.frequency),
image_path=os.path.join(self.local_scratch.path, "2d2.jpg"),
+ show=False,
)
assert os.path.exists(os.path.join(self.local_scratch.path, "2d2.jpg"))
ffdata.polar_plot_3d(
- quantity="RealizedGain", image_path=os.path.join(self.local_scratch.path, "3d1.jpg"), convert_to_db=True
+ quantity="RealizedGain",
+ image_path=os.path.join(self.local_scratch.path, "3d1.jpg"),
+ convert_to_db=True,
+ show=False,
)
assert os.path.exists(os.path.join(self.local_scratch.path, "3d1.jpg"))
@@ -708,7 +743,10 @@ def test_72_antenna_plot(self, array_test):
assert os.path.exists(os.path.join(self.local_scratch.path, "2d2.jpg"))
ffdata.polar_plot_3d(
- quantity="RealizedGain", image_path=os.path.join(self.local_scratch.path, "3d1.jpg"), convert_to_db=True
+ quantity="RealizedGain",
+ image_path=os.path.join(self.local_scratch.path, "3d1.jpg"),
+ convert_to_db=True,
+ show=False,
)
assert os.path.exists(os.path.join(self.local_scratch.path, "3d1.jpg"))
diff --git a/_unittest/test_13_LoadAEDTFile.py b/_unittest/test_13_LoadAEDTFile.py
index 32dae828262..256260eb42f 100644
--- a/_unittest/test_13_LoadAEDTFile.py
+++ b/_unittest/test_13_LoadAEDTFile.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import base64
import filecmp
import os
diff --git a/_unittest/test_14_AedtLogger.py b/_unittest/test_14_AedtLogger.py
index 09f246b13ec..ba8900b741a 100644
--- a/_unittest/test_14_AedtLogger.py
+++ b/_unittest/test_14_AedtLogger.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import io
import logging
import os
@@ -230,10 +254,10 @@ def test_log_when_accessing_non_existing_object(self, caplog):
from pyaedt import Hfss
app = Hfss(
- projectname="log_project",
- designname="log_design",
- specified_version=desktop_version,
- new_desktop_session=True,
+ project="log_project",
+ design="log_design",
+ version=desktop_version,
+ new_desktop=True,
)
with pytest.raises(AttributeError):
app.get_object_material_properties("MS1", "conductivity")
diff --git a/_unittest/test_15_ibs_reader.py b/_unittest/test_15_ibs_reader.py
index e1d5453dacb..0fa6de41c51 100644
--- a/_unittest/test_15_ibs_reader.py
+++ b/_unittest/test_15_ibs_reader.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import os
from _unittest.conftest import local_path
diff --git a/_unittest/test_16_3d_stackup.py b/_unittest/test_16_3d_stackup.py
index 0a503983b66..9250fdd7dea 100644
--- a/_unittest/test_16_3d_stackup.py
+++ b/_unittest/test_16_3d_stackup.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import pytest
diff --git a/_unittest/test_20_HFSS.py b/_unittest/test_20_HFSS.py
index f70f81b9117..48ffe2c4f37 100644
--- a/_unittest/test_20_HFSS.py
+++ b/_unittest/test_20_HFSS.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import math
import os
import shutil
@@ -943,7 +967,7 @@ def test_33_copy_solid_bodies(self, add_app):
design_name = "HfssCopiedBodies"
new_design = add_app(project_name=project_name, design_name=design_name)
num_orig_bodies = len(self.aedtapp.modeler.solid_names)
- assert new_design.copy_solid_bodies_from(self.aedtapp, vacuum=False, pec=False)
+ assert new_design.copy_solid_bodies_from(self.aedtapp, no_vacuum=False, no_pec=False)
assert len(new_design.modeler.solid_bodies) == num_orig_bodies
new_design.delete_design(design_name)
new_design.close_project(project_name)
@@ -1296,7 +1320,7 @@ def test_52_crate_setup_hybrid_sbr(self, add_app):
assert bound.props["Type"] == "IE"
bound.props["Type"] = "PO"
assert bound.props["Type"] == "PO"
- aedtapp.close_project(save_project=False)
+ aedtapp.close_project(save=False)
def test_53_import_source_excitation(self, add_app):
aedtapp = add_app(solution_type="Modal", project_name="test_53")
@@ -1310,7 +1334,7 @@ def test_53_import_source_excitation(self, add_app):
assert aedtapp.edit_source_from_file(
aedtapp.excitations[0], time_domain, is_time_domain=True, x_scale=1e-6, y_scale=1e-3, data_format="Voltage"
)
- aedtapp.close_project(save_project=False)
+ aedtapp.close_project(save=False)
def test_54_assign_symmetry(self, add_app):
aedtapp = add_app(project_name="test_54", solution_type="Modal")
@@ -1330,7 +1354,7 @@ def test_54_assign_symmetry(self, add_app):
assert not aedtapp.assign_symmetry(ids[0])
assert not aedtapp.assign_symmetry("test")
assert aedtapp.set_impedance_multiplier(2)
- aedtapp.close_project(save_project=False)
+ aedtapp.close_project(save=False)
def test_55_create_near_field_sphere(self):
air = self.aedtapp.modeler.create_box([0, 0, 0], [20, 20, 20], name="rad", material="vacuum")
@@ -1630,13 +1654,13 @@ def test_66_assign_febi(self, add_app):
aedtapp.hybrid = True
assert aedtapp.assign_febi(["inner"])
assert len(aedtapp.boundaries) == 1
- aedtapp.close_project(save_project=False)
+ aedtapp.close_project(save=False)
def test_67_transient_composite(self, add_app):
aedtapp = add_app(project_name="test_66")
aedtapp.solution_type = "Transient Composite"
assert aedtapp.solution_type == "Transient Composite"
- aedtapp.close_project(save_project=False)
+ aedtapp.close_project(save=False)
@pytest.mark.skipif(config["NonGraphical"], reason="Test fails on build machine")
def test_68_import_gds_3d(self):
diff --git a/_unittest/test_21_Circuit.py b/_unittest/test_21_Circuit.py
index 23b44ed622e..f342e63d75d 100644
--- a/_unittest/test_21_Circuit.py
+++ b/_unittest/test_21_Circuit.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import os
import time
@@ -6,7 +30,7 @@
import pytest
from pyaedt import Circuit
-from pyaedt import is_linux
+from pyaedt.generic.settings import is_linux
test_subfolder = "T21"
diff --git a/_unittest/test_22_Circuit_DynamicLink.py b/_unittest/test_22_Circuit_DynamicLink.py
index 4756805a3b9..37891b77d86 100644
--- a/_unittest/test_22_Circuit_DynamicLink.py
+++ b/_unittest/test_22_Circuit_DynamicLink.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import os
from _unittest.conftest import config
@@ -7,8 +31,8 @@
from pyaedt import Circuit
from pyaedt import Q2d
from pyaedt import Q3d
-from pyaedt import is_ironpython
-from pyaedt import is_linux
+from pyaedt.generic.general_methods import is_ironpython
+from pyaedt.generic.settings import is_linux
test_subfloder = "T22"
test_project_name = "Dynamic_Link"
diff --git a/_unittest/test_27_Maxwell2D.py b/_unittest/test_27_Maxwell2D.py
index 39f36dae04a..d19bd64ce6b 100644
--- a/_unittest/test_27_Maxwell2D.py
+++ b/_unittest/test_27_Maxwell2D.py
@@ -1,4 +1,29 @@
#!/ekm/software/anaconda3/bin/python
+
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
from collections import OrderedDict
import os
import shutil
diff --git a/_unittest/test_28_Maxwell3D.py b/_unittest/test_28_Maxwell3D.py
index d60dbd56748..5cb4110b245 100644
--- a/_unittest/test_28_Maxwell3D.py
+++ b/_unittest/test_28_Maxwell3D.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import os
import shutil
@@ -480,7 +504,7 @@ def test_32_matrix(self, add_app):
L = m3d.assign_matrix(assignment="Current1")
assert not L
- def test_32B_matrix(self, add_app):
+ def test_32a_matrix(self, add_app):
m3d = add_app(application=Maxwell3d, design_name="Matrix2")
m3d.solution_type = SOLUTIONS.Maxwell3d.EddyCurrent
m3d.modeler.create_box([0, 1.5, 0], [1, 2.5, 5], name="Coil_1", material="aluminum")
@@ -493,22 +517,24 @@ def test_32B_matrix(self, add_app):
rectangle3 = m3d.modeler.create_rectangle(0, [16.5, 1.5, 0], [2.5, 5], name="Sheet3")
rectangle4 = m3d.modeler.create_rectangle(0, [32.5, 1.5, 0], [2.5, 5], name="Sheet4")
+ m3d.modeler.create_polyline(points=[[1, 2.75, 2.5], [8.5, 2.75, 2.5]], name="line_test")
+
m3d.assign_current(rectangle1.faces[0], amplitude=1, name="Cur1")
m3d.assign_current(rectangle2.faces[0], amplitude=1, name="Cur2")
m3d.assign_current(rectangle3.faces[0], amplitude=1, name="Cur3")
m3d.assign_current(rectangle4.faces[0], amplitude=1, name="Cur4")
- L = m3d.assign_matrix(assignment=["Cur1", "Cur2", "Cur3"])
- out = L.join_series(["Cur1", "Cur2"])
+ L = m3d.assign_matrix(assignment=["Cur1", "Cur2", "Cur3"], matrix_name="Matrix1")
+ out = L.join_series(sources=["Cur1", "Cur2"], matrix_name="ReducedMatrix1")
assert isinstance(out[0], str)
assert isinstance(out[1], str)
- out = L.join_parallel(["Cur1", "Cur3"])
+ out = L.join_parallel(["Cur1", "Cur3"], matrix_name="ReducedMatrix2")
assert isinstance(out[0], str)
assert isinstance(out[1], str)
out = L.join_parallel(["Cur5"])
assert not out[0]
- def test_32a_export_rl_matrix(self):
+ def test_32b_export_rl_matrix(self):
self.aedtapp.set_active_design("Matrix2")
L = self.aedtapp.assign_matrix(assignment=["Cur1", "Cur2", "Cur3"], matrix_name="matrix_export_test")
L.join_series(["Cur1", "Cur2"], matrix_name="reduced_matrix_export_test")
@@ -527,6 +553,75 @@ def test_32a_export_rl_matrix(self):
assert self.aedtapp.export_rl_matrix("matrix_export_test", export_path_2, False, 10, 3, True)
assert os.path.exists(export_path_2)
+ def test_32c_post_processing(self):
+ expressions = self.aedtapp.post.available_report_quantities(
+ report_category="EddyCurrent", display_type="Data Table", context={"Matrix1": "ReducedMatrix1"}
+ )
+ assert isinstance(expressions, list)
+ categories = self.aedtapp.post.available_quantities_categories(
+ report_category="EddyCurrent", display_type="Data Table", context={"Matrix1": "ReducedMatrix1"}
+ )
+ assert isinstance(categories, list)
+ assert "R" in categories
+ assert "L" in categories
+ categories = self.aedtapp.post.available_quantities_categories(
+ report_category="EddyCurrent", display_type="Data Table", context="Matrix1"
+ )
+ assert isinstance(categories, list)
+ assert "R" in categories
+ assert "L" in categories
+ assert "Z" in categories
+ categories = self.aedtapp.post.available_quantities_categories(
+ report_category="EddyCurrent", display_type="Data Table"
+ )
+ assert isinstance(categories, list)
+ assert "R" in categories
+ assert "L" in categories
+ assert "Z" in categories
+ report = self.aedtapp.post.create_report(
+ expressions=expressions,
+ context={"Matrix1": "ReducedMatrix1"},
+ plot_type="Data Table",
+ plot_name="reduced_matrix",
+ )
+ assert report.expressions == expressions
+ assert report.matrix == "Matrix1"
+ assert report.reduced_matrix == "ReducedMatrix1"
+ data = self.aedtapp.post.get_solution_data(expressions=expressions, context={"Matrix1": "ReducedMatrix1"})
+ assert data
+ expressions = self.aedtapp.post.available_report_quantities(
+ report_category="EddyCurrent", display_type="Data Table"
+ )
+ assert isinstance(expressions, list)
+ expressions = self.aedtapp.post.available_report_quantities(
+ report_category="EddyCurrent", display_type="Data Table", context="Matrix1"
+ )
+ assert isinstance(expressions, list)
+ report = self.aedtapp.post.create_report(
+ expressions=expressions,
+ context="Matrix1",
+ plot_type="Data Table",
+ plot_name="reduced_matrix",
+ )
+ assert report.expressions == expressions
+ assert report.matrix == "Matrix1"
+ assert not report.reduced_matrix
+ data = self.aedtapp.post.get_solution_data(expressions=expressions, context="Matrix1")
+ assert data
+
+ report = self.aedtapp.post.create_report(
+ expressions="Mag_H", context="line_test", primary_sweep_variable="Distance", report_category="Fields"
+ )
+ assert report.expressions == ["Mag_H"]
+ assert report.polyline == "line_test"
+ data = self.aedtapp.post.get_solution_data(
+ expressions=["Mag_H"],
+ context="line_test",
+ report_category="Fields",
+ primary_sweep_variable="Distance",
+ )
+ assert data
+
def test_33_mesh_settings(self):
assert self.aedtapp.mesh.initial_mesh_settings
assert self.aedtapp.mesh.initial_mesh_settings.props
diff --git a/_unittest/test_29_Mechanical.py b/_unittest/test_29_Mechanical.py
index c353a1d505d..d00903202b2 100644
--- a/_unittest/test_29_Mechanical.py
+++ b/_unittest/test_29_Mechanical.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import os
import shutil
diff --git a/_unittest/test_30_Q2D.py b/_unittest/test_30_Q2D.py
index ec88160bca7..53a4e41c8f9 100644
--- a/_unittest/test_30_Q2D.py
+++ b/_unittest/test_30_Q2D.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import os
from _unittest.conftest import config
@@ -102,7 +126,7 @@ def test_11_matrix_reduction(self, add_app):
assert q2d.matrices[4].name == "Test4"
assert q2d.insert_reduced_matrix(q2d.MATRIXOPERATIONS.DiffPair, ["Circle2", "Circle3"], "Test5", "New_net")
assert q2d.matrices[5].name == "Test5"
- self.aedtapp.close_project(q2d.project_name, save_project=False)
+ self.aedtapp.close_project(q2d.project_name, save=False)
def test_12_edit_sources(self, add_app):
q2d = add_app(application=Q2d, project_name=self.test_matrix, just_open=True)
@@ -119,7 +143,7 @@ def test_12_edit_sources(self, add_app):
sources_ac = {"Circle5": "40A"}
assert not q2d.edit_sources(sources_cg, sources_ac)
- self.aedtapp.close_project(q2d.project_name, save_project=False)
+ self.aedtapp.close_project(q2d.project_name, save=False)
def test_13_get_all_conductors(self):
self.aedtapp.insert_design("condcutors")
@@ -189,7 +213,7 @@ def test_14_export_matrix_data(self, add_app):
assert not q2d.export_matrix_data(os.path.join(self.local_scratch.path, "test_2d.txt"), c_unit="H")
assert q2d.export_matrix_data(os.path.join(self.local_scratch.path, "test_2d.txt"), g_unit="fSie")
assert not q2d.export_matrix_data(os.path.join(self.local_scratch.path, "test_2d.txt"), g_unit="A")
- self.aedtapp.close_project(q2d.project_name, save_project=True)
+ self.aedtapp.close_project(q2d.project_name, save=True)
def test_15_export_equivalent_circuit(self, add_app):
q2d = add_app(application=Q2d, project_name=self.test_matrix, just_open=True)
@@ -274,13 +298,13 @@ def test_15_export_equivalent_circuit(self, add_app):
assert not q2d.export_equivalent_circuit(
output_file=os.path.join(self.local_scratch.path, "test_export_circuit.cir"), model="test"
)
- self.aedtapp.close_project(q2d.project_name, save_project=False)
+ self.aedtapp.close_project(q2d.project_name, save=False)
def test_16_export_results_q2d(self, add_app):
q2d = add_app(application=Q2d, project_name=self.test_matrix, just_open=True)
exported_files = q2d.export_results(analyze=True)
assert len(exported_files) > 0
- self.aedtapp.close_project(q2d.project_name, save_project=False)
+ self.aedtapp.close_project(q2d.project_name, save=False)
def test_17_set_variable(self):
self.aedtapp.variable_manager.set_variable("var_test", expression="123")
diff --git a/_unittest/test_32_RMxprt.py b/_unittest/test_32_RMxprt.py
index 97ffb03a56d..a6883dcd807 100644
--- a/_unittest/test_32_RMxprt.py
+++ b/_unittest/test_32_RMxprt.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import os
import pytest
diff --git a/_unittest/test_34_TwinBuilder.py b/_unittest/test_34_TwinBuilder.py
index b7714db35ef..27103b11947 100644
--- a/_unittest/test_34_TwinBuilder.py
+++ b/_unittest/test_34_TwinBuilder.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import os
from _unittest.conftest import NONGRAPHICAL
diff --git a/_unittest/test_35_MaxwellCircuit.py b/_unittest/test_35_MaxwellCircuit.py
index 1e4b627bb86..a13e7bd1360 100644
--- a/_unittest/test_35_MaxwellCircuit.py
+++ b/_unittest/test_35_MaxwellCircuit.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import os
from _unittest.conftest import local_path
diff --git a/_unittest/test_36_Q2D_PostProcessing.py b/_unittest/test_36_Q2D_PostProcessing.py
index 6a50e6feb4e..7c0e58d8076 100644
--- a/_unittest/test_36_Q2D_PostProcessing.py
+++ b/_unittest/test_36_Q2D_PostProcessing.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import os
from _unittest.conftest import config
diff --git a/_unittest/test_37_Genetic_Algorithm.py b/_unittest/test_37_Genetic_Algorithm.py
index a0b382abc80..323eed56c4a 100644
--- a/_unittest/test_37_Genetic_Algorithm.py
+++ b/_unittest/test_37_Genetic_Algorithm.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import random
import time
diff --git a/_unittest/test_41_3dlayout_modeler.py b/_unittest/test_41_3dlayout_modeler.py
index b72b7761d77..bbc425e938e 100644
--- a/_unittest/test_41_3dlayout_modeler.py
+++ b/_unittest/test_41_3dlayout_modeler.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import os
import tempfile
import time
@@ -299,6 +323,8 @@ def test_12_create_line(self):
line.center_line = {"Pt0": ["0mm", "0mm"]}
assert line.remove("Pt1")
assert line.add([1, 2], 1)
+ assert line.set_property_value("Pt0", "10mm ,10mm")
+ assert line.get_property_value("Pt0") == "10 ,10"
def test_13a_create_edge_port(self):
port_wave = self.aedtapp.create_edge_port("line1", 3, False, True, 6, 4, "2mm")
diff --git a/_unittest/test_43_CableModeling.py b/_unittest/test_43_CableModeling.py
index ea2430f4cb0..a200d51ce64 100644
--- a/_unittest/test_43_CableModeling.py
+++ b/_unittest/test_43_CableModeling.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import os
from _unittest.conftest import config
diff --git a/_unittest/test_44_TouchstoneParser.py b/_unittest/test_44_TouchstoneParser.py
index a7ed22c3ff8..45fb945c164 100644
--- a/_unittest/test_44_TouchstoneParser.py
+++ b/_unittest/test_44_TouchstoneParser.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import os
from _unittest.conftest import local_path
diff --git a/_unittest/test_98_Icepak.py b/_unittest/test_98_Icepak.py
index 89f220e914a..f9983fc56a2 100644
--- a/_unittest/test_98_Icepak.py
+++ b/_unittest/test_98_Icepak.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import os
from _unittest.conftest import config
@@ -70,20 +94,34 @@ def test_02_ImportPCB(self):
assert len(self.aedtapp.native_components) == 1
assert len(self.aedtapp.modeler.user_defined_component_names) == 1
- def test_02b_PCB_filters(self):
+ def test_02b_PCB_filters(self, local_scratch):
new_component = os.path.join(local_path, "example_models", "T40", "Package.aedt")
+ new_component_edb = os.path.join(local_path, "example_models", "T40", "Package.aedb")
+ new_component_dest = os.path.join(local_scratch.path, "Package.aedt")
+ local_scratch.copyfolder(new_component_edb, os.path.join(local_scratch.path, "Package.aedb"))
+ local_scratch.copyfile(new_component, new_component_dest)
cmp2 = self.aedtapp.create_ipk_3dcomponent_pcb(
"Board_w_cmp",
- [new_component, "FlipChip_TopBot", "HFSS PI Setup 1", en_ForceSimulation, en_PreserveResults],
+ [new_component_dest, "FlipChip_TopBot", "HFSS PI Setup 1", en_ForceSimulation, en_PreserveResults],
solution_freq,
resolution,
custom_x_resolution=400,
custom_y_resolution=500,
extent_type="Polygon",
)
- assert cmp2.set_parts("Package Parts", True, "Steel-mild-surface")
- assert cmp2.set_parts("Device Parts", True, "Steel-mild-surface")
+ assert cmp2.set_device_parts(True, "Steel-mild-surface")
+ assert cmp2.disable_device_parts()
+ assert cmp2.set_package_parts(solderballs="Boxes", connector="Solderbump", solderbumps_modeling="Lumped")
+ assert cmp2.set_package_parts(
+ solderballs="Lumped", connector="Bondwire", bondwire_material="Al-Extruded", bondwire_diameter="0.5mm"
+ )
+ assert not cmp2.set_package_parts(solderballs="Error1") # invalid input
+ assert not cmp2.set_package_parts(connector="Error2") # invalid input
+ assert not cmp2.set_package_parts(solderbumps_modeling="Error3") # invalid input
+ assert not cmp2.set_package_parts(bondwire_material="Error4") # material does not exist
assert not bool(cmp2.overridden_components)
+ assert not cmp2.override_component("FCHIP", True) # invalid part import selection
+ assert cmp2.set_device_parts()
assert cmp2.override_component("FCHIP", True)
assert "Board_w_cmp_FCHIP_device" not in self.aedtapp.modeler.object_names
assert cmp2.override_component("FCHIP", False)
@@ -93,15 +131,27 @@ def test_02b_PCB_filters(self):
assert cmp2.set_board_settings("Polygon")
assert cmp2.set_board_settings("Bounding Box")
assert cmp2.set_board_settings("Polygon", "outline:poly_0")
+ cmp2.disable_device_parts()
+ cmp2.footprint_filter = "1mm2"
+ assert cmp2.footprint_filter is None
+ cmp2.power_filter = "1W"
+ assert cmp2.power_filter is None
+ cmp2.type_filters = "Resistors"
+ assert cmp2.type_filters is None
+ cmp2.height_filter = "1mm"
+ assert cmp2.height_filter is None
+ cmp2.objects_2d_filter = True
+ assert cmp2.objects_2d_filter is None
+
component_name = "RadioBoard2"
cmp = self.aedtapp.create_ipk_3dcomponent_pcb(
component_name, link_data, solution_freq, resolution, custom_x_resolution=400, custom_y_resolution=500
)
+ assert not cmp.filters
+ assert cmp.set_device_parts()
f = cmp.filters
assert len(f.keys()) == 1
assert all(not v for v in f["Type"].values())
- assert not cmp.set_parts("Device Pt")
- assert cmp.set_parts("Device Parts", True, "Steel-mild-surface")
assert cmp.height_filter is None
assert cmp.footprint_filter is None
assert cmp.power_filter is None
@@ -297,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
@@ -773,13 +826,12 @@ def test_50_advanced3dcomp_export(self):
"test_dataset",
[1, 2, 3, 4],
[1, 2, 3, 4],
- zlist=None,
- vlist=None,
+ z=None,
+ v=None,
is_project_dataset=False,
- xunit="cel",
- yunit="W",
- zunit="",
- vunit="",
+ x_unit="cel",
+ y_unit="W",
+ v_unit="",
)
file_path = self.local_scratch.path
file_name = "Advanced3DComp.a3dcomp"
@@ -804,13 +856,12 @@ def test_50_advanced3dcomp_export(self):
"test_ignore",
[1, 2, 3, 4],
[1, 2, 3, 4],
- zlist=None,
- vlist=None,
+ z=None,
+ v=None,
is_project_dataset=False,
- xunit="cel",
- yunit="W",
- zunit="",
- vunit="",
+ x_unit="cel",
+ y_unit="W",
+ v_unit="",
)
file_name = "Advanced3DComp1.a3dcomp"
mon_list = list(self.aedtapp.monitor.all_monitors.keys())
@@ -859,13 +910,12 @@ def test_51_advanced3dcomp_import(self):
"test_dataset",
[1, 2, 3, 4],
[1, 2, 3, 4],
- zlist=None,
- vlist=None,
+ z=None,
+ v=None,
is_project_dataset=False,
- xunit="cel",
- yunit="W",
- zunit="",
- vunit="",
+ x_unit="cel",
+ y_unit="W",
+ v_unit="",
)
file_path = self.local_scratch.path
file_name = "Advanced3DComp_T51.a3dcomp"
@@ -884,13 +934,12 @@ def test_51_advanced3dcomp_import(self):
"test_ignore",
[1, 2, 3, 4],
[1, 2, 3, 4],
- zlist=None,
- vlist=None,
+ z=None,
+ v=None,
is_project_dataset=False,
- xunit="cel",
- yunit="W",
- zunit="",
- vunit="",
+ x_unit="cel",
+ y_unit="W",
+ v_unit="",
)
mon_list = list(self.aedtapp.monitor.all_monitors.keys())
self.aedtapp.monitor.assign_point_monitor([0, 0, 0])
@@ -1429,7 +1478,7 @@ def test_68_mesh_priority_3d_comp(self, add_app):
assert app.mesh.add_priority(entity_type=2, component="all_3d_objects1", priority=2)
- app.close_project(name="3d_comp_mesh_prio_test", save_project=False)
+ app.close_project(name="3d_comp_mesh_prio_test", save=False)
def test_69_recirculation_boundary(self):
box = self.aedtapp.modeler.create_box([5, 5, 5], [1, 2, 3], "BlockBoxEmpty", "copper")
@@ -1584,7 +1633,7 @@ def test_73_conducting_plate(self):
def test_74_boundary_conditions_dictionaries(self):
box1 = self.aedtapp.modeler.create_box([5, 5, 5], [1, 2, 3])
ds_temp = self.aedtapp.create_dataset(
- "ds_temp3", [1, 2, 3], [3, 2, 1], is_project_dataset=False, xunit="cel", yunit="W"
+ "ds_temp3", [1, 2, 3], [3, 2, 1], is_project_dataset=False, x_unit="cel", y_unit="W"
)
bc1 = self.aedtapp.create_temp_dep_assignment(ds_temp.name)
assert bc1
@@ -1594,7 +1643,7 @@ def test_74_boundary_conditions_dictionaries(self):
self.aedtapp.solution_type = "Transient"
ds_time = self.aedtapp.create_dataset(
- "ds_time3", [1, 2, 3], [3, 2, 1], is_project_dataset=False, xunit="s", yunit="W"
+ "ds_time3", [1, 2, 3], [3, 2, 1], is_project_dataset=False, x_unit="s", y_unit="W"
)
bc2 = self.aedtapp.create_dataset_transient_assignment(ds_time.name)
rect = self.aedtapp.modeler.create_rectangle(self.aedtapp.PLANE.XY, [0, 0, 0], [20, 10])
@@ -1641,7 +1690,7 @@ def test_74_boundary_conditions_dictionaries(self):
)
ds1_temp = self.aedtapp.create_dataset(
- "ds_temp3", [1, 2, 3], [3, 2, 1], is_project_dataset=True, xunit="cel", yunit="W"
+ "ds_temp3", [1, 2, 3], [3, 2, 1], is_project_dataset=True, x_unit="cel", y_unit="W"
)
assert not self.aedtapp.create_temp_dep_assignment(ds1_temp.name)
assert not self.aedtapp.create_temp_dep_assignment("nods")
@@ -1671,3 +1720,49 @@ def test_76_design_settings(self):
assert d["GravityDir"] == "Positive"
d["GravityVec"] = "Global::Y"
assert d["GravityVec"] == "Global::Y"
+
+ def test_78_restart_solution(self):
+ self.aedtapp.insert_design("test_78-1")
+ self.aedtapp.insert_design("test_78-2")
+ self.aedtapp.set_active_design("test_78-1")
+ self.aedtapp["a"] = "1mm"
+ self.aedtapp.modeler.create_box([0, 0, 0], ["a", "1", "2"])
+ s1 = self.aedtapp.create_setup()
+ self.aedtapp.set_active_design("test_78-2")
+ self.aedtapp["b"] = "1mm"
+ self.aedtapp.modeler.create_box([0, 0, 0], ["b", "1", "2"])
+ s2 = self.aedtapp.create_setup()
+ assert s2.start_continue_from_previous_setup(
+ "test_78-1", "{} : SteadyState".format(s1.name), parameters={"a": "1mm"}
+ )
+ s2.delete()
+ s2 = self.aedtapp.create_setup()
+ assert s2.start_continue_from_previous_setup("test_78-1", "{} : SteadyState".format(s1.name), parameters=None)
+ s2.delete()
+ s2 = self.aedtapp.create_setup()
+ assert not s2.start_continue_from_previous_setup(
+ "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",
+ )
diff --git a/_unittest/test_launch_desktop.py b/_unittest/test_launch_desktop.py
index 37e928cbdf6..6f1e464321c 100644
--- a/_unittest/test_launch_desktop.py
+++ b/_unittest/test_launch_desktop.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
from _unittest.conftest import config
import pytest
diff --git a/_unittest/test_utils.py b/_unittest/test_utils.py
index a87c0010036..397d493630d 100644
--- a/_unittest/test_utils.py
+++ b/_unittest/test_utils.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
"""Test utility functions of PyAEDT.
"""
@@ -7,8 +31,8 @@
import pytest
-from pyaedt import settings
from pyaedt.generic.general_methods import pyaedt_function_handler
+from pyaedt.generic.settings import settings
SETTINGS_RELEASE_ON_EXCEPTION = settings.release_on_exception
SETTINGS_ENABLE_ERROR_HANDLER = settings.enable_error_handler
diff --git a/_unittest/test_warnings.py b/_unittest/test_warnings.py
index 7a2c7b1bec4..a1ba7badbb7 100644
--- a/_unittest/test_warnings.py
+++ b/_unittest/test_warnings.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import sys
from unittest.mock import patch
import warnings
diff --git a/_unittest_solvers/conftest.py b/_unittest_solvers/conftest.py
index 6d581605884..29a6b3b864f 100644
--- a/_unittest_solvers/conftest.py
+++ b/_unittest_solvers/conftest.py
@@ -164,10 +164,10 @@ def _method(
if not application:
application = Hfss
return application(
- projectname=test_project,
- designname=design_name,
+ project=test_project,
+ design=design_name,
solution_type=solution_type,
- specified_version=desktop_version,
+ version=desktop_version,
)
return _method
diff --git a/_unittest_solvers/example_models/T01/compliance/ANSYS-HSD_V1_0_test.aedtz b/_unittest_solvers/example_models/T01/compliance/ANSYS-HSD_V1_0_test.aedtz
index be4ebe5c0cc..dc1da4afdb6 100644
Binary files a/_unittest_solvers/example_models/T01/compliance/ANSYS-HSD_V1_0_test.aedtz and b/_unittest_solvers/example_models/T01/compliance/ANSYS-HSD_V1_0_test.aedtz differ
diff --git a/_unittest_solvers/example_models/T01/compliance/general_compliance_template.json b/_unittest_solvers/example_models/T01/compliance/general_compliance_template.json
index 1f51d87e736..08af8bae72d 100644
--- a/_unittest_solvers/example_models/T01/compliance/general_compliance_template.json
+++ b/_unittest_solvers/example_models/T01/compliance/general_compliance_template.json
@@ -46,7 +46,7 @@
"type": "statistical eye",
"config": "StatisticalEyeDiagram_Custom.json",
"quantity_type": 3,
- "traces": ["b_input_67"],
+ "traces": ["b_input_67", "b_input_119"],
"pass_fail": true
},
{"name": "eye3",
@@ -54,7 +54,7 @@
"type": "contour eye diagram",
"config": "ContourEyeDiagram_Custom.json",
"quantity_type": 3,
- "traces": ["b_input_67"],
+ "traces": ["b_input_67", "b_input_119"],
"pass_fail": true
},
{"name": "eye2",
diff --git a/_unittest_solvers/example_models/T45/ANSYS-HSD_V1.aedb/edb.def b/_unittest_solvers/example_models/T45/ANSYS-HSD_V1.aedb/edb.def
new file mode 100644
index 00000000000..51fcd27e22a
Binary files /dev/null and b/_unittest_solvers/example_models/T45/ANSYS-HSD_V1.aedb/edb.def differ
diff --git a/_unittest_solvers/example_models/T45/ANSYS-HSD_V1.aedt b/_unittest_solvers/example_models/T45/ANSYS-HSD_V1.aedt
new file mode 100644
index 00000000000..f6b1505d130
--- /dev/null
+++ b/_unittest_solvers/example_models/T45/ANSYS-HSD_V1.aedt
@@ -0,0 +1,5431 @@
+$begin 'AnsoftProject'
+ Created='Fri Jun 21 09:25:15 2024'
+ Product='ElectronicsDesktop'
+ FileOwnedByWorkbench=false
+ $begin 'Desktop'
+ Version(2024, 1)
+ InfrastructureVersion(1, 0)
+ $begin 'FactoryHeader'
+ $begin 'geometry3deditor'
+ KernelVersion(2, 0)
+ ProjectContainsGeometry3D='0'
+ $end 'geometry3deditor'
+ $end 'FactoryHeader'
+ $end 'Desktop'
+ UsesAdvancedFeatures=false
+ NextUniqueID=0
+ MoveBackwards=false
+ $begin 'HFSSEnvironment'
+ Version(1, 0)
+ $end 'HFSSEnvironment'
+ $begin 'PlanarEMEnvironment'
+ Version(1, 0)
+ $end 'PlanarEMEnvironment'
+ $begin 'Q3DEnvironment'
+ Version(1, 0)
+ $end 'Q3DEnvironment'
+ $begin '2DExtractorEnvironment'
+ Version(1, 0)
+ $end '2DExtractorEnvironment'
+ $begin 'NexximEnvironment'
+ Version(1, 0)
+ $end 'NexximEnvironment'
+ $begin 'NexximNetlistEnvironment'
+ Version(1, 0)
+ $end 'NexximNetlistEnvironment'
+ $begin 'EmitEnvironment'
+ Version(1, 0)
+ $end 'EmitEnvironment'
+ $begin 'Maxwell3DEnvironment'
+ Version(1, 0)
+ $end 'Maxwell3DEnvironment'
+ $begin 'Maxwell2DEnvironment'
+ Version(1, 0)
+ $end 'Maxwell2DEnvironment'
+ $begin 'RMxprtEnvironment'
+ Version(1, 0)
+ $end 'RMxprtEnvironment'
+ $begin 'MaxCirEnvironment'
+ Version(1, 0)
+ $end 'MaxCirEnvironment'
+ $begin 'SimplorerEnvironment'
+ Version(1, 0)
+ $end 'SimplorerEnvironment'
+ $begin 'IcepakEnvironment'
+ Version(1, 0)
+ $end 'IcepakEnvironment'
+ $begin 'MechanicalEnvironment'
+ Version(1, 0)
+ $end 'MechanicalEnvironment'
+ $begin 'SchematicEnvironment'
+ Version(1, 0)
+ $end 'SchematicEnvironment'
+ $begin 'geometry3deditor'
+ Version(1, 0)
+ $end 'geometry3deditor'
+ ReadVersion=11
+ $begin 'EDB'
+ Path=''
+ LastUpdateTimeStamp=1718954715
+ $end 'EDB'
+ $begin 'DesignMgrEnvironment'
+ CompInstCounter=1
+ GPortCounter=0
+ NetCounter=0
+ Alias('Ieee;Simplorer Elements\\Ieee', 'Std;Simplorer Elements\\Std', 'Basic_VHDLAMS;Simplorer Elements\\Basic Elements VHDLAMS\\Basic Elements VHDLAMS', 'Digital_Elements;Simplorer Elements\\Digital Elements\\Digital Elements', 'Transformations;Simplorer Elements\\Tools\\Transformations\\Transformations', 'HEV_VHDLAMS;Simplorer Elements\\HEV VHDLAMS\\HEV VHDLAMS', 'automotive_vda;Simplorer Elements\\VDALibs VHDLAMS\\automotive_vda', 'example_boardnet;Simplorer Elements\\VDALibs VHDLAMS\\example_boardnet', 'example_ecar;Simplorer Elements\\VDALibs VHDLAMS\\example_ecar', 'fundamentals_vda;Simplorer Elements\\VDALibs VHDLAMS\\fundamentals_vda', 'hybrid_emc_vda;Simplorer Elements\\VDALibs VHDLAMS\\hybrid_emc_vda', 'megma;Simplorer Elements\\VDALibs VHDLAMS\\megma', 'modelica_rotational;Simplorer Elements\\VDALibs VHDLAMS\\modelica_rotational', 'modelica_thermal;Simplorer Elements\\VDALibs VHDLAMS\\modelica_thermal', 'modelica_translational;Simplorer Elements\\VDALibs VHDLAMS\\modelica_translational', 'spice2vhd;Simplorer Elements\\VDALibs VHDLAMS\\spice2vhd', 'spice2vhd_devices;Simplorer Elements\\VDALibs VHDLAMS\\spice2vhd_devices', 'aircraft_electrical_vhdlams;Simplorer Elements\\Aircraft Electrical VHDLAMS\\Aircraft Electrical VHDLAMS', 'power_system_vhdlams;Simplorer Elements\\Power System VHDLAMS\\Power System VHDLAMS')
+ $end 'DesignMgrEnvironment'
+ $begin 'ProjectDatasets'
+ NextUniqueID=0
+ MoveBackwards=false
+ DatasetType='ProjectDatasetType'
+ $begin 'DatasetDefinitions'
+ $end 'DatasetDefinitions'
+ $end 'ProjectDatasets'
+ VariableOrders[0:]
+ $begin 'Definitions'
+ $begin 'Materials'
+ $begin 'copper'
+ CoordinateSystemType='Cartesian'
+ BulkOrSurfaceType=1
+ $begin 'PhysicsTypes'
+ set('Electromagnetic')
+ $end 'PhysicsTypes'
+ conductivity='58000000'
+ ModTime=1677073156
+ Library=''
+ LibLocation='Project'
+ ModSinceLib=false
+ $end 'copper'
+ $begin 'Megtron4'
+ CoordinateSystemType='Cartesian'
+ BulkOrSurfaceType=1
+ $begin 'PhysicsTypes'
+ set('Electromagnetic')
+ $end 'PhysicsTypes'
+ permittivity='3.77'
+ dielectric_loss_tangent='0.005'
+ ModTime=1677073156
+ Library=''
+ LibLocation='Project'
+ ModSinceLib=false
+ $end 'Megtron4'
+ $begin 'Megtron4_2'
+ CoordinateSystemType='Cartesian'
+ BulkOrSurfaceType=1
+ $begin 'PhysicsTypes'
+ set('Electromagnetic')
+ $end 'PhysicsTypes'
+ permittivity='3.47'
+ dielectric_loss_tangent='0.006'
+ ModTime=1677073156
+ Library=''
+ LibLocation='Project'
+ ModSinceLib=false
+ $end 'Megtron4_2'
+ $begin 'Megtron4_3'
+ CoordinateSystemType='Cartesian'
+ BulkOrSurfaceType=1
+ $begin 'PhysicsTypes'
+ set('Electromagnetic')
+ $end 'PhysicsTypes'
+ permittivity='4.2'
+ dielectric_loss_tangent='0.005'
+ ModTime=1677073156
+ Library=''
+ LibLocation='Project'
+ ModSinceLib=false
+ $end 'Megtron4_3'
+ $begin 'Solder Resist'
+ CoordinateSystemType='Cartesian'
+ BulkOrSurfaceType=1
+ $begin 'PhysicsTypes'
+ set('Electromagnetic')
+ $end 'PhysicsTypes'
+ permittivity='3'
+ dielectric_loss_tangent='0'
+ ModTime=1677073156
+ Library=''
+ LibLocation='Project'
+ ModSinceLib=false
+ $end 'Solder Resist'
+ $begin 'FR4_epoxy'
+ CoordinateSystemType='Cartesian'
+ BulkOrSurfaceType=1
+ $begin 'PhysicsTypes'
+ set('Electromagnetic', 'Thermal', 'Structural')
+ $end 'PhysicsTypes'
+ $begin 'AttachedData'
+ $begin 'MatAppearanceData'
+ property_data='appearance_data'
+ Red=27
+ Green=110
+ Blue=76
+ $end 'MatAppearanceData'
+ $end 'AttachedData'
+ permittivity='4.4'
+ dielectric_loss_tangent='0.02'
+ thermal_conductivity='0.294'
+ mass_density='1900'
+ specific_heat='1150'
+ youngs_modulus='11000000000'
+ poissons_ratio='0.28'
+ thermal_expansion_coefficient='1.5e-05'
+ ModTime=1499970477
+ Library='Materials'
+ LibLocation='SysLibrary'
+ ModSinceLib=false
+ $end 'FR4_epoxy'
+ $end 'Materials'
+ $begin 'SurfaceMaterials'
+ $end 'SurfaceMaterials'
+ $begin 'Scripts'
+ $end 'Scripts'
+ $begin 'Symbols'
+ $begin 'CAPC0603X33X15LL03T05'
+ ModTime=1718954704
+ CE=0
+ Library=''
+ ModSinceLib=false
+ LibLocation='Project'
+ HighestLevel=1
+ Normalize=false
+ InitialLevels(0, 1)
+ $begin 'PinDef'
+ Pin('1', -0.00508, 0, 0, 'N', 0, 0.00254, false, 0, true, '', true, false, '1', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(-0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '1', false, false, ExtentRect(0, 0, 0, 0, -0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'PinDef'
+ Pin('2', 0.00508, 0, 3.14159265358979, 'N', 0, 0.00254, false, 0, true, '', true, false, '2', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '2', false, false, ExtentRect(0, 0, 0, 0, 0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'Graphics'
+ Rect(0, 0, 0, 0, 0, 0, 0.00508, 0.00508, 0, 0, 0)
+ Rect(0, 1, 0, 0, -0.00211666666666667, 0, 0.000423333333333333, 0.000423333333333334, 0, 0, 0)
+ $end 'Graphics'
+ $end 'CAPC0603X33X15LL03T05'
+ $begin 'CAPC1005X05N'
+ ModTime=1718954704
+ CE=0
+ Library=''
+ ModSinceLib=false
+ LibLocation='Project'
+ HighestLevel=1
+ Normalize=false
+ InitialLevels(0, 1)
+ $begin 'PinDef'
+ Pin('2', -0.00508, 0, 0, 'N', 0, 0.00254, false, 0, true, '', true, false, '2', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(-0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '2', false, false, ExtentRect(0, 0, 0, 0, -0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'PinDef'
+ Pin('1', 0.00508, 0, 3.14159265358979, 'N', 0, 0.00254, false, 0, true, '', true, false, '1', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '1', false, false, ExtentRect(0, 0, 0, 0, 0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'Graphics'
+ Rect(0, 0, 0, 0, 0, 0, 0.00508, 0.00508, 0, 0, 0)
+ Rect(0, 1, 0, 0, -0.00211666666666667, 0, 0.000423333333333333, 0.000423333333333334, 0, 0, 0)
+ $end 'Graphics'
+ $end 'CAPC1005X05N'
+ $begin 'CAPC1005X33X10LL5'
+ ModTime=1718954704
+ CE=0
+ Library=''
+ ModSinceLib=false
+ LibLocation='Project'
+ HighestLevel=1
+ Normalize=false
+ InitialLevels(0, 1)
+ $begin 'PinDef'
+ Pin('1', -0.00508, 0, 0, 'N', 0, 0.00254, false, 0, true, '', true, false, '1', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(-0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '1', false, false, ExtentRect(0, 0, 0, 0, -0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'PinDef'
+ Pin('2', 0.00508, 0, 3.14159265358979, 'N', 0, 0.00254, false, 0, true, '', true, false, '2', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '2', false, false, ExtentRect(0, 0, 0, 0, 0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'Graphics'
+ Rect(0, 0, 0, 0, 0, 0, 0.00508, 0.00508, 0, 0, 0)
+ Rect(0, 1, 0, 0, -0.00211666666666667, 0, 0.000423333333333333, 0.000423333333333334, 0, 0, 0)
+ $end 'Graphics'
+ $end 'CAPC1005X33X10LL5'
+ $begin 'CAPC1005X55X10LL05'
+ ModTime=1718954704
+ CE=0
+ Library=''
+ ModSinceLib=false
+ LibLocation='Project'
+ HighestLevel=1
+ Normalize=false
+ InitialLevels(0, 1)
+ $begin 'PinDef'
+ Pin('2', -0.00508, 0, 0, 'N', 0, 0.00254, false, 0, true, '', true, false, '2', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(-0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '2', false, false, ExtentRect(0, 0, 0, 0, -0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'PinDef'
+ Pin('1', 0.00508, 0, 3.14159265358979, 'N', 0, 0.00254, false, 0, true, '', true, false, '1', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '1', false, false, ExtentRect(0, 0, 0, 0, 0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'Graphics'
+ Rect(0, 0, 0, 0, 0, 0, 0.00508, 0.00508, 0, 0, 0)
+ Rect(0, 1, 0, 0, -0.00211666666666667, 0, 0.000423333333333333, 0.000423333333333334, 0, 0, 0)
+ $end 'Graphics'
+ $end 'CAPC1005X55X10LL05'
+ $begin 'CAPC1005X55X23ML05T8'
+ ModTime=1718954704
+ CE=0
+ Library=''
+ ModSinceLib=false
+ LibLocation='Project'
+ HighestLevel=1
+ Normalize=false
+ InitialLevels(0, 1)
+ $begin 'PinDef'
+ Pin('2', -0.00508, 0, 0, 'N', 0, 0.00254, false, 0, true, '', true, false, '2', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(-0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '2', false, false, ExtentRect(0, 0, 0, 0, -0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'PinDef'
+ Pin('1', 0.00508, 0, 3.14159265358979, 'N', 0, 0.00254, false, 0, true, '', true, false, '1', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '1', false, false, ExtentRect(0, 0, 0, 0, 0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'Graphics'
+ Rect(0, 0, 0, 0, 0, 0, 0.00508, 0.00508, 0, 0, 0)
+ Rect(0, 1, 0, 0, -0.00211666666666667, 0, 0.000423333333333333, 0.000423333333333334, 0, 0, 0)
+ $end 'Graphics'
+ $end 'CAPC1005X55X23ML05T8'
+ $begin 'CAPC1005X55X25LL05T10'
+ ModTime=1718954704
+ CE=0
+ Library=''
+ ModSinceLib=false
+ LibLocation='Project'
+ HighestLevel=1
+ Normalize=false
+ InitialLevels(0, 1)
+ $begin 'PinDef'
+ Pin('1', -0.00508, 0, 0, 'N', 0, 0.00254, false, 0, true, '', true, false, '1', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(-0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '1', false, false, ExtentRect(0, 0, 0, 0, -0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'PinDef'
+ Pin('2', 0.00508, 0, 3.14159265358979, 'N', 0, 0.00254, false, 0, true, '', true, false, '2', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '2', false, false, ExtentRect(0, 0, 0, 0, 0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'Graphics'
+ Rect(0, 0, 0, 0, 0, 0, 0.00508, 0.00508, 0, 0, 0)
+ Rect(0, 1, 0, 0, -0.00211666666666667, 0, 0.000423333333333333, 0.000423333333333334, 0, 0, 0)
+ $end 'Graphics'
+ $end 'CAPC1005X55X25LL05T10'
+ $begin 'CAPC1005X55X25ML05T10'
+ ModTime=1718954704
+ CE=0
+ Library=''
+ ModSinceLib=false
+ LibLocation='Project'
+ HighestLevel=1
+ Normalize=false
+ InitialLevels(0, 1)
+ $begin 'PinDef'
+ Pin('1', -0.00508, 0, 0, 'N', 0, 0.00254, false, 0, true, '', true, false, '1', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(-0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '1', false, false, ExtentRect(0, 0, 0, 0, -0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'PinDef'
+ Pin('2', 0.00508, 0, 3.14159265358979, 'N', 0, 0.00254, false, 0, true, '', true, false, '2', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '2', false, false, ExtentRect(0, 0, 0, 0, 0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'Graphics'
+ Rect(0, 0, 0, 0, 0, 0, 0.00508, 0.00508, 0, 0, 0)
+ Rect(0, 1, 0, 0, -0.00211666666666667, 0, 0.000423333333333333, 0.000423333333333334, 0, 0, 0)
+ $end 'Graphics'
+ $end 'CAPC1005X55X25ML05T10'
+ $begin 'CAPC1005X55X25NL05T10'
+ ModTime=1718954704
+ CE=0
+ Library=''
+ ModSinceLib=false
+ LibLocation='Project'
+ HighestLevel=1
+ Normalize=false
+ InitialLevels(0, 1)
+ $begin 'PinDef'
+ Pin('2', -0.00508, 0, 0, 'N', 0, 0.00254, false, 0, true, '', true, false, '2', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(-0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '2', false, false, ExtentRect(0, 0, 0, 0, -0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'PinDef'
+ Pin('1', 0.00508, 0, 3.14159265358979, 'N', 0, 0.00254, false, 0, true, '', true, false, '1', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '1', false, false, ExtentRect(0, 0, 0, 0, 0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'Graphics'
+ Rect(0, 0, 0, 0, 0, 0, 0.00508, 0.00508, 0, 0, 0)
+ Rect(0, 1, 0, 0, -0.00211666666666667, 0, 0.000423333333333333, 0.000423333333333334, 0, 0, 0)
+ $end 'Graphics'
+ $end 'CAPC1005X55X25NL05T10'
+ $begin 'CAPC1608X08N'
+ ModTime=1718954704
+ CE=0
+ Library=''
+ ModSinceLib=false
+ LibLocation='Project'
+ HighestLevel=1
+ Normalize=false
+ InitialLevels(0, 1)
+ $begin 'PinDef'
+ Pin('2', -0.00508, 0, 0, 'N', 0, 0.00254, false, 0, true, '', true, false, '2', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(-0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '2', false, false, ExtentRect(0, 0, 0, 0, -0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'PinDef'
+ Pin('1', 0.00508, 0, 3.14159265358979, 'N', 0, 0.00254, false, 0, true, '', true, false, '1', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '1', false, false, ExtentRect(0, 0, 0, 0, 0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'Graphics'
+ Rect(0, 0, 0, 0, 0, 0, 0.00508, 0.00508, 0, 0, 0)
+ Rect(0, 1, 0, 0, -0.00211666666666667, 0, 0.000423333333333333, 0.000423333333333334, 0, 0, 0)
+ $end 'Graphics'
+ $end 'CAPC1608X08N'
+ $begin 'CAPC1608X90X35ML10T15'
+ ModTime=1718954704
+ CE=0
+ Library=''
+ ModSinceLib=false
+ LibLocation='Project'
+ HighestLevel=1
+ Normalize=false
+ InitialLevels(0, 1)
+ $begin 'PinDef'
+ Pin('2', -0.00508, 0, 0, 'N', 0, 0.00254, false, 0, true, '', true, false, '2', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(-0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '2', false, false, ExtentRect(0, 0, 0, 0, -0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'PinDef'
+ Pin('1', 0.00508, 0, 3.14159265358979, 'N', 0, 0.00254, false, 0, true, '', true, false, '1', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '1', false, false, ExtentRect(0, 0, 0, 0, 0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'Graphics'
+ Rect(0, 0, 0, 0, 0, 0, 0.00508, 0.00508, 0, 0, 0)
+ Rect(0, 1, 0, 0, -0.00211666666666667, 0, 0.000423333333333333, 0.000423333333333334, 0, 0, 0)
+ $end 'Graphics'
+ $end 'CAPC1608X90X35ML10T15'
+ $begin 'CAPC2012X12N'
+ ModTime=1718954704
+ CE=0
+ Library=''
+ ModSinceLib=false
+ LibLocation='Project'
+ HighestLevel=1
+ Normalize=false
+ InitialLevels(0, 1)
+ $begin 'PinDef'
+ Pin('1', -0.00508, 0, 0, 'N', 0, 0.00254, false, 0, true, '', true, false, '1', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(-0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '1', false, false, ExtentRect(0, 0, 0, 0, -0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'PinDef'
+ Pin('2', 0.00508, 0, 3.14159265358979, 'N', 0, 0.00254, false, 0, true, '', true, false, '2', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '2', false, false, ExtentRect(0, 0, 0, 0, 0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'Graphics'
+ Rect(0, 0, 0, 0, 0, 0, 0.00508, 0.00508, 0, 0, 0)
+ Rect(0, 1, 0, 0, -0.00211666666666667, 0, 0.000423333333333333, 0.000423333333333334, 0, 0, 0)
+ $end 'Graphics'
+ $end 'CAPC2012X12N'
+ $begin 'CAPC2013X100X20NL20'
+ ModTime=1718954704
+ CE=0
+ Library=''
+ ModSinceLib=false
+ LibLocation='Project'
+ HighestLevel=1
+ Normalize=false
+ InitialLevels(0, 1)
+ $begin 'PinDef'
+ Pin('1', -0.00508, 0, 0, 'N', 0, 0.00254, false, 0, true, '', true, false, '1', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(-0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '1', false, false, ExtentRect(0, 0, 0, 0, -0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'PinDef'
+ Pin('2', 0.00508, 0, 3.14159265358979, 'N', 0, 0.00254, false, 0, true, '', true, false, '2', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '2', false, false, ExtentRect(0, 0, 0, 0, 0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'Graphics'
+ Rect(0, 0, 0, 0, 0, 0, 0.00508, 0.00508, 0, 0, 0)
+ Rect(0, 1, 0, 0, -0.00211666666666667, 0, 0.000423333333333333, 0.000423333333333334, 0, 0, 0)
+ $end 'Graphics'
+ $end 'CAPC2013X100X20NL20'
+ $begin 'CAPC3216X180X20ML20'
+ ModTime=1718954704
+ CE=0
+ Library=''
+ ModSinceLib=false
+ LibLocation='Project'
+ HighestLevel=1
+ Normalize=false
+ InitialLevels(0, 1)
+ $begin 'PinDef'
+ Pin('2', -0.00508, 0, 0, 'N', 0, 0.00254, false, 0, true, '', true, false, '2', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(-0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '2', false, false, ExtentRect(0, 0, 0, 0, -0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'PinDef'
+ Pin('1', 0.00508, 0, 3.14159265358979, 'N', 0, 0.00254, false, 0, true, '', true, false, '1', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '1', false, false, ExtentRect(0, 0, 0, 0, 0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'Graphics'
+ Rect(0, 0, 0, 0, 0, 0, 0.00508, 0.00508, 0, 0, 0)
+ Rect(0, 1, 0, 0, -0.00211666666666667, 0, 0.000423333333333333, 0.000423333333333334, 0, 0, 0)
+ $end 'Graphics'
+ $end 'CAPC3216X180X20ML20'
+ $begin 'CAPC3216X180X55ML20T25'
+ ModTime=1718954704
+ CE=0
+ Library=''
+ ModSinceLib=false
+ LibLocation='Project'
+ HighestLevel=1
+ Normalize=false
+ InitialLevels(0, 1)
+ $begin 'PinDef'
+ Pin('2', -0.00508, 0, 0, 'N', 0, 0.00254, false, 0, true, '', true, false, '2', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(-0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '2', false, false, ExtentRect(0, 0, 0, 0, -0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'PinDef'
+ Pin('1', 0.00508, 0, 3.14159265358979, 'N', 0, 0.00254, false, 0, true, '', true, false, '1', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '1', false, false, ExtentRect(0, 0, 0, 0, 0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'Graphics'
+ Rect(0, 0, 0, 0, 0, 0, 0.00508, 0.00508, 0, 0, 0)
+ Rect(0, 1, 0, 0, -0.00211666666666667, 0, 0.000423333333333333, 0.000423333333333334, 0, 0, 0)
+ $end 'Graphics'
+ $end 'CAPC3216X180X55ML20T25'
+ $begin 'CAPC3216X190X55ML30T25'
+ ModTime=1718954704
+ CE=0
+ Library=''
+ ModSinceLib=false
+ LibLocation='Project'
+ HighestLevel=1
+ Normalize=false
+ InitialLevels(0, 1)
+ $begin 'PinDef'
+ Pin('1', -0.00508, 0, 0, 'N', 0, 0.00254, false, 0, true, '', true, false, '1', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(-0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '1', false, false, ExtentRect(0, 0, 0, 0, -0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'PinDef'
+ Pin('2', 0.00508, 0, 3.14159265358979, 'N', 0, 0.00254, false, 0, true, '', true, false, '2', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '2', false, false, ExtentRect(0, 0, 0, 0, 0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'Graphics'
+ Rect(0, 0, 0, 0, 0, 0, 0.00508, 0.00508, 0, 0, 0)
+ Rect(0, 1, 0, 0, -0.00211666666666667, 0, 0.000423333333333333, 0.000423333333333334, 0, 0, 0)
+ $end 'Graphics'
+ $end 'CAPC3216X190X55ML30T25'
+ $begin 'CAPMP7343X31N'
+ ModTime=1718954704
+ CE=0
+ Library=''
+ ModSinceLib=false
+ LibLocation='Project'
+ HighestLevel=1
+ Normalize=false
+ InitialLevels(0, 1)
+ $begin 'PinDef'
+ Pin('1', -0.00508, 0, 0, 'N', 0, 0.00254, false, 0, true, '', true, false, '1', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(-0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '1', false, false, ExtentRect(0, 0, 0, 0, -0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'PinDef'
+ Pin('2', 0.00508, 0, 3.14159265358979, 'N', 0, 0.00254, false, 0, true, '', true, false, '2', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '2', false, false, ExtentRect(0, 0, 0, 0, 0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'Graphics'
+ Rect(0, 0, 0, 0, 0, 0, 0.00508, 0.00508, 0, 0, 0)
+ Rect(0, 1, 0, 0, -0.00211666666666667, 0, 0.000423333333333333, 0.000423333333333334, 0, 0, 0)
+ $end 'Graphics'
+ $end 'CAPMP7343X31N'
+ $begin 'COIL-1008CS_V'
+ ModTime=1718954704
+ CE=0
+ Library=''
+ ModSinceLib=false
+ LibLocation='Project'
+ HighestLevel=1
+ Normalize=false
+ InitialLevels(0, 1)
+ $begin 'PinDef'
+ Pin('1', -0.00508, 0, 0, 'N', 0, 0.00254, false, 0, true, '', true, false, '1', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(-0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '1', false, false, ExtentRect(0, 0, 0, 0, -0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'PinDef'
+ Pin('2', 0.00508, 0, 3.14159265358979, 'N', 0, 0.00254, false, 0, true, '', true, false, '2', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '2', false, false, ExtentRect(0, 0, 0, 0, 0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'Graphics'
+ Rect(0, 0, 0, 0, 0, 0, 0.00508, 0.00508, 0, 0, 0)
+ Rect(0, 1, 0, 0, -0.00211666666666667, 0, 0.000423333333333333, 0.000423333333333334, 0, 0, 0)
+ $end 'Graphics'
+ $end 'COIL-1008CS_V'
+ $begin 'main'
+ ModTime=1718954704
+ CE=0
+ Library=''
+ ModSinceLib=false
+ LibLocation='Project'
+ HighestLevel=1
+ Normalize=true
+ InitialLevels(0, 1)
+ $begin 'Graphics'
+ Rect(0, 0, 0, 0, 0.00254, 0.00254, 0.00508, 0.00508, 0, 0, 0)
+ Rect(0, 1, 0, 0, 0.000423333333333333, 0.00254, 0.000423333333333333, 0.000423333333333334, 0, 0, 0)
+ $end 'Graphics'
+ $end 'main'
+ $begin 'MURA-BLM15-CHIP-2_V'
+ ModTime=1718954704
+ CE=0
+ Library=''
+ ModSinceLib=false
+ LibLocation='Project'
+ HighestLevel=1
+ Normalize=false
+ InitialLevels(0, 1)
+ $begin 'PinDef'
+ Pin('2', -0.00508, 0, 0, 'N', 0, 0.00254, false, 0, true, '', true, false, '2', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(-0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '2', false, false, ExtentRect(0, 0, 0, 0, -0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'PinDef'
+ Pin('1', 0.00508, 0, 3.14159265358979, 'N', 0, 0.00254, false, 0, true, '', true, false, '1', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '1', false, false, ExtentRect(0, 0, 0, 0, 0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'Graphics'
+ Rect(0, 0, 0, 0, 0, 0, 0.00508, 0.00508, 0, 0, 0)
+ Rect(0, 1, 0, 0, -0.00211666666666667, 0, 0.000423333333333333, 0.000423333333333334, 0, 0, 0)
+ $end 'Graphics'
+ $end 'MURA-BLM15-CHIP-2_V'
+ $begin 'MURA-BLM15AG221SN1x_V'
+ ModTime=1718954704
+ CE=0
+ Library=''
+ ModSinceLib=false
+ LibLocation='Project'
+ HighestLevel=1
+ Normalize=false
+ InitialLevels(0, 1)
+ $begin 'PinDef'
+ Pin('2', -0.00508, 0, 0, 'N', 0, 0.00254, false, 0, true, '', true, false, '2', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(-0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '2', false, false, ExtentRect(0, 0, 0, 0, -0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'PinDef'
+ Pin('1', 0.00508, 0, 3.14159265358979, 'N', 0, 0.00254, false, 0, true, '', true, false, '1', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '1', false, false, ExtentRect(0, 0, 0, 0, 0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'Graphics'
+ Rect(0, 0, 0, 0, 0, 0, 0.00508, 0.00508, 0, 0, 0)
+ Rect(0, 1, 0, 0, -0.00211666666666667, 0, 0.000423333333333333, 0.000423333333333334, 0, 0, 0)
+ $end 'Graphics'
+ $end 'MURA-BLM15AG221SN1x_V'
+ $begin 'RESC1005X35X25NL8T10'
+ ModTime=1718954704
+ CE=0
+ Library=''
+ ModSinceLib=false
+ LibLocation='Project'
+ HighestLevel=1
+ Normalize=false
+ InitialLevels(0, 1)
+ $begin 'PinDef'
+ Pin('1', -0.00508, 0, 0, 'N', 0, 0.00254, false, 0, true, '', true, false, '1', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(-0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '1', false, false, ExtentRect(0, 0, 0, 0, -0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'PinDef'
+ Pin('2', 0.00508, 0, 3.14159265358979, 'N', 0, 0.00254, false, 0, true, '', true, false, '2', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '2', false, false, ExtentRect(0, 0, 0, 0, 0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'Graphics'
+ Rect(0, 0, 0, 0, 0, 0, 0.00508, 0.00508, 0, 0, 0)
+ Rect(0, 1, 0, 0, -0.00211666666666667, 0, 0.000423333333333333, 0.000423333333333334, 0, 0, 0)
+ $end 'Graphics'
+ $end 'RESC1005X35X25NL8T10'
+ $begin 'RESC1005X40X25LL05T05'
+ ModTime=1718954704
+ CE=0
+ Library=''
+ ModSinceLib=false
+ LibLocation='Project'
+ HighestLevel=1
+ Normalize=false
+ InitialLevels(0, 1)
+ $begin 'PinDef'
+ Pin('2', -0.00508, 0, 0, 'N', 0, 0.00254, false, 0, true, '', true, false, '2', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(-0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '2', false, false, ExtentRect(0, 0, 0, 0, -0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'PinDef'
+ Pin('1', 0.00508, 0, 3.14159265358979, 'N', 0, 0.00254, false, 0, true, '', true, false, '1', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '1', false, false, ExtentRect(0, 0, 0, 0, 0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'Graphics'
+ Rect(0, 0, 0, 0, 0, 0, 0.00508, 0.00508, 0, 0, 0)
+ Rect(0, 1, 0, 0, -0.00211666666666667, 0, 0.000423333333333333, 0.000423333333333334, 0, 0, 0)
+ $end 'Graphics'
+ $end 'RESC1005X40X25LL05T05'
+ $begin 'RESC1005X40X25ML05T05'
+ ModTime=1718954704
+ CE=0
+ Library=''
+ ModSinceLib=false
+ LibLocation='Project'
+ HighestLevel=1
+ Normalize=false
+ InitialLevels(0, 1)
+ $begin 'PinDef'
+ Pin('1', -0.00508, 0, 0, 'N', 0, 0.00254, false, 0, true, '', true, false, '1', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(-0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '1', false, false, ExtentRect(0, 0, 0, 0, -0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'PinDef'
+ Pin('2', 0.00508, 0, 3.14159265358979, 'N', 0, 0.00254, false, 0, true, '', true, false, '2', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '2', false, false, ExtentRect(0, 0, 0, 0, 0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'Graphics'
+ Rect(0, 0, 0, 0, 0, 0, 0.00508, 0.00508, 0, 0, 0)
+ Rect(0, 1, 0, 0, -0.00211666666666667, 0, 0.000423333333333333, 0.000423333333333334, 0, 0, 0)
+ $end 'Graphics'
+ $end 'RESC1005X40X25ML05T05'
+ $begin 'RESC1005X40X25NL05T05'
+ ModTime=1718954704
+ CE=0
+ Library=''
+ ModSinceLib=false
+ LibLocation='Project'
+ HighestLevel=1
+ Normalize=false
+ InitialLevels(0, 1)
+ $begin 'PinDef'
+ Pin('2', -0.00508, 0, 0, 'N', 0, 0.00254, false, 0, true, '', true, false, '2', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(-0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '2', false, false, ExtentRect(0, 0, 0, 0, -0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'PinDef'
+ Pin('1', 0.00508, 0, 3.14159265358979, 'N', 0, 0.00254, false, 0, true, '', true, false, '1', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '1', false, false, ExtentRect(0, 0, 0, 0, 0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'Graphics'
+ Rect(0, 0, 0, 0, 0, 0, 0.00508, 0.00508, 0, 0, 0)
+ Rect(0, 1, 0, 0, -0.00211666666666667, 0, 0.000423333333333333, 0.000423333333333334, 0, 0, 0)
+ $end 'Graphics'
+ $end 'RESC1005X40X25NL05T05'
+ $begin 'RESC1005X40X25NL5T10'
+ ModTime=1718954704
+ CE=0
+ Library=''
+ ModSinceLib=false
+ LibLocation='Project'
+ HighestLevel=1
+ Normalize=false
+ InitialLevels(0, 1)
+ $begin 'PinDef'
+ Pin('2', -0.00508, 0, 0, 'N', 0, 0.00254, false, 0, true, '', true, false, '2', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(-0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '2', false, false, ExtentRect(0, 0, 0, 0, -0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'PinDef'
+ Pin('1', 0.00508, 0, 3.14159265358979, 'N', 0, 0.00254, false, 0, true, '', true, false, '1', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '1', false, false, ExtentRect(0, 0, 0, 0, 0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'Graphics'
+ Rect(0, 0, 0, 0, 0, 0, 0.00508, 0.00508, 0, 0, 0)
+ Rect(0, 1, 0, 0, -0.00211666666666667, 0, 0.000423333333333333, 0.000423333333333334, 0, 0, 0)
+ $end 'Graphics'
+ $end 'RESC1005X40X25NL5T10'
+ $begin 'RESC1608X05N'
+ ModTime=1718954704
+ CE=0
+ Library=''
+ ModSinceLib=false
+ LibLocation='Project'
+ HighestLevel=1
+ Normalize=false
+ InitialLevels(0, 1)
+ $begin 'PinDef'
+ Pin('2', -0.00508, 0, 0, 'N', 0, 0.00254, false, 0, true, '', true, false, '2', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(-0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '2', false, false, ExtentRect(0, 0, 0, 0, -0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'PinDef'
+ Pin('1', 0.00508, 0, 3.14159265358979, 'N', 0, 0.00254, false, 0, true, '', true, false, '1', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '1', false, false, ExtentRect(0, 0, 0, 0, 0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'Graphics'
+ Rect(0, 0, 0, 0, 0, 0, 0.00508, 0.00508, 0, 0, 0)
+ Rect(0, 1, 0, 0, -0.00211666666666667, 0, 0.000423333333333333, 0.000423333333333334, 0, 0, 0)
+ $end 'Graphics'
+ $end 'RESC1608X05N'
+ $begin 'SMD-0603'
+ ModTime=1718954704
+ CE=0
+ Library=''
+ ModSinceLib=false
+ LibLocation='Project'
+ HighestLevel=1
+ Normalize=false
+ InitialLevels(0, 1)
+ $begin 'PinDef'
+ Pin('1', -0.00508, 0, 0, 'N', 0, 0.00254, false, 0, true, '', true, false, '1', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(-0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '1', false, false, ExtentRect(0, 0, 0, 0, -0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'PinDef'
+ Pin('2', 0.00508, 0, 3.14159265358979, 'N', 0, 0.00254, false, 0, true, '', true, false, '2', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '2', false, false, ExtentRect(0, 0, 0, 0, 0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'Graphics'
+ Rect(0, 0, 0, 0, 0, 0, 0.00508, 0.00508, 0, 0, 0)
+ Rect(0, 1, 0, 0, -0.00211666666666667, 0, 0.000423333333333333, 0.000423333333333334, 0, 0, 0)
+ $end 'Graphics'
+ $end 'SMD-0603'
+ $begin 'WE-Coil-744301047'
+ ModTime=1718954704
+ CE=0
+ Library=''
+ ModSinceLib=false
+ LibLocation='Project'
+ HighestLevel=1
+ Normalize=false
+ InitialLevels(0, 1)
+ $begin 'PinDef'
+ Pin('1', -0.00508, 0, 0, 'N', 0, 0.00254, false, 0, true, '', true, false, '1', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(-0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '1', false, false, ExtentRect(0, 0, 0, 0, -0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'PinDef'
+ Pin('2', 0.00508, 0, 3.14159265358979, 'N', 0, 0.00254, false, 0, true, '', true, false, '2', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '2', false, false, ExtentRect(0, 0, 0, 0, 0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'Graphics'
+ Rect(0, 0, 0, 0, 0, 0, 0.00508, 0.00508, 0, 0, 0)
+ Rect(0, 1, 0, 0, -0.00211666666666667, 0, 0.000423333333333333, 0.000423333333333334, 0, 0, 0)
+ $end 'Graphics'
+ $end 'WE-Coil-744301047'
+ $begin 'WE-Coil-PD4-S'
+ ModTime=1718954704
+ CE=0
+ Library=''
+ ModSinceLib=false
+ LibLocation='Project'
+ HighestLevel=1
+ Normalize=false
+ InitialLevels(0, 1)
+ $begin 'PinDef'
+ Pin('1', -0.00508, 0, 0, 'N', 0, 0.00254, false, 0, true, '', true, false, '1', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(-0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '1', false, false, ExtentRect(0, 0, 0, 0, -0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'PinDef'
+ Pin('2', 0.00508, 0, 3.14159265358979, 'N', 0, 0.00254, false, 0, true, '', true, false, '2', true)
+ $begin 'PropDisplayMap'
+ PinName(2, 5, 1, Text(0.00508, 0.000635, 0, 4, 5, false, 'Arial', 0, '2', false, false, ExtentRect(0, 0, 0, 0, 0.00508, 0.00113792000000018, 0.000670560000000244, 0.00167640000000061, 0, 0, 0)))
+ $end 'PropDisplayMap'
+ $end 'PinDef'
+ $begin 'Graphics'
+ Rect(0, 0, 0, 0, 0, 0, 0.00508, 0.00508, 0, 0, 0)
+ Rect(0, 1, 0, 0, -0.00211666666666667, 0, 0.000423333333333333, 0.000423333333333334, 0, 0, 0)
+ $end 'Graphics'
+ $end 'WE-Coil-PD4-S'
+ $end 'Symbols'
+ $begin 'DefInfo'
+ CAPC0603X33X15LL03T05(1002, 0, 0, 2, '', 1718954704, '', 'CAPC0603X33X15LL03T05', '', '', '', '', '', '', '', 'Project', '', '', 1718954704, '', 0, 0)
+ CAPC1005X05N(1002, 0, 0, 2, '', 1718954704, '', 'CAPC1005X05N', '', '', '', '', '', '', '', 'Project', '', '', 1718954704, '', 0, 0)
+ CAPC1005X33X10LL5(1002, 0, 0, 2, '', 1718954704, '', 'CAPC1005X33X10LL5', '', '', '', '', '', '', '', 'Project', '', '', 1718954704, '', 0, 0)
+ CAPC1005X55X10LL05(1002, 0, 0, 2, '', 1718954704, '', 'CAPC1005X55X10LL05', '', '', '', '', '', '', '', 'Project', '', '', 1718954704, '', 0, 0)
+ CAPC1005X55X23ML05T8(1002, 0, 0, 2, '', 1718954704, '', 'CAPC1005X55X23ML05T8', '', '', '', '', '', '', '', 'Project', '', '', 1718954704, '', 0, 0)
+ CAPC1005X55X25LL05T10(1002, 0, 0, 2, '', 1718954704, '', 'CAPC1005X55X25LL05T10', '', '', '', '', '', '', '', 'Project', '', '', 1718954704, '', 0, 0)
+ CAPC1005X55X25ML05T10(1002, 0, 0, 2, '', 1718954704, '', 'CAPC1005X55X25ML05T10', '', '', '', '', '', '', '', 'Project', '', '', 1718954704, '', 0, 0)
+ CAPC1005X55X25NL05T10(1002, 0, 0, 2, '', 1718954704, '', 'CAPC1005X55X25NL05T10', '', '', '', '', '', '', '', 'Project', '', '', 1718954704, '', 0, 0)
+ CAPC1608X08N(1002, 0, 0, 2, '', 1718954704, '', 'CAPC1608X08N', '', '', '', '', '', '', '', 'Project', '', '', 1718954704, '', 0, 0)
+ CAPC1608X90X35ML10T15(1002, 0, 0, 2, '', 1718954704, '', 'CAPC1608X90X35ML10T15', '', '', '', '', '', '', '', 'Project', '', '', 1718954704, '', 0, 0)
+ CAPC2012X12N(1002, 0, 0, 2, '', 1718954704, '', 'CAPC2012X12N', '', '', '', '', '', '', '', 'Project', '', '', 1718954704, '', 0, 0)
+ CAPC2013X100X20NL20(1002, 0, 0, 2, '', 1718954704, '', 'CAPC2013X100X20NL20', '', '', '', '', '', '', '', 'Project', '', '', 1718954704, '', 0, 0)
+ CAPC3216X180X20ML20(1002, 0, 0, 2, '', 1718954704, '', 'CAPC3216X180X20ML20', '', '', '', '', '', '', '', 'Project', '', '', 1718954704, '', 0, 0)
+ CAPC3216X180X55ML20T25(1002, 0, 0, 2, '', 1718954704, '', 'CAPC3216X180X55ML20T25', '', '', '', '', '', '', '', 'Project', '', '', 1718954704, '', 0, 0)
+ CAPC3216X190X55ML30T25(1002, 0, 0, 2, '', 1718954704, '', 'CAPC3216X190X55ML30T25', '', '', '', '', '', '', '', 'Project', '', '', 1718954704, '', 0, 0)
+ CAPMP7343X31N(1002, 0, 0, 2, '', 1718954704, '', 'CAPMP7343X31N', '', '', '', '', '', '', '', 'Project', '', '', 1718954704, '', 0, 0)
+ 'COIL-1008CS_V'(1002, 0, 0, 2, '', 1718954704, '', 'COIL-1008CS_V', '', '', '', '', '', '', '', 'Project', '', '', 1718954704, '', 0, 0)
+ 'MURA-BLM15-CHIP-2_V'(1002, 0, 0, 2, '', 1718954704, '', 'MURA-BLM15-CHIP-2_V', '', '', '', '', '', '', '', 'Project', '', '', 1718954704, '', 0, 0)
+ 'MURA-BLM15AG221SN1x_V'(1002, 0, 0, 2, '', 1718954704, '', 'MURA-BLM15AG221SN1x_V', '', '', '', '', '', '', '', 'Project', '', '', 1718954704, '', 0, 0)
+ RESC1005X35X25NL8T10(1002, 0, 0, 2, '', 1718954704, '', 'RESC1005X35X25NL8T10', '', '', '', '', '', '', '', 'Project', '', '', 1718954704, '', 0, 0)
+ RESC1005X40X25LL05T05(1002, 0, 0, 2, '', 1718954704, '', 'RESC1005X40X25LL05T05', '', '', '', '', '', '', '', 'Project', '', '', 1718954704, '', 0, 0)
+ RESC1005X40X25ML05T05(1002, 0, 0, 2, '', 1718954704, '', 'RESC1005X40X25ML05T05', '', '', '', '', '', '', '', 'Project', '', '', 1718954704, '', 0, 0)
+ RESC1005X40X25NL05T05(1002, 0, 0, 2, '', 1718954704, '', 'RESC1005X40X25NL05T05', '', '', '', '', '', '', '', 'Project', '', '', 1718954704, '', 0, 0)
+ RESC1005X40X25NL5T10(1002, 0, 0, 2, '', 1718954704, '', 'RESC1005X40X25NL5T10', '', '', '', '', '', '', '', 'Project', '', '', 1718954704, '', 0, 0)
+ RESC1608X05N(1002, 0, 0, 2, '', 1718954704, '', 'RESC1608X05N', '', '', '', '', '', '', '', 'Project', '', '', 1718954704, '', 0, 0)
+ 'SMD-0603'(1002, 0, 0, 2, '', 1718954704, '', 'SMD-0603', '', '', '', '', '', '', '', 'Project', '', '', 1718954704, '', 0, 0)
+ 'WE-Coil-744301047'(1002, 0, 0, 2, '', 1718954704, '', 'WE-Coil-744301047', '', '', '', '', '', '', '', 'Project', '', '', 1718954704, '', 0, 0)
+ 'WE-Coil-PD4-S'(1002, 0, 0, 2, '', 1718954704, '', 'WE-Coil-PD4-S', '', '', '', '', '', '', '', 'Project', '', '', 1718954704, '', 0, 0)
+ main(1002, 0, 16, 0, '', 1718954704, '', 'main', '', '', '', '', '', '', '', 'Project', '', '', 1718954704, '', 0, 0)
+ $end 'DefInfo'
+ $begin 'Compdefs'
+ $begin 'CAPC0603X33X15LL03T05'
+ Library=''
+ CircuitEnv=0
+ Refbase='U'
+ NumParts=1
+ ModSinceLib=true
+ Terminal('1', '', 'A', false, 0, 1, '', 'Electrical', '0')
+ Terminal('2', '', 'A', false, 1, 1, '', 'Electrical', '0')
+ CompExtID=1
+ $begin 'Parameters'
+ MenuProp('CoSimulator', 'D', '', 'DefaultNetlist', 0)
+ ButtonProp('CosimDefinition', 'D', '', 'Edit', 'Edit', 40501, ButtonPropClientData())
+ $end 'Parameters'
+ $begin 'CosimDefinitions'
+ $begin 'CosimDefinition'
+ CosimulatorType=4
+ CosimDefName='DefaultNetlist'
+ IsDefinition=true
+ Connect=true
+ Data()
+ GRef()
+ $end 'CosimDefinition'
+ DefaultCosim='DefaultNetlist'
+ $end 'CosimDefinitions'
+ $end 'CAPC0603X33X15LL03T05'
+ $begin 'CAPC1005X05N'
+ Library=''
+ CircuitEnv=0
+ Refbase='U'
+ NumParts=1
+ ModSinceLib=true
+ Terminal('2', '', 'A', false, 2, 1, '', 'Electrical', '0')
+ Terminal('1', '', 'A', false, 3, 1, '', 'Electrical', '0')
+ CompExtID=1
+ $begin 'Parameters'
+ MenuProp('CoSimulator', 'D', '', 'DefaultNetlist', 0)
+ ButtonProp('CosimDefinition', 'D', '', 'Edit', 'Edit', 40501, ButtonPropClientData())
+ $end 'Parameters'
+ $begin 'CosimDefinitions'
+ $begin 'CosimDefinition'
+ CosimulatorType=4
+ CosimDefName='DefaultNetlist'
+ IsDefinition=true
+ Connect=true
+ Data()
+ GRef()
+ $end 'CosimDefinition'
+ DefaultCosim='DefaultNetlist'
+ $end 'CosimDefinitions'
+ $end 'CAPC1005X05N'
+ $begin 'CAPC1005X33X10LL5'
+ Library=''
+ CircuitEnv=0
+ Refbase='U'
+ NumParts=1
+ ModSinceLib=true
+ Terminal('1', '', 'A', false, 4, 1, '', 'Electrical', '0')
+ Terminal('2', '', 'A', false, 5, 1, '', 'Electrical', '0')
+ CompExtID=1
+ $begin 'Parameters'
+ MenuProp('CoSimulator', 'D', '', 'DefaultNetlist', 0)
+ ButtonProp('CosimDefinition', 'D', '', 'Edit', 'Edit', 40501, ButtonPropClientData())
+ $end 'Parameters'
+ $begin 'CosimDefinitions'
+ $begin 'CosimDefinition'
+ CosimulatorType=4
+ CosimDefName='DefaultNetlist'
+ IsDefinition=true
+ Connect=true
+ Data()
+ GRef()
+ $end 'CosimDefinition'
+ DefaultCosim='DefaultNetlist'
+ $end 'CosimDefinitions'
+ $end 'CAPC1005X33X10LL5'
+ $begin 'CAPC1005X55X10LL05'
+ Library=''
+ CircuitEnv=0
+ Refbase='U'
+ NumParts=1
+ ModSinceLib=true
+ Terminal('2', '', 'A', false, 6, 1, '', 'Electrical', '0')
+ Terminal('1', '', 'A', false, 7, 1, '', 'Electrical', '0')
+ CompExtID=1
+ $begin 'Parameters'
+ MenuProp('CoSimulator', 'D', '', 'DefaultNetlist', 0)
+ ButtonProp('CosimDefinition', 'D', '', 'Edit', 'Edit', 40501, ButtonPropClientData())
+ $end 'Parameters'
+ $begin 'CosimDefinitions'
+ $begin 'CosimDefinition'
+ CosimulatorType=4
+ CosimDefName='DefaultNetlist'
+ IsDefinition=true
+ Connect=true
+ Data()
+ GRef()
+ $end 'CosimDefinition'
+ DefaultCosim='DefaultNetlist'
+ $end 'CosimDefinitions'
+ $end 'CAPC1005X55X10LL05'
+ $begin 'CAPC1005X55X23ML05T8'
+ Library=''
+ CircuitEnv=0
+ Refbase='U'
+ NumParts=1
+ ModSinceLib=true
+ Terminal('2', '', 'A', false, 8, 1, '', 'Electrical', '0')
+ Terminal('1', '', 'A', false, 9, 1, '', 'Electrical', '0')
+ CompExtID=1
+ $begin 'Parameters'
+ MenuProp('CoSimulator', 'D', '', 'DefaultNetlist', 0)
+ ButtonProp('CosimDefinition', 'D', '', 'Edit', 'Edit', 40501, ButtonPropClientData())
+ $end 'Parameters'
+ $begin 'CosimDefinitions'
+ $begin 'CosimDefinition'
+ CosimulatorType=4
+ CosimDefName='DefaultNetlist'
+ IsDefinition=true
+ Connect=true
+ Data()
+ GRef()
+ $end 'CosimDefinition'
+ DefaultCosim='DefaultNetlist'
+ $end 'CosimDefinitions'
+ $end 'CAPC1005X55X23ML05T8'
+ $begin 'CAPC1005X55X25LL05T10'
+ Library=''
+ CircuitEnv=0
+ Refbase='U'
+ NumParts=1
+ ModSinceLib=true
+ Terminal('1', '', 'A', false, 10, 1, '', 'Electrical', '0')
+ Terminal('2', '', 'A', false, 11, 1, '', 'Electrical', '0')
+ CompExtID=1
+ $begin 'Parameters'
+ MenuProp('CoSimulator', 'D', '', 'DefaultNetlist', 0)
+ ButtonProp('CosimDefinition', 'D', '', 'Edit', 'Edit', 40501, ButtonPropClientData())
+ $end 'Parameters'
+ $begin 'CosimDefinitions'
+ $begin 'CosimDefinition'
+ CosimulatorType=4
+ CosimDefName='DefaultNetlist'
+ IsDefinition=true
+ Connect=true
+ Data()
+ GRef()
+ $end 'CosimDefinition'
+ DefaultCosim='DefaultNetlist'
+ $end 'CosimDefinitions'
+ $end 'CAPC1005X55X25LL05T10'
+ $begin 'CAPC1005X55X25ML05T10'
+ Library=''
+ CircuitEnv=0
+ Refbase='U'
+ NumParts=1
+ ModSinceLib=true
+ Terminal('1', '', 'A', false, 12, 1, '', 'Electrical', '0')
+ Terminal('2', '', 'A', false, 13, 1, '', 'Electrical', '0')
+ CompExtID=1
+ $begin 'Parameters'
+ MenuProp('CoSimulator', 'D', '', 'DefaultNetlist', 0)
+ ButtonProp('CosimDefinition', 'D', '', 'Edit', 'Edit', 40501, ButtonPropClientData())
+ $end 'Parameters'
+ $begin 'CosimDefinitions'
+ $begin 'CosimDefinition'
+ CosimulatorType=4
+ CosimDefName='DefaultNetlist'
+ IsDefinition=true
+ Connect=true
+ Data()
+ GRef()
+ $end 'CosimDefinition'
+ DefaultCosim='DefaultNetlist'
+ $end 'CosimDefinitions'
+ $end 'CAPC1005X55X25ML05T10'
+ $begin 'CAPC1005X55X25NL05T10'
+ Library=''
+ CircuitEnv=0
+ Refbase='U'
+ NumParts=1
+ ModSinceLib=true
+ Terminal('2', '', 'A', false, 14, 1, '', 'Electrical', '0')
+ Terminal('1', '', 'A', false, 15, 1, '', 'Electrical', '0')
+ CompExtID=1
+ $begin 'Parameters'
+ MenuProp('CoSimulator', 'D', '', 'DefaultNetlist', 0)
+ ButtonProp('CosimDefinition', 'D', '', 'Edit', 'Edit', 40501, ButtonPropClientData())
+ $end 'Parameters'
+ $begin 'CosimDefinitions'
+ $begin 'CosimDefinition'
+ CosimulatorType=4
+ CosimDefName='DefaultNetlist'
+ IsDefinition=true
+ Connect=true
+ Data()
+ GRef()
+ $end 'CosimDefinition'
+ DefaultCosim='DefaultNetlist'
+ $end 'CosimDefinitions'
+ $end 'CAPC1005X55X25NL05T10'
+ $begin 'CAPC1608X08N'
+ Library=''
+ CircuitEnv=0
+ Refbase='U'
+ NumParts=1
+ ModSinceLib=true
+ Terminal('2', '', 'A', false, 16, 1, '', 'Electrical', '0')
+ Terminal('1', '', 'A', false, 17, 1, '', 'Electrical', '0')
+ CompExtID=1
+ $begin 'Parameters'
+ MenuProp('CoSimulator', 'D', '', 'DefaultNetlist', 0)
+ ButtonProp('CosimDefinition', 'D', '', 'Edit', 'Edit', 40501, ButtonPropClientData())
+ $end 'Parameters'
+ $begin 'CosimDefinitions'
+ $begin 'CosimDefinition'
+ CosimulatorType=4
+ CosimDefName='DefaultNetlist'
+ IsDefinition=true
+ Connect=true
+ Data()
+ GRef()
+ $end 'CosimDefinition'
+ DefaultCosim='DefaultNetlist'
+ $end 'CosimDefinitions'
+ $end 'CAPC1608X08N'
+ $begin 'CAPC1608X90X35ML10T15'
+ Library=''
+ CircuitEnv=0
+ Refbase='U'
+ NumParts=1
+ ModSinceLib=true
+ Terminal('2', '', 'A', false, 18, 1, '', 'Electrical', '0')
+ Terminal('1', '', 'A', false, 19, 1, '', 'Electrical', '0')
+ CompExtID=1
+ $begin 'Parameters'
+ MenuProp('CoSimulator', 'D', '', 'DefaultNetlist', 0)
+ ButtonProp('CosimDefinition', 'D', '', 'Edit', 'Edit', 40501, ButtonPropClientData())
+ $end 'Parameters'
+ $begin 'CosimDefinitions'
+ $begin 'CosimDefinition'
+ CosimulatorType=4
+ CosimDefName='DefaultNetlist'
+ IsDefinition=true
+ Connect=true
+ Data()
+ GRef()
+ $end 'CosimDefinition'
+ DefaultCosim='DefaultNetlist'
+ $end 'CosimDefinitions'
+ $end 'CAPC1608X90X35ML10T15'
+ $begin 'CAPC2012X12N'
+ Library=''
+ CircuitEnv=0
+ Refbase='U'
+ NumParts=1
+ ModSinceLib=true
+ Terminal('1', '', 'A', false, 20, 1, '', 'Electrical', '0')
+ Terminal('2', '', 'A', false, 21, 1, '', 'Electrical', '0')
+ CompExtID=1
+ $begin 'Parameters'
+ MenuProp('CoSimulator', 'D', '', 'DefaultNetlist', 0)
+ ButtonProp('CosimDefinition', 'D', '', 'Edit', 'Edit', 40501, ButtonPropClientData())
+ $end 'Parameters'
+ $begin 'CosimDefinitions'
+ $begin 'CosimDefinition'
+ CosimulatorType=4
+ CosimDefName='DefaultNetlist'
+ IsDefinition=true
+ Connect=true
+ Data()
+ GRef()
+ $end 'CosimDefinition'
+ DefaultCosim='DefaultNetlist'
+ $end 'CosimDefinitions'
+ $end 'CAPC2012X12N'
+ $begin 'CAPC2013X100X20NL20'
+ Library=''
+ CircuitEnv=0
+ Refbase='U'
+ NumParts=1
+ ModSinceLib=true
+ Terminal('1', '', 'A', false, 22, 1, '', 'Electrical', '0')
+ Terminal('2', '', 'A', false, 23, 1, '', 'Electrical', '0')
+ CompExtID=1
+ $begin 'Parameters'
+ MenuProp('CoSimulator', 'D', '', 'DefaultNetlist', 0)
+ ButtonProp('CosimDefinition', 'D', '', 'Edit', 'Edit', 40501, ButtonPropClientData())
+ $end 'Parameters'
+ $begin 'CosimDefinitions'
+ $begin 'CosimDefinition'
+ CosimulatorType=4
+ CosimDefName='DefaultNetlist'
+ IsDefinition=true
+ Connect=true
+ Data()
+ GRef()
+ $end 'CosimDefinition'
+ DefaultCosim='DefaultNetlist'
+ $end 'CosimDefinitions'
+ $end 'CAPC2013X100X20NL20'
+ $begin 'CAPC3216X180X20ML20'
+ Library=''
+ CircuitEnv=0
+ Refbase='U'
+ NumParts=1
+ ModSinceLib=true
+ Terminal('2', '', 'A', false, 24, 1, '', 'Electrical', '0')
+ Terminal('1', '', 'A', false, 25, 1, '', 'Electrical', '0')
+ CompExtID=1
+ $begin 'Parameters'
+ MenuProp('CoSimulator', 'D', '', 'DefaultNetlist', 0)
+ ButtonProp('CosimDefinition', 'D', '', 'Edit', 'Edit', 40501, ButtonPropClientData())
+ $end 'Parameters'
+ $begin 'CosimDefinitions'
+ $begin 'CosimDefinition'
+ CosimulatorType=4
+ CosimDefName='DefaultNetlist'
+ IsDefinition=true
+ Connect=true
+ Data()
+ GRef()
+ $end 'CosimDefinition'
+ DefaultCosim='DefaultNetlist'
+ $end 'CosimDefinitions'
+ $end 'CAPC3216X180X20ML20'
+ $begin 'CAPC3216X180X55ML20T25'
+ Library=''
+ CircuitEnv=0
+ Refbase='U'
+ NumParts=1
+ ModSinceLib=true
+ Terminal('2', '', 'A', false, 26, 1, '', 'Electrical', '0')
+ Terminal('1', '', 'A', false, 27, 1, '', 'Electrical', '0')
+ CompExtID=1
+ $begin 'Parameters'
+ MenuProp('CoSimulator', 'D', '', 'DefaultNetlist', 0)
+ ButtonProp('CosimDefinition', 'D', '', 'Edit', 'Edit', 40501, ButtonPropClientData())
+ $end 'Parameters'
+ $begin 'CosimDefinitions'
+ $begin 'CosimDefinition'
+ CosimulatorType=4
+ CosimDefName='DefaultNetlist'
+ IsDefinition=true
+ Connect=true
+ Data()
+ GRef()
+ $end 'CosimDefinition'
+ DefaultCosim='DefaultNetlist'
+ $end 'CosimDefinitions'
+ $end 'CAPC3216X180X55ML20T25'
+ $begin 'CAPC3216X190X55ML30T25'
+ Library=''
+ CircuitEnv=0
+ Refbase='U'
+ NumParts=1
+ ModSinceLib=true
+ Terminal('1', '', 'A', false, 28, 1, '', 'Electrical', '0')
+ Terminal('2', '', 'A', false, 29, 1, '', 'Electrical', '0')
+ CompExtID=1
+ $begin 'Parameters'
+ MenuProp('CoSimulator', 'D', '', 'DefaultNetlist', 0)
+ ButtonProp('CosimDefinition', 'D', '', 'Edit', 'Edit', 40501, ButtonPropClientData())
+ $end 'Parameters'
+ $begin 'CosimDefinitions'
+ $begin 'CosimDefinition'
+ CosimulatorType=4
+ CosimDefName='DefaultNetlist'
+ IsDefinition=true
+ Connect=true
+ Data()
+ GRef()
+ $end 'CosimDefinition'
+ DefaultCosim='DefaultNetlist'
+ $end 'CosimDefinitions'
+ $end 'CAPC3216X190X55ML30T25'
+ $begin 'CAPMP7343X31N'
+ Library=''
+ CircuitEnv=0
+ Refbase='U'
+ NumParts=1
+ ModSinceLib=true
+ Terminal('1', '', 'A', false, 30, 1, '', 'Electrical', '0')
+ Terminal('2', '', 'A', false, 31, 1, '', 'Electrical', '0')
+ CompExtID=1
+ $begin 'Parameters'
+ MenuProp('CoSimulator', 'D', '', 'DefaultNetlist', 0)
+ ButtonProp('CosimDefinition', 'D', '', 'Edit', 'Edit', 40501, ButtonPropClientData())
+ $end 'Parameters'
+ $begin 'CosimDefinitions'
+ $begin 'CosimDefinition'
+ CosimulatorType=4
+ CosimDefName='DefaultNetlist'
+ IsDefinition=true
+ Connect=true
+ Data()
+ GRef()
+ $end 'CosimDefinition'
+ DefaultCosim='DefaultNetlist'
+ $end 'CosimDefinitions'
+ $end 'CAPMP7343X31N'
+ $begin 'COIL-1008CS_V'
+ Library=''
+ CircuitEnv=0
+ Refbase='U'
+ NumParts=1
+ ModSinceLib=true
+ Terminal('1', '', 'A', false, 32, 1, '', 'Electrical', '0')
+ Terminal('2', '', 'A', false, 33, 1, '', 'Electrical', '0')
+ CompExtID=1
+ $begin 'Parameters'
+ MenuProp('CoSimulator', 'D', '', 'DefaultNetlist', 0)
+ ButtonProp('CosimDefinition', 'D', '', 'Edit', 'Edit', 40501, ButtonPropClientData())
+ $end 'Parameters'
+ $begin 'CosimDefinitions'
+ $begin 'CosimDefinition'
+ CosimulatorType=4
+ CosimDefName='DefaultNetlist'
+ IsDefinition=true
+ Connect=true
+ Data()
+ GRef()
+ $end 'CosimDefinition'
+ DefaultCosim='DefaultNetlist'
+ $end 'CosimDefinitions'
+ $end 'COIL-1008CS_V'
+ $begin 'MURA-BLM15-CHIP-2_V'
+ Library=''
+ CircuitEnv=0
+ Refbase='U'
+ NumParts=1
+ ModSinceLib=true
+ Terminal('2', '', 'A', false, 34, 1, '', 'Electrical', '0')
+ Terminal('1', '', 'A', false, 35, 1, '', 'Electrical', '0')
+ CompExtID=1
+ $begin 'Parameters'
+ MenuProp('CoSimulator', 'D', '', 'DefaultNetlist', 0)
+ ButtonProp('CosimDefinition', 'D', '', 'Edit', 'Edit', 40501, ButtonPropClientData())
+ $end 'Parameters'
+ $begin 'CosimDefinitions'
+ $begin 'CosimDefinition'
+ CosimulatorType=4
+ CosimDefName='DefaultNetlist'
+ IsDefinition=true
+ Connect=true
+ Data()
+ GRef()
+ $end 'CosimDefinition'
+ DefaultCosim='DefaultNetlist'
+ $end 'CosimDefinitions'
+ $end 'MURA-BLM15-CHIP-2_V'
+ $begin 'MURA-BLM15AG221SN1x_V'
+ Library=''
+ CircuitEnv=0
+ Refbase='U'
+ NumParts=1
+ ModSinceLib=true
+ Terminal('2', '', 'A', false, 36, 1, '', 'Electrical', '0')
+ Terminal('1', '', 'A', false, 37, 1, '', 'Electrical', '0')
+ CompExtID=1
+ $begin 'Parameters'
+ MenuProp('CoSimulator', 'D', '', 'DefaultNetlist', 0)
+ ButtonProp('CosimDefinition', 'D', '', 'Edit', 'Edit', 40501, ButtonPropClientData())
+ $end 'Parameters'
+ $begin 'CosimDefinitions'
+ $begin 'CosimDefinition'
+ CosimulatorType=4
+ CosimDefName='DefaultNetlist'
+ IsDefinition=true
+ Connect=true
+ Data()
+ GRef()
+ $end 'CosimDefinition'
+ DefaultCosim='DefaultNetlist'
+ $end 'CosimDefinitions'
+ $end 'MURA-BLM15AG221SN1x_V'
+ $begin 'RESC1005X35X25NL8T10'
+ Library=''
+ CircuitEnv=0
+ Refbase='U'
+ NumParts=1
+ ModSinceLib=true
+ Terminal('1', '', 'A', false, 38, 1, '', 'Electrical', '0')
+ Terminal('2', '', 'A', false, 39, 1, '', 'Electrical', '0')
+ CompExtID=1
+ $begin 'Parameters'
+ MenuProp('CoSimulator', 'D', '', 'DefaultNetlist', 0)
+ ButtonProp('CosimDefinition', 'D', '', 'Edit', 'Edit', 40501, ButtonPropClientData())
+ $end 'Parameters'
+ $begin 'CosimDefinitions'
+ $begin 'CosimDefinition'
+ CosimulatorType=4
+ CosimDefName='DefaultNetlist'
+ IsDefinition=true
+ Connect=true
+ Data()
+ GRef()
+ $end 'CosimDefinition'
+ DefaultCosim='DefaultNetlist'
+ $end 'CosimDefinitions'
+ $end 'RESC1005X35X25NL8T10'
+ $begin 'RESC1005X40X25LL05T05'
+ Library=''
+ CircuitEnv=0
+ Refbase='U'
+ NumParts=1
+ ModSinceLib=true
+ Terminal('2', '', 'A', false, 40, 1, '', 'Electrical', '0')
+ Terminal('1', '', 'A', false, 41, 1, '', 'Electrical', '0')
+ CompExtID=1
+ $begin 'Parameters'
+ MenuProp('CoSimulator', 'D', '', 'DefaultNetlist', 0)
+ ButtonProp('CosimDefinition', 'D', '', 'Edit', 'Edit', 40501, ButtonPropClientData())
+ $end 'Parameters'
+ $begin 'CosimDefinitions'
+ $begin 'CosimDefinition'
+ CosimulatorType=4
+ CosimDefName='DefaultNetlist'
+ IsDefinition=true
+ Connect=true
+ Data()
+ GRef()
+ $end 'CosimDefinition'
+ DefaultCosim='DefaultNetlist'
+ $end 'CosimDefinitions'
+ $end 'RESC1005X40X25LL05T05'
+ $begin 'RESC1005X40X25ML05T05'
+ Library=''
+ CircuitEnv=0
+ Refbase='U'
+ NumParts=1
+ ModSinceLib=true
+ Terminal('1', '', 'A', false, 42, 1, '', 'Electrical', '0')
+ Terminal('2', '', 'A', false, 43, 1, '', 'Electrical', '0')
+ CompExtID=1
+ $begin 'Parameters'
+ MenuProp('CoSimulator', 'D', '', 'DefaultNetlist', 0)
+ ButtonProp('CosimDefinition', 'D', '', 'Edit', 'Edit', 40501, ButtonPropClientData())
+ $end 'Parameters'
+ $begin 'CosimDefinitions'
+ $begin 'CosimDefinition'
+ CosimulatorType=4
+ CosimDefName='DefaultNetlist'
+ IsDefinition=true
+ Connect=true
+ Data()
+ GRef()
+ $end 'CosimDefinition'
+ DefaultCosim='DefaultNetlist'
+ $end 'CosimDefinitions'
+ $end 'RESC1005X40X25ML05T05'
+ $begin 'RESC1005X40X25NL05T05'
+ Library=''
+ CircuitEnv=0
+ Refbase='U'
+ NumParts=1
+ ModSinceLib=true
+ Terminal('2', '', 'A', false, 44, 1, '', 'Electrical', '0')
+ Terminal('1', '', 'A', false, 45, 1, '', 'Electrical', '0')
+ CompExtID=1
+ $begin 'Parameters'
+ MenuProp('CoSimulator', 'D', '', 'DefaultNetlist', 0)
+ ButtonProp('CosimDefinition', 'D', '', 'Edit', 'Edit', 40501, ButtonPropClientData())
+ $end 'Parameters'
+ $begin 'CosimDefinitions'
+ $begin 'CosimDefinition'
+ CosimulatorType=4
+ CosimDefName='DefaultNetlist'
+ IsDefinition=true
+ Connect=true
+ Data()
+ GRef()
+ $end 'CosimDefinition'
+ DefaultCosim='DefaultNetlist'
+ $end 'CosimDefinitions'
+ $end 'RESC1005X40X25NL05T05'
+ $begin 'RESC1005X40X25NL5T10'
+ Library=''
+ CircuitEnv=0
+ Refbase='U'
+ NumParts=1
+ ModSinceLib=true
+ Terminal('2', '', 'A', false, 46, 1, '', 'Electrical', '0')
+ Terminal('1', '', 'A', false, 47, 1, '', 'Electrical', '0')
+ CompExtID=1
+ $begin 'Parameters'
+ MenuProp('CoSimulator', 'D', '', 'DefaultNetlist', 0)
+ ButtonProp('CosimDefinition', 'D', '', 'Edit', 'Edit', 40501, ButtonPropClientData())
+ $end 'Parameters'
+ $begin 'CosimDefinitions'
+ $begin 'CosimDefinition'
+ CosimulatorType=4
+ CosimDefName='DefaultNetlist'
+ IsDefinition=true
+ Connect=true
+ Data()
+ GRef()
+ $end 'CosimDefinition'
+ DefaultCosim='DefaultNetlist'
+ $end 'CosimDefinitions'
+ $end 'RESC1005X40X25NL5T10'
+ $begin 'RESC1608X05N'
+ Library=''
+ CircuitEnv=0
+ Refbase='U'
+ NumParts=1
+ ModSinceLib=true
+ Terminal('2', '', 'A', false, 48, 1, '', 'Electrical', '0')
+ Terminal('1', '', 'A', false, 49, 1, '', 'Electrical', '0')
+ CompExtID=1
+ $begin 'Parameters'
+ MenuProp('CoSimulator', 'D', '', 'DefaultNetlist', 0)
+ ButtonProp('CosimDefinition', 'D', '', 'Edit', 'Edit', 40501, ButtonPropClientData())
+ $end 'Parameters'
+ $begin 'CosimDefinitions'
+ $begin 'CosimDefinition'
+ CosimulatorType=4
+ CosimDefName='DefaultNetlist'
+ IsDefinition=true
+ Connect=true
+ Data()
+ GRef()
+ $end 'CosimDefinition'
+ DefaultCosim='DefaultNetlist'
+ $end 'CosimDefinitions'
+ $end 'RESC1608X05N'
+ $begin 'SMD-0603'
+ Library=''
+ CircuitEnv=0
+ Refbase='U'
+ NumParts=1
+ ModSinceLib=true
+ Terminal('1', '', 'A', false, 50, 1, '', 'Electrical', '0')
+ Terminal('2', '', 'A', false, 51, 1, '', 'Electrical', '0')
+ CompExtID=1
+ $begin 'Parameters'
+ MenuProp('CoSimulator', 'D', '', 'DefaultNetlist', 0)
+ ButtonProp('CosimDefinition', 'D', '', 'Edit', 'Edit', 40501, ButtonPropClientData())
+ $end 'Parameters'
+ $begin 'CosimDefinitions'
+ $begin 'CosimDefinition'
+ CosimulatorType=4
+ CosimDefName='DefaultNetlist'
+ IsDefinition=true
+ Connect=true
+ Data()
+ GRef()
+ $end 'CosimDefinition'
+ DefaultCosim='DefaultNetlist'
+ $end 'CosimDefinitions'
+ $end 'SMD-0603'
+ $begin 'WE-Coil-744301047'
+ Library=''
+ CircuitEnv=0
+ Refbase='U'
+ NumParts=1
+ ModSinceLib=true
+ Terminal('1', '', 'A', false, 52, 1, '', 'Electrical', '0')
+ Terminal('2', '', 'A', false, 53, 1, '', 'Electrical', '0')
+ CompExtID=1
+ $begin 'Parameters'
+ MenuProp('CoSimulator', 'D', '', 'DefaultNetlist', 0)
+ ButtonProp('CosimDefinition', 'D', '', 'Edit', 'Edit', 40501, ButtonPropClientData())
+ $end 'Parameters'
+ $begin 'CosimDefinitions'
+ $begin 'CosimDefinition'
+ CosimulatorType=4
+ CosimDefName='DefaultNetlist'
+ IsDefinition=true
+ Connect=true
+ Data()
+ GRef()
+ $end 'CosimDefinition'
+ DefaultCosim='DefaultNetlist'
+ $end 'CosimDefinitions'
+ $end 'WE-Coil-744301047'
+ $begin 'WE-Coil-PD4-S'
+ Library=''
+ CircuitEnv=0
+ Refbase='U'
+ NumParts=1
+ ModSinceLib=true
+ Terminal('1', '', 'A', false, 54, 1, '', 'Electrical', '0')
+ Terminal('2', '', 'A', false, 55, 1, '', 'Electrical', '0')
+ CompExtID=1
+ $begin 'Parameters'
+ MenuProp('CoSimulator', 'D', '', 'DefaultNetlist', 0)
+ ButtonProp('CosimDefinition', 'D', '', 'Edit', 'Edit', 40501, ButtonPropClientData())
+ $end 'Parameters'
+ $begin 'CosimDefinitions'
+ $begin 'CosimDefinition'
+ CosimulatorType=4
+ CosimDefName='DefaultNetlist'
+ IsDefinition=true
+ Connect=true
+ Data()
+ GRef()
+ $end 'CosimDefinition'
+ DefaultCosim='DefaultNetlist'
+ $end 'CosimDefinitions'
+ $end 'WE-Coil-PD4-S'
+ $begin 'main'
+ Library=''
+ CircuitEnv=0
+ Refbase='U'
+ NumParts=1
+ ModSinceLib=true
+ $begin 'Properties'
+ TextProp('Representation', 'D', '', 'main')
+ $end 'Properties'
+ CompExtID=1
+ $begin 'Parameters'
+ MenuProp('CoSimulator', 'D', '', 'DefaultNetlist', 0)
+ ButtonProp('CosimDefinition', 'D', '', 'Edit', 'Edit', 40501, ButtonPropClientData())
+ $end 'Parameters'
+ $begin 'CosimDefinitions'
+ $begin 'CosimDefinition'
+ CosimulatorType=4
+ CosimDefName='DefaultNetlist'
+ IsDefinition=true
+ Connect=true
+ Data()
+ GRef()
+ $end 'CosimDefinition'
+ DefaultCosim='DefaultNetlist'
+ $end 'CosimDefinitions'
+ $end 'main'
+ $end 'Compdefs'
+ $end 'Definitions'
+ DesignIDServer=2
+ MoveBackwards=false
+ $begin 'PlanarEMCircuit'
+ RepRewriteV2=true
+ Name='main'
+ DesignID=0
+ $begin 'Circuit'
+ ComponentName='main'
+ AutoFP=''
+ $begin 'DesignDatasets'
+ NextUniqueID=0
+ MoveBackwards=false
+ DatasetType='DesignDatasetType'
+ $begin 'DatasetDefinitions'
+ $end 'DatasetDefinitions'
+ $end 'DesignDatasets'
+ VariableOrders[0:]
+ $begin 'Net'
+ NetName='+VREFDDR4'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='1.2V_AVDDL'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='1.2V_AVDLL_PLL'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='1.2V_DVDDL'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='1.8V_DVDDH'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='12V-In'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='1V0'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='2V5'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='3.3V_AVDDH'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='5V'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='A10_GNDSENSE'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='AVCC_1V3'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='CLOCK_I2C_SCL'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='CLOCK_I2C_SDA'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_A0'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_A1'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_A10'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_A11'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_A12'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_A13'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_A2'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_A3'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_A4'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_A5'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_A6'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_A7'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_A8'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_A9'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_ACT'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_ALERT0'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_ALERT1'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_ALERT2'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_ALERT3'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_BA0'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_BA1'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_BG0'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_CAS'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_CKE'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_CLK_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_CLK_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_CSN'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DM0'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DM1'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DM2'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DM3'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DM4'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DM5'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DM6'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DM7'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ0'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ1'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ10'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ11'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ12'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ13'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ14'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ15'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ16'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ17'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ18'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ19'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ2'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ20'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ21'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ22'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ23'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ24'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ25'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ26'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ27'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ28'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ29'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ3'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ30'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ31'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ32'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ33'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ34'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ35'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ36'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ37'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ38'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ39'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ4'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ40'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ41'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ42'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ43'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ44'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ45'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ46'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ47'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ48'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ49'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ5'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ50'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ51'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ52'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ53'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ54'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ55'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ56'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ57'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ58'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ59'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ6'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ60'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ61'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ62'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ63'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ7'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ8'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQ9'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQS0_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQS0_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQS1_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQS1_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQS2_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQS2_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQS3_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQS3_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQS4_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQS4_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQS5_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQS5_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQS6_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQS6_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQS7_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_DQS7_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_ODT'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_PAR'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_RAS'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_RESETN'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DDR4_WEN'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DP_3V3'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DP_ML_LANE0_C_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DP_ML_LANE0_C_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DP_ML_LANE0_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DP_ML_LANE0_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DP_ML_LANE1_C_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DP_ML_LANE1_C_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DP_ML_LANE1_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DP_ML_LANE1_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DP_ML_LANE2_C_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DP_ML_LANE2_C_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DP_ML_LANE2_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DP_ML_LANE2_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DP_ML_LANE3_C_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DP_ML_LANE3_C_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DP_ML_LANE3_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='DP_ML_LANE3_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='ENET_HPS_GTX_CLK'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='ENET_HPS_MDC'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='ENET_HPS_MDIO'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='ENET_HPS_RX_CLK'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='ENET_HPS_RX_DV'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='ENET_HPS_RXD0'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='ENET_HPS_RXD1'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='ENET_HPS_RXD2'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='ENET_HPS_RXD3'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='ENET_HPS_TX_EN'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='ENET_HPS_TXD0'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='ENET_HPS_TXD1'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='ENET_HPS_TXD2'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='ENET_HPS_TXD3'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='GND'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='GND_DP'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='JTAG_TCK'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='JTAG_TDI'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='JTAG_TDO'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='JTAG_TMS'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='JTAG_TRST'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='LVDS_CH01_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='LVDS_CH01_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='LVDS_CH02_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='LVDS_CH02_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='LVDS_CH03_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='LVDS_CH03_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='LVDS_CH04_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='LVDS_CH04_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='LVDS_CH05_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='LVDS_CH05_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='LVDS_CH06_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='LVDS_CH06_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='LVDS_CH07_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='LVDS_CH07_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='LVDS_CH08_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='LVDS_CH08_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='LVDS_CH09_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='LVDS_CH09_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='LVDS_CH10_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='LVDS_CH10_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='LVDS_CH11_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='LVDS_CH11_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='LVDS_CH12_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='LVDS_CH12_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetC10_1'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetC10_2'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetC177_2'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetC178_2'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetC179_2'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetC180_2'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetC18_2'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetC19_1'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetC19_2'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetC25_2'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetC26_1'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetC26_2'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetC271_1'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetC291_2'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetC33_2'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetC34_1'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetC34_2'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetC35_1'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetC42_2'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetC43_2'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetC50_1'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetC50_2'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetC9_2'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetD3_2'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetIC1_7'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetIC1_8'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetIC1_9'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetIC2_5'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetJ1_13'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetJ1_14'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetJ1_18'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetJ1_19'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetJ2_13'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetJ2_14'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetJ2_16'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetJ2_17'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetJ3_2'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetR100_2'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetR102_1'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetR104_1'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetR105_2'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetR106_1'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetR108_2'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetR113_2'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetR114_2'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetR115_2'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetR116_1'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetR116_2'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetR117_2'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetR119_2'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetR11_2'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetR120_2'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetR121_2'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetR122_2'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetR123_1'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetR124_1'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetR12_1'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetR13_1'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetR1_2'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetR22_1'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetR24_2'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetR25_1'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetR26_1'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetR34_2'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetR65_1'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetR66_1'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetR82_1'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetR83_1'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetR8_1'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetR99_1'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetSW1_2'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetSW1_3'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetSW1_4'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetU13_1'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetU13_2'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetU1_AP13'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetU1_AV11'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetU1_AW11'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetU1_AW13'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='NetU9_46'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='PCIe_Gen4_CLKREQ_L'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='PCIe_Gen4_REFCLK_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='PCIe_Gen4_REFCLK_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='PCIe_Gen4_RST_L'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='PCIe_Gen4_RX0_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='PCIe_Gen4_RX0_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='PCIe_Gen4_RX1_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='PCIe_Gen4_RX1_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='PCIe_Gen4_RX2_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='PCIe_Gen4_RX2_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='PCIe_Gen4_RX3_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='PCIe_Gen4_RX3_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='PCIe_Gen4_SMB_CLK'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='PCIe_Gen4_SMB_DATA'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='PCIe_Gen4_TX0_CAP_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='PCIe_Gen4_TX0_CAP_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='PCIe_Gen4_TX0_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='PCIe_Gen4_TX0_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='PCIe_Gen4_TX1_CAP_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='PCIe_Gen4_TX1_CAP_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='PCIe_Gen4_TX1_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='PCIe_Gen4_TX1_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='PCIe_Gen4_TX2_CAP_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='PCIe_Gen4_TX2_CAP_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='PCIe_Gen4_TX2_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='PCIe_Gen4_TX2_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='PCIe_Gen4_TX3_CAP_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='PCIe_Gen4_TX3_CAP_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='PCIe_Gen4_TX3_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='PCIe_Gen4_TX3_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='PCIe_Gen4_USB_D_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='PCIe_Gen4_USB_D_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='PCIe_Gen4_W_DISABLE_L'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='PCIe_Gen4_WAKE_L'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='PDEN'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='PLL_1V8'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='REFCLK0_FMCB_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='REFCLK0_FMCB_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='REFCLK_DP_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='REFCLK_DP_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='SFPA__Mod_ABS'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='SFPA_RS0'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='SFPA_RS1'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='SFPA_Rx_LOS'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='SFPA_RX_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='SFPA_RX_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='SFPA_SCL'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='SFPA_SDA'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='SFPA_Tx_Disable'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='SFPA_Tx_Fault'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='SFPA_TX_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='SFPA_TX_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='SFPA_VCCR'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='SFPA_VCCT'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='TRD1_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='TRD1_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='TRD2_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='TRD2_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='TRD3_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='TRD3_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='TRD4_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='TRD4_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='USB3_D_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='USB3_D_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='USB3_SSRX_C_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='USB3_SSRX_C_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='USB3_SSRX_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='USB3_SSRX_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='USB3_SSTX_N'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='USB3_SSTX_P'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='USB3_VBUS'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $begin 'Net'
+ NetName='VDD_DDR'
+ $begin 'Properties'
+ CheckboxProp('AlignMicrowavePorts', 'D', '', true)
+ $end 'Properties'
+ $end 'Net'
+ $end 'Circuit'
+ $begin 'Layout'
+ BlackBox=false
+ DefUnits='mm'
+ NIdx=5951
+ ActLyr='1_Top'
+ Tol(1e-08, 1e-08, 1e-12)
+ $begin 'HfssExportInfo'
+ ScriptFileName=''
+ HfssFileName=''
+ Version=2
+ ExtentType='PolygonExtent'
+ BasePolygon=''
+ BasePolygonEDBUId=5949
+ DielExtentType='BboxExtent'
+ DielBasePolygon=''
+ DielBasePolygonEDBUId=-1
+ DielExt(Ext='0', Dim=false)
+ HonorUserDiel=true
+ TruncAtGnd=false
+ AirHorExt(Ext='0.15', Dim=false)
+ AirPosZExt(Ext='0.15', Dim=false)
+ AirNegZExt(Ext='0.15', Dim=false)
+ SyncZExt=true
+ OpenRegionType='Radiation'
+ UseRadBound=true
+ PMLVisible=false
+ OperFreq='5GHz'
+ RadLvl=0
+ UseStackupForZExtFact=false
+ Smooth=true
+ $end 'HfssExportInfo'
+ $end 'Layout'
+ $begin 'Rule Set'
+ $begin 'Data'
+ $end 'Data'
+ $begin 'DRCSolutionMgr'
+ $end 'DRCSolutionMgr'
+ $end 'Rule Set'
+ $begin 'Port'
+ $begin 'Data'
+ $end 'Data'
+ $begin 'CoupledPortsList'
+ $end 'CoupledPortsList'
+ $begin 'DiffPairs'
+ $end 'DiffPairs'
+ TotalVoltage=false
+ IncludePortPostProcess=true
+ $begin 'SortOrder'
+ $end 'SortOrder'
+ LegacySolverPinOrdering=false
+ $end 'Port'
+ $begin 'Boundary'
+ $begin 'Data'
+ $end 'Data'
+ $begin 'CoupledPortsList'
+ $end 'CoupledPortsList'
+ $begin 'DiffPairs'
+ $end 'DiffPairs'
+ TotalVoltage=false
+ IncludePortPostProcess=true
+ $begin 'SortOrder'
+ $end 'SortOrder'
+ LegacySolverPinOrdering=false
+ $end 'Boundary'
+ $begin 'Cavity'
+ $begin 'Data'
+ $end 'Data'
+ $end 'Cavity'
+ $begin 'Via'
+ $begin 'Data'
+ $end 'Data'
+ $end 'Via'
+ $begin 'LayoutVia'
+ $begin 'Data'
+ $end 'Data'
+ $end 'LayoutVia'
+ $begin 'Source'
+ $begin 'Data'
+ $end 'Data'
+ $end 'Source'
+ $begin 'Voltage Probe'
+ $begin 'Data'
+ $end 'Data'
+ $end 'Voltage Probe'
+ $begin 'DC Terminal'
+ $begin 'Data'
+ $end 'Data'
+ $end 'DC Terminal'
+ $begin 'CircuitSources'
+ $begin 'Data'
+ $end 'Data'
+ $end 'CircuitSources'
+ $begin 'NexximPorts'
+ $begin 'Data'
+ $end 'Data'
+ $begin 'DiffPairs'
+ $end 'DiffPairs'
+ $end 'NexximPorts'
+ $begin 'SortOrder'
+ $end 'SortOrder'
+ $begin 'NexximMultiComponentContainers'
+ $begin 'Data'
+ $end 'Data'
+ $end 'NexximMultiComponentContainers'
+ $begin 'ComponentConfigurationData'
+ $begin 'EnabledPorts'
+ $end 'EnabledPorts'
+ $begin 'EnabledMultipleComponents'
+ $end 'EnabledMultipleComponents'
+ $begin 'EnabledAnalyses'
+ $end 'EnabledAnalyses'
+ $end 'ComponentConfigurationData'
+ $begin 'Properties'
+ $end 'Properties'
+ $begin 'CustomSimSetups'
+ $begin 'Data'
+ $end 'Data'
+ $end 'CustomSimSetups'
+ $begin 'RadSetup'
+ $begin 'Data'
+ $end 'Data'
+ $end 'RadSetup'
+ $begin 'Setup'
+ $begin 'Data'
+ $end 'Data'
+ $end 'Setup'
+ $begin 'AnalysisOptionBlocks'
+ $end 'AnalysisOptionBlocks'
+ $begin 'EM properties'
+ $begin 'Data'
+ $end 'Data'
+ $end 'EM properties'
+ $begin 'OutputVariable'
+ NextUniqueID=0
+ MoveBackwards=false
+ $end 'OutputVariable'
+ $begin 'Optimetrics'
+ $begin 'OptimetricsSetups'
+ NextUniqueID=0
+ MoveBackwards=false
+ $end 'OptimetricsSetups'
+ $end 'Optimetrics'
+ $begin 'FieldsReporter'
+ $begin 'FieldsCalculator'
+ Line_Discretization=1000
+ 'Show Stack'=true
+ $end 'FieldsCalculator'
+ $begin 'PlotDefaults'
+ Default_SolutionId=-1
+ Default_PlotFolder='Automatic'
+ $end 'PlotDefaults'
+ $begin 'FieldsPlotManagerID'
+ NextUniqueID=0
+ MoveBackwards=false
+ NumQuantityType=0
+ NumPlots=0
+ $end 'FieldsPlotManagerID'
+ $begin 'Report3dInGeomWnd'
+ Report3dNum=0
+ $end 'Report3dInGeomWnd'
+ $begin 'Report2dInGeomWnd'
+ Report2dNum=0
+ $end 'Report2dInGeomWnd'
+ $begin 'AntennaParametersInGeomWnd'
+ AntennaParametersNum=0
+ $end 'AntennaParametersInGeomWnd'
+ AntennaParametersPlotTablesOrder()
+ $begin 'EntitySelectionCache'
+ $end 'EntitySelectionCache'
+ $end 'FieldsReporter'
+ $begin 'SolutionManager'
+ $begin 'SimDataExtractors'
+ $begin 'Version ID Map'
+ V=0
+ $end 'Version ID Map'
+ $end 'SimDataExtractors'
+ $end 'SolutionManager'
+ $begin 'InterfaceOptions'
+ SchematicEnabled=false
+ SaveBeforeSolving=true
+ $end 'InterfaceOptions'
+ $begin 'AdvancedSettings'
+ ComputeBothEvenAndOddCPWModes=false
+ CausalMaterials=true
+ MeshingMethod='Phi'
+ EnableDesignIntersectionCheck=true
+ UseAlternativeMeshMethodsAsFallBack=true
+ CircuitSparamDefinition=false
+ CircuitIntegrationType='FFT'
+ BroadbandFreqOption='AutoMaxFreq'
+ BroadbandMaxNumFreq=5
+ SaveADP=false
+ UseAdvancedDCExtrap=false
+ ModeOption='General mode'
+ PhiMesherDeltaZRatio=100000
+ SpiceType='TouchStone1.0'
+ EnforcePassivity=false
+ EnforceCausality=false
+ UseCommonGround=true
+ ShowGammaComments=false
+ Renormalize=true
+ RenormImpedance=50
+ FittingError=0.5
+ MaxPoles=10000
+ PassivityType='IteratedFittingOfPV'
+ ColumnFittingType='Matrix'
+ SSFittingType='FastFit'
+ RelativeErrorToleranc=false
+ EnsureAccurateZfit=true
+ TouchstoneFormat='MA'
+ TouchstoneUnits='GHz'
+ TouchStonePrecision=15
+ ExportAfterSolve=false
+ ExportDir=''
+ $end 'AdvancedSettings'
+ $begin 'CoSimOptions'
+ Override=false
+ Setup=''
+ OverrideSweep=false
+ Sweep=''
+ FrequencySweepType=0
+ Interpolate=false
+ YMatrix=true
+ AutoAlignPorts=false
+ Simulator=1
+ InterpAlg='auto'
+ Renormalize=false
+ RenormImpedance=50
+ $end 'CoSimOptions'
+ $begin 'TemperatureData'
+ IncludeTempDependence=false
+ EnableFeedback=false
+ Temperature='22cel'
+ $end 'TemperatureData'
+ $begin 'UserDefinedSolutionMgr'
+ NextUniqueID=1000000
+ MoveBackwards=false
+ $end 'UserDefinedSolutionMgr'
+ $begin 'DatasetSolutionMgr'
+ NextUniqueID=2000000
+ MoveBackwards=false
+ $end 'DatasetSolutionMgr'
+ Notes=$begin_cdata$ $end_cdata$
+ $begin 'AnimationSetups'
+ $end 'AnimationSetups'
+ CacheHeaderFile='HDR6CBA363617189547153.tmp'
+ $end 'PlanarEMCircuit'
+ $begin 'DataInstances'
+ DesignEditor='TopLevel'
+ Refdes('0', 'U1')
+ $begin 'CompInstances'
+ $begin 'Compinst'
+ ID='0'
+ Status='Status'
+ CompName='main'
+ GatesInUse()
+ $begin 'Properties'
+ TextProp('ID', 'SRID', '', '0')
+ $end 'Properties'
+ $begin 'Parameters'
+ MenuProp('CoSimulator', 'OHD', '', 'DefaultNetlist', 0)
+ ButtonProp('CosimDefinition', 'OHD', '', 'Edit', 'Edit', 40501, ButtonPropClientData())
+ $end 'Parameters'
+ $end 'Compinst'
+ $end 'CompInstances'
+ $begin 'Instance'
+ DesignEditor='main'
+ ID='0'
+ $begin 'PlanarEMItem'
+ Editor3D=true
+ $begin 'PostProcessing'
+ DesignInstanceID=1
+ $begin 'WindowPosition'
+ $begin 'EditorWindow'
+ Circuit(Layout(View(WindowPos(3, -1, -1, -16, -72, 0, 0, 324, 88), Extent(-3.06630444526672, -1, 3.06630444526672, 1, 14294.3901877805, 14289.1680718094, -0.0477049872279167, 0.0901622250676155, 0.230649910867214, 0.104624703526497, 1), ViewingXfm(-2.20454549789429, 2.20454549789429, -1, 1, 255.771438598633, 273.350341796875, 19.1159439086914, 0, 0, 0, 0, 19.1159439086914, 0, 0, 0, 0, 19.1159439086914, 0, -1.29261958599091, -0.72353607416153, -264.577545166016, 1))), Layout())
+ $end 'EditorWindow'
+ $end 'WindowPosition'
+ $begin 'ReportSetup'
+ $begin 'ReportManager'
+ $begin 'Reports'
+ $end 'Reports'
+ NextUniqueID=0
+ MoveBackwards=false
+ $begin 'NextVersID'
+ NextUniqueID=0
+ MoveBackwards=false
+ $end 'NextVersID'
+ $end 'ReportManager'
+ $begin 'Reports'
+ $end 'Reports'
+ $begin 'ReportsWindowInfoList'
+ $end 'ReportsWindowInfoList'
+ $end 'ReportSetup'
+ $end 'PostProcessing'
+ $begin 'Properties'
+ $end 'Properties'
+ $begin 'UserDefinedDocument'
+ $begin 'Data'
+ $end 'Data'
+ $end 'UserDefinedDocument'
+ $end 'PlanarEMItem'
+ $begin 'TopLayout'
+ DefaultUnits='mm'
+ DefaultAngleUnits='deg'
+ MajorSize='10mm'
+ MinorSize='1mm'
+ PixelSnapTolerance=20
+ SnapAcrossHierarchy=true
+ SnapTargetVertex_on=true
+ SnapTargetEdgeCenter_on=true
+ SnapTargetObjCenter_on=true
+ SnapTargetEdge_on=false
+ SnapTargetElecConnection_on=true
+ SnapTargetIntersection_on=false
+ SnapTargetGrid_on=true
+ SnapSourceVertex_on=true
+ SnapSourceEdgeCenter_on=true
+ SnapSourceObjCenter_on=true
+ SnapSourceEdge_on=false
+ SnapSourceElecConnection_on=true
+ ConstrainToGrid=false
+ DirectionConstraint=0
+ defaultholesize='25mil'
+ anglesnap='5deg'
+ $begin 'NamingConvention'
+ OptionUseNamingConvention_PadPort=false
+ OptionNamingConvention_PadPort='$REFDES_$PINNAME_$NETNAME'
+ OptionUseNamingConvention_EdgePort=false
+ OptionNamingConvention_EdgePort='$NETNAME'
+ OptionUseNamingConvention_PointPort=false
+ OptionNamingConvention_PointPort='$POSTERM_LAYER_$NEGTERM_LAYER'
+ OptionUseNamingConvention_PinGroup=false
+ OptionNamingConvention_PinGroup='$REFDES_GROUP_$NETNAME'
+ OptionUseNamingConvention_PinGroupPort=false
+ OptionNamingConvention_PinGroupPort='$REFDES_$GROUPNAME_$NETNAME'
+ OptionUseNamingConvention_PointISource=false
+ OptionNamingConvention_PointISource='I_$POSTERM_NETNAME'
+ OptionUseNamingConvention_PointVSource=false
+ OptionNamingConvention_PointVSource='V_$POSTERM_NETNAME'
+ OptionUseNamingConvention_PointVProbe=false
+ OptionNamingConvention_PointVProbe='VP_$POSTERM_NETNAME'
+ OptionUseNamingConvention_PointDCTerm=false
+ OptionNamingConvention_PointDCTerm='DCT_$NETNAME'
+ OptionUseNamingConvention_PinISource=false
+ OptionNamingConvention_PinISource='I_$REFDES_$NETNAME'
+ OptionUseNamingConvention_PinVSource=false
+ OptionNamingConvention_PinVSource='V_$REFDES_$NETNAME'
+ OptionUseNamingConvention_PinVProbe=false
+ OptionNamingConvention_PinVProbe='VP_$REFDES_$NETNAME'
+ OptionUseNamingConvention_PinDCTerm=false
+ OptionNamingConvention_PinDCTerm='DCT_$REFDES_$NETNAME'
+ OptionUseNamingConvention_GroupISource=false
+ OptionNamingConvention_GroupISource='I_$REFDES_$NETNAME'
+ OptionUseNamingConvention_GroupVSource=false
+ OptionNamingConvention_GroupVSource='V_$REFDES_$NETNAME'
+ OptionUseNamingConvention_GroupVProbe=false
+ OptionNamingConvention_GroupVProbe='VP_$REFDES_$NETNAME'
+ OptionUseNamingConvention_GroupDCTerm=false
+ OptionNamingConvention_GroupDCTerm='DCT_$REFDES_$NETNAME'
+ OptionUseNamingConvention_NCPortInstPort=false
+ OptionNamingConvention_NCPortInstPort='$REFDES_$PORTNAME_$TERMNAME'
+ $end 'NamingConvention'
+ $begin 'TextStyles'
+ TextStyle(N='', F='Arial', Hght=12, Scale=false)
+ TextStyle(N='', Plot=true, F='RomanSimplex', Hght=5, HghtUnt='mm')
+ TextStyle(N='', Plot=true, F='RomanSimplex', Hght=1, HghtUnt='mm')
+ $end 'TextStyles'
+ $begin 'TraceStyles'
+ TraceStyle(name='Half Grid', size='0.5mm', bendStyle=0, capStyle=0, capStyle=0)
+ TraceStyle(name='1 Grid', size='1mm', bendStyle=0, capStyle=0, capStyle=0)
+ TraceStyle(name='2 Grids', size='2mm', bendStyle=0, capStyle=0, capStyle=0)
+ TraceStyle(name='5 Grids', size='5mm', bendStyle=0, capStyle=0, capStyle=0)
+ $end 'TraceStyles'
+ 'current via style'='PlanarEMVia'
+ 'current pin style'=''
+ MajorColor=14599364
+ MinorColor=15391450
+ ShowGrid=true
+ PageExtent(-0.1, -0.1, 0.1, 0.1)
+ 'background color'=16777215
+ DefaultToSketchMode=true
+ fillMode=false
+ DocVisibilityFlag=962
+ FastViewTransforms=true
+ StartingHierarchyLevel=0
+ EndingHierarchyLevel=-1
+ SingleLevelView=false
+ DesignMode=1
+ Is2dRendering=false
+ 'show connection points'=false
+ 'draw rats'=false
+ 'display vertex labels'=false
+ ColorByNet=false
+ 'display package graphics'=false
+ 'rectangle description'=0
+ snaptoport=true
+ autoplacecomp=false
+ AutoScale=true
+ 'measure display digits'=3
+ 'display measure units'=false
+ SuppressPads=true
+ AntiPadsOption=0
+ TextIsVisible=true
+ 'primary selection color'=255
+ 'secondary selection color'=3289780
+ 'preview selection'=false
+ AllowDragOnFirstClick=false
+ PinConnectivityPopup=false
+ CreatePortsOnComp=false
+ OptionUseNamingConvention_PadPort=false
+ OptionNamingConvention_PadPort='$REFDES_$PINNAME_$NETNAME'
+ OptionUseNamingConvention_EdgePort=false
+ OptionNamingConvention_EdgePort='$NETNAME'
+ OptionUseNamingConvention_PointPort=false
+ OptionNamingConvention_PointPort='$POSTERM_LAYER_$NEGTERM_LAYER'
+ OptionUseNamingConvention_PinGroup=false
+ OptionNamingConvention_PinGroup='$REFDES_GROUP_$NETNAME'
+ OptionUseNamingConvention_PinGroupPort=false
+ OptionNamingConvention_PinGroupPort='$REFDES_$GROUPNAME_$NETNAME'
+ OptionUseNamingConvention_PointISource=false
+ OptionNamingConvention_PointISource='I_$POSTERM_NETNAME'
+ OptionUseNamingConvention_PointVSource=false
+ OptionNamingConvention_PointVSource='V_$POSTERM_NETNAME'
+ OptionUseNamingConvention_PointVProbe=false
+ OptionNamingConvention_PointVProbe='VP_$POSTERM_NETNAME'
+ OptionUseNamingConvention_PointDCTerm=false
+ OptionNamingConvention_PointDCTerm='DCT_$NETNAME'
+ OptionUseNamingConvention_PinISource=false
+ OptionNamingConvention_PinISource='I_$REFDES_$NETNAME'
+ OptionUseNamingConvention_PinVSource=false
+ OptionNamingConvention_PinVSource='V_$REFDES_$NETNAME'
+ OptionUseNamingConvention_PinVProbe=false
+ OptionNamingConvention_PinVProbe='VP_$REFDES_$NETNAME'
+ OptionUseNamingConvention_PinDCTerm=false
+ OptionNamingConvention_PinDCTerm='DCT_$REFDES_$NETNAME'
+ OptionUseNamingConvention_GroupISource=false
+ OptionNamingConvention_GroupISource='I_$REFDES_$NETNAME'
+ OptionUseNamingConvention_GroupVSource=false
+ OptionNamingConvention_GroupVSource='V_$REFDES_$NETNAME'
+ OptionUseNamingConvention_GroupVProbe=false
+ OptionNamingConvention_GroupVProbe='VP_$REFDES_$NETNAME'
+ OptionUseNamingConvention_GroupDCTerm=false
+ OptionNamingConvention_GroupDCTerm='DCT_$REFDES_$NETNAME'
+ OptionUseNamingConvention_NCPortInstPort=false
+ OptionNamingConvention_NCPortInstPort='$REFDES_$PORTNAME_$TERMNAME'
+ useFixedDrawingResolution=false
+ DrawingResolution='0.002mm'
+ $begin 'ViewConfigs'
+ ViewConfigsCurrent=''
+ $end 'ViewConfigs'
+ currentTextStyle=0
+ currentTraceStyle=0
+ prevBounds(-3.06630444526672, -1, 3.06630444526672, 1)
+ prevMapFactor(14294.3901877805, 14289.1680718094)
+ prevOrigin(-0.0477049872279167, 0.0901622250676155)
+ prevViewExtent(0.230649910867214, 0.104624703526497)
+ prevZoomScale=1
+ $begin 'Animation'
+ LabelColor(R=230, G=230, B=230)
+ FontName='Arial'
+ FontHeight=60
+ FontWeight=400
+ $end 'Animation'
+ $end 'TopLayout'
+ $end 'Instance'
+ $begin 'SODInfo'
+ $begin 'CAPC0603X33X15LL03T05'
+ $begin 'CosimDefinition'
+ CosimDefName='DefaultNetlist'
+ $begin 'SODInstanceMap'
+ $end 'SODInstanceMap'
+ SODComponentList()
+ $end 'CosimDefinition'
+ $end 'CAPC0603X33X15LL03T05'
+ $begin 'CAPC1005X05N'
+ $begin 'CosimDefinition'
+ CosimDefName='DefaultNetlist'
+ $begin 'SODInstanceMap'
+ $end 'SODInstanceMap'
+ SODComponentList()
+ $end 'CosimDefinition'
+ $end 'CAPC1005X05N'
+ $begin 'CAPC1005X33X10LL5'
+ $begin 'CosimDefinition'
+ CosimDefName='DefaultNetlist'
+ $begin 'SODInstanceMap'
+ $end 'SODInstanceMap'
+ SODComponentList()
+ $end 'CosimDefinition'
+ $end 'CAPC1005X33X10LL5'
+ $begin 'CAPC1005X55X10LL05'
+ $begin 'CosimDefinition'
+ CosimDefName='DefaultNetlist'
+ $begin 'SODInstanceMap'
+ $end 'SODInstanceMap'
+ SODComponentList()
+ $end 'CosimDefinition'
+ $end 'CAPC1005X55X10LL05'
+ $begin 'CAPC1005X55X23ML05T8'
+ $begin 'CosimDefinition'
+ CosimDefName='DefaultNetlist'
+ $begin 'SODInstanceMap'
+ $end 'SODInstanceMap'
+ SODComponentList()
+ $end 'CosimDefinition'
+ $end 'CAPC1005X55X23ML05T8'
+ $begin 'CAPC1005X55X25LL05T10'
+ $begin 'CosimDefinition'
+ CosimDefName='DefaultNetlist'
+ $begin 'SODInstanceMap'
+ $end 'SODInstanceMap'
+ SODComponentList()
+ $end 'CosimDefinition'
+ $end 'CAPC1005X55X25LL05T10'
+ $begin 'CAPC1005X55X25ML05T10'
+ $begin 'CosimDefinition'
+ CosimDefName='DefaultNetlist'
+ $begin 'SODInstanceMap'
+ $end 'SODInstanceMap'
+ SODComponentList()
+ $end 'CosimDefinition'
+ $end 'CAPC1005X55X25ML05T10'
+ $begin 'CAPC1005X55X25NL05T10'
+ $begin 'CosimDefinition'
+ CosimDefName='DefaultNetlist'
+ $begin 'SODInstanceMap'
+ $end 'SODInstanceMap'
+ SODComponentList()
+ $end 'CosimDefinition'
+ $end 'CAPC1005X55X25NL05T10'
+ $begin 'CAPC1608X08N'
+ $begin 'CosimDefinition'
+ CosimDefName='DefaultNetlist'
+ $begin 'SODInstanceMap'
+ $end 'SODInstanceMap'
+ SODComponentList()
+ $end 'CosimDefinition'
+ $end 'CAPC1608X08N'
+ $begin 'CAPC1608X90X35ML10T15'
+ $begin 'CosimDefinition'
+ CosimDefName='DefaultNetlist'
+ $begin 'SODInstanceMap'
+ $end 'SODInstanceMap'
+ SODComponentList()
+ $end 'CosimDefinition'
+ $end 'CAPC1608X90X35ML10T15'
+ $begin 'CAPC2012X12N'
+ $begin 'CosimDefinition'
+ CosimDefName='DefaultNetlist'
+ $begin 'SODInstanceMap'
+ $end 'SODInstanceMap'
+ SODComponentList()
+ $end 'CosimDefinition'
+ $end 'CAPC2012X12N'
+ $begin 'CAPC2013X100X20NL20'
+ $begin 'CosimDefinition'
+ CosimDefName='DefaultNetlist'
+ $begin 'SODInstanceMap'
+ $end 'SODInstanceMap'
+ SODComponentList()
+ $end 'CosimDefinition'
+ $end 'CAPC2013X100X20NL20'
+ $begin 'CAPC3216X180X20ML20'
+ $begin 'CosimDefinition'
+ CosimDefName='DefaultNetlist'
+ $begin 'SODInstanceMap'
+ $end 'SODInstanceMap'
+ SODComponentList()
+ $end 'CosimDefinition'
+ $end 'CAPC3216X180X20ML20'
+ $begin 'CAPC3216X180X55ML20T25'
+ $begin 'CosimDefinition'
+ CosimDefName='DefaultNetlist'
+ $begin 'SODInstanceMap'
+ $end 'SODInstanceMap'
+ SODComponentList()
+ $end 'CosimDefinition'
+ $end 'CAPC3216X180X55ML20T25'
+ $begin 'CAPC3216X190X55ML30T25'
+ $begin 'CosimDefinition'
+ CosimDefName='DefaultNetlist'
+ $begin 'SODInstanceMap'
+ $end 'SODInstanceMap'
+ SODComponentList()
+ $end 'CosimDefinition'
+ $end 'CAPC3216X190X55ML30T25'
+ $begin 'CAPMP7343X31N'
+ $begin 'CosimDefinition'
+ CosimDefName='DefaultNetlist'
+ $begin 'SODInstanceMap'
+ $end 'SODInstanceMap'
+ SODComponentList()
+ $end 'CosimDefinition'
+ $end 'CAPMP7343X31N'
+ $begin 'COIL-1008CS_V'
+ $begin 'CosimDefinition'
+ CosimDefName='DefaultNetlist'
+ $begin 'SODInstanceMap'
+ $end 'SODInstanceMap'
+ SODComponentList()
+ $end 'CosimDefinition'
+ $end 'COIL-1008CS_V'
+ $begin 'MURA-BLM15-CHIP-2_V'
+ $begin 'CosimDefinition'
+ CosimDefName='DefaultNetlist'
+ $begin 'SODInstanceMap'
+ $end 'SODInstanceMap'
+ SODComponentList()
+ $end 'CosimDefinition'
+ $end 'MURA-BLM15-CHIP-2_V'
+ $begin 'MURA-BLM15AG221SN1x_V'
+ $begin 'CosimDefinition'
+ CosimDefName='DefaultNetlist'
+ $begin 'SODInstanceMap'
+ $end 'SODInstanceMap'
+ SODComponentList()
+ $end 'CosimDefinition'
+ $end 'MURA-BLM15AG221SN1x_V'
+ $begin 'RESC1005X35X25NL8T10'
+ $begin 'CosimDefinition'
+ CosimDefName='DefaultNetlist'
+ $begin 'SODInstanceMap'
+ $end 'SODInstanceMap'
+ SODComponentList()
+ $end 'CosimDefinition'
+ $end 'RESC1005X35X25NL8T10'
+ $begin 'RESC1005X40X25LL05T05'
+ $begin 'CosimDefinition'
+ CosimDefName='DefaultNetlist'
+ $begin 'SODInstanceMap'
+ $end 'SODInstanceMap'
+ SODComponentList()
+ $end 'CosimDefinition'
+ $end 'RESC1005X40X25LL05T05'
+ $begin 'RESC1005X40X25ML05T05'
+ $begin 'CosimDefinition'
+ CosimDefName='DefaultNetlist'
+ $begin 'SODInstanceMap'
+ $end 'SODInstanceMap'
+ SODComponentList()
+ $end 'CosimDefinition'
+ $end 'RESC1005X40X25ML05T05'
+ $begin 'RESC1005X40X25NL05T05'
+ $begin 'CosimDefinition'
+ CosimDefName='DefaultNetlist'
+ $begin 'SODInstanceMap'
+ $end 'SODInstanceMap'
+ SODComponentList()
+ $end 'CosimDefinition'
+ $end 'RESC1005X40X25NL05T05'
+ $begin 'RESC1005X40X25NL5T10'
+ $begin 'CosimDefinition'
+ CosimDefName='DefaultNetlist'
+ $begin 'SODInstanceMap'
+ $end 'SODInstanceMap'
+ SODComponentList()
+ $end 'CosimDefinition'
+ $end 'RESC1005X40X25NL5T10'
+ $begin 'RESC1608X05N'
+ $begin 'CosimDefinition'
+ CosimDefName='DefaultNetlist'
+ $begin 'SODInstanceMap'
+ $end 'SODInstanceMap'
+ SODComponentList()
+ $end 'CosimDefinition'
+ $end 'RESC1608X05N'
+ $begin 'SMD-0603'
+ $begin 'CosimDefinition'
+ CosimDefName='DefaultNetlist'
+ $begin 'SODInstanceMap'
+ $end 'SODInstanceMap'
+ SODComponentList()
+ $end 'CosimDefinition'
+ $end 'SMD-0603'
+ $begin 'WE-Coil-744301047'
+ $begin 'CosimDefinition'
+ CosimDefName='DefaultNetlist'
+ $begin 'SODInstanceMap'
+ $end 'SODInstanceMap'
+ SODComponentList()
+ $end 'CosimDefinition'
+ $end 'WE-Coil-744301047'
+ $begin 'WE-Coil-PD4-S'
+ $begin 'CosimDefinition'
+ CosimDefName='DefaultNetlist'
+ $begin 'SODInstanceMap'
+ $end 'SODInstanceMap'
+ SODComponentList()
+ $end 'CosimDefinition'
+ $end 'WE-Coil-PD4-S'
+ $begin 'main'
+ $begin 'CosimDefinition'
+ CosimDefName='DefaultNetlist'
+ $begin 'SODInstanceMap'
+ $end 'SODInstanceMap'
+ SODComponentList()
+ $end 'CosimDefinition'
+ $end 'main'
+ $end 'SODInfo'
+ $end 'DataInstances'
+ $begin 'WBSystemIDToDesignInstanceIDMap'
+ $end 'WBSystemIDToDesignInstanceIDMap'
+ $begin 'WBSysIDSysDetails'
+ $end 'WBSysIDSysDetails'
+ $begin 'WBConnIDConnDetails'
+ $end 'WBConnIDConnDetails'
+ $begin 'WBMaterialGuidDetails'
+ WBMaterialGuidMap()
+ $end 'WBMaterialGuidDetails'
+ $begin 'MinervaProjectSettingsBlk'
+ MinervaRemoteFilePath=''
+ FolderContainerString=''
+ $end 'MinervaProjectSettingsBlk'
+$end 'AnsoftProject'
+$begin 'AllReferencedFilesForProject'
+$end 'AllReferencedFilesForProject'
+$begin 'ProjectPreview'
+ IsEncrypted=false
+ Thumbnail64='/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQE\
+BAQICAQECAQEBAgICAgICAgICAQICAgICAgICAgL/2wBDAQEBAQEBAQEBAQECAQEBAgICAgICAgICAg\
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgL/wAARCABgAGADASIAAhEBAxEB/\
+8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQR\
+BRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUp\
+TVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5us\
+LDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAA\
+AECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHB\
+CSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ\
+3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4u\
+Pk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD+q/xDoGhQaFrlzDoukw3EOk6nPFcRadZxzRTR2\
+c8kc0cqQhklVwGDAggjIOa1v+EZ8Of9C/on/gqsP/kesnxDotnDoWuXCTasZItJ1OZVl1/XZ4S6Wc7g\
+SW02otHNFkDKOjIwyrKVJFa3/CP2H/Pxrf8A4U3iP/5a197bV+6n/W+2/wDkvlzmR4f8P6DcaDolxca\
+JpE88+kabNNNNptnLLNLLZwvJLLI8JMkjOzFmJJJJJOaNE8P6DPZzPNomkTOur+IIVeXTbORhFb69qV\
+vbxBnhJEaQRRoi9FSNVUAACjw/olnPoOiTPNq6vNpGmyusPiDXreINJZwuwit7fUljgjyTtRFVFGFVQ\
+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'
+ $begin 'DesignInfo'
+ DesignName='main'
+ Notes=''
+ Factory='HFSS 3D Layout Design'
+ IsSolved=false
+ 'Nominal Setups'[0:]
+ 'Nominal Setup Types'[0:]
+ 'Optimetrics Setups'[0:]
+ 'Optimetrics Experiment Types'[0:]
+ Image64='/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQE\
+BAQICAQECAQEBAgICAgICAgICAQICAgICAgICAgL/2wBDAQEBAQEBAQEBAQECAQEBAgICAgICAgICAg\
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgL/wAARCADIAMgDASIAAhEBAxEB/\
+8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQR\
+BRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUp\
+TVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5us\
+LDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAA\
+AECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHB\
+CSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ\
+3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4u\
+Pk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD+w698I6Av9oZ8KaOu3+1858LWUe3Z/wALCzn/A\
+ItzD5e37PJn/UbPsp/49fsx/sPL8U+FtFttF8TzweGNLt57fS/E8sM0Xhi0glglgtPiQ6SRunw3iMEi\
+PbMQQITGbMkC2Nt/xI+svbLb9v8A9A2bP7W/5hPl7PL/AOE//wCpAh8rb9k/6YeX9h/5dfsv/Eix/F1\
+lt0DxWP7P27dH8UjH9kbNvl2XxG4x/wAK9j8vb9k6bYtn2LpbfZcaH9lFtSi07NNHOFt4R0A312o8Ka\
+OxHiXUYyv/AAi1k5Vl8ReEIzCY/wDhXMmxg0qJ5XkxbTOIv7Pg84WGqFl4R0Bv7Px4U0dt39kYx4Wsp\
+N2//hXuMf8AFuZvM3faI8f6/f8Aah/x9faR/bmxbWW69u1+wbtviPUIdn9k79uzxB4Sh+z+X/wgEmzb\
+9o2eT5MWz7V5X9nwef8AYNULKy3fYP8AQN+/+yf+YT5m/wAz/hAP+pAm83d9r/6b+Z9u/wCXr7V/xPV\
+d9wOT0Lwtos13eJJ4Y0uVItU0KK3V/DFpKqRSaL8JZ/LhDfDeUGNp753wv2gSPfls3RuiNbdZ+E/D50\
+eFx4X0ZgdNuW8weG7JwQLXx6S/n/8ACEy7gBA53/anx9lJ+0R/ZzJoul4fst17qX/Ev3eZrGhH/kEb/\
+M8zQPhGM5/4V7L5277X1zc7/tuM3X2rbrc9na7tIhk+yb86bcv5v9neZnba+O28zz/+EPl3Y+yZ3/an\
+x9i3faI/s3maJbb5W76rl/J/5L7kBia74W0WG7s0j8MaXEkuqa7FcKnhi0iV4o9F+LU/lzBfhvEBGs9\
+ij4b7OI3sA2bU2oGialz4R0AX1op8KaOpPiXT4wv/AAi1khZm8ReL4xD5f/CuY97FonTyvJl3GAxf2f\
+P5JsNLPEFltvdN/wCJft8vWNdP/II2eX5egfFwZz/wr2Lydv2Trm22fYsZtfsu3RNi5stt7aL9g27vE\
+enw7P7J2bt/iDxbD9n8v/hAI9+77Ps8nyZd/wBl8r+z5/I+waXF3pq9NvIDHsvCOgN/Z+PCmjtu/sjG\
+PC1lJu3/APCvcY/4tzN5m77RHj/X7/tQ/wCPr7SP7cy/C3hbRbnRfDE8/hjS7ie40vwxLNNL4YtJ5Z5\
+Z7T4bu8kjv8N5TPI73KkkiYyG8BIuTc/8TzrLKy3fYP8AQN+/+yf+YT5m/wAz/hAP+pAm83d9r/6b+Z\
+9u/wCXr7V/xPcfwjZbtA8KD+z927R/Cwx/ZG/d5ll8OeMf8K9k8zd9r6bZd/23pc/asa4XdrXdv8tgM\
+2Lwn4fMd8f+EX0Y7dN0lif+EbsjtD+BdZnDk/8ACEt5YZEMu/dDvEZuPtFyE/tm0bceFtF/trX4G8Ma\
+WIIdL81IW8MWiRQyvd/F5LiREPw3hEMhSwjDkGEqNPUMLQWg/sTbitcx3x+yZ2abpT5/s7ds8zwRrF1\
+5mf8AhD28vd5fnb90O/yvtP2i58v+2bSCay26/wCIj/Z+zbo8Iz/ZHl7PKvfjDxn/AIV7D5ez7J03Q+\
+X9i6Wf2bOiW21ezt7q/wDbQC98I6Av9oZ8KaOu3+1858LWUe3Z/wALCzn/AItzD5e37PJn/UbPsp/49\
+fsx/sPLvvC2ixPMYPDGlxyf8JxaWzeV4YtN4SXx54BtLi1ZE+G8pVGiumieHyYgFuzC1hbif7FqfWXt\
+lt+3/wCgbNn9rf8AMJ8vZ5f/AAn/AP1IEPlbfsn/AEw8v7D/AMuv2X/iRY+p2W4yJ/Z+/b4702HZ/ZH\
+mbfL+IHw/i8jyv+FezeXt+0bPK8iLZ9p8r7Bbef8AYtTmLalFp2aaALLwjoDf2fjwpo7bv7IxjwtZSb\
+t//CvcY/4tzN5m77RHj/X7/tQ/4+vtI/tzNvPCfh8aPM58L6MoGm2zeYfDdkgANr4CIfz/APhCYtoIn\
+Q7/ALUmftQP2iT7QJNa6qyst32D/QN+/wDsn/mE+Zv8z/hAP+pAm83d9r/6b+Z9u/5evtX/ABPc68td\
+ukTSfZNmNNtn83+zvLxutfAjeZ5//CHxbc/a87/tSZ+27vtEn2nzNbIfFH1QGJa+FtFltNVefwxpbum\
+qeM4g0vhi0DRxWutfFKCGMF/hvAYo4oLMIo/ciJLHaDbC1zoepe+EdAX+0M+FNHXb/a+c+FrKPbs/4W\
+FnP/FuYfL2/Z5M/wCo2fZT/wAev2Y/2GafZbLLVv8AiX7NmseOD/yCPK2bNf8Aikc4/wCFeweVt+ydc\
+Q7PsWc2/wBl3aHsXtlt+3/6Bs2f2t/zCfL2eX/wn/8A1IEPlbfsn/TDy/sP/Lr9l/4kSbbbbbbYHJ6z\
+4W0WLWfDEUfhjS4lufHFpbTxJ4YtI1uENx8RnW1liX4bp5yG5s48QmGQM9mEFhO1uNP0zUsvCOgN/Z+\
+PCmjtu/sjGPC1lJu3/wDCvcY/4tzN5m77RHj/AF+/7UP+Pr7SP7cNcssa14TX+z8Z8d20Oz+yNud5+J\
+MHkeX/AMK9Tdu+z+X5XlPv+zeT9guPI/s/TNiyst32D/QN+/8Asn/mE+Zv8z/hAP8AqQJvN3fa/wDpv\
+5n27/l6+1f8T0u9NXpt5AY9l4R0Bv7Px4U0dt39kYx4WspN2/8A4V7jH/FuZvM3faI8f6/f9qH/AB9f\
+aR/bnM+HvDGiXGg208/hvSp55PDPhqeeabw7aSyvJP8ADvVLp55pH8Dkh32vMZGMBk2G5M9zsOsWnfW\
+Vlu+wf6Bv3/2T/wAwnzN/mf8ACAf9SBN5u77X/wBN/M+3f8vX2r/ie8t4Ztf+KcsP9D+54V8Lv/yDf9\
+Xv+HepXW//AJE39zu8rzt3+j7/ACvtPn3Hl/2xaVFvlmr6WT+aaA0b3wjoC/2hnwpo67f7XznwtZR7d\
+n/Cws5/4tzD5e37PJn/AFGz7Kf+PX7Mf7Dy7jwtov8AbWvwN4Y0sQQ6X5qQt4YtEihle7+LyXEiIfhv\
+CIZClhGHIMJUaeoYWgtB/YnWXtlt+3/6Bs2f2t/zCfL2eX/wn/8A1IEPlbfsn/TDy/sP/Lr9l/4kWPN\
+Zbdf8RH+z9m3R4Rn+yPL2eVe/GHjP/CvYfL2fZOm6Hy/sXSz+zZ0RJu0ten6r/JAFl4R0Bv7Px4U0dt\
+39kYx4WspN2/8A4V7jH/FuZvM3faI8f6/f9qH/AB9faR/bhWxZWW77B/oG/f8A2T/zCfM3+Z/wgH/Ug\
+Tebu+1/9N/M+3f8vX2r/ielc9aUly2k1vs/QqO/9d0ctdWetj7ZjxD4VbH9pbdng7wqm7H/AAmWzZ9l\
+8dN5e7y4Nvk7tn2qD7Nv+z6L9pyvE9pqy6J4kM2veGZoF0rxEZY4PCXhC2kmhW08cFkglj8aypbu6Rw\
+iNkSVYzdwGBZRb6MLrvr293fb/wDT9+/+1v8AmLeZv8z/AIT/AP6n+bzd32v/AKb+Z9u/5evtX/E9x/\
+F17u0DxWf7Q3btH8UnP9r793mWXxG5z/wsKTzN32vrul3/AG3rc/as651Rm7rRb/yx/wAiTOgs9bN3c\
+A+IfCqqNcvVDN4O8KsjRjWvDarMqT+OhEkBjeV1jjZrFUgljhlayl1KWEtbPWz9jz4h8Krn+zd2/wAH\
+eFX25/4Q3fv+1eOl8zb5k+7ztu/7LP8Aadn2jWvs3U217tvbtvt+3d4j1Cbf/a2zdv8AEHhKb7R5n/C\
+fx7932ff53nS7/svm/wBoT+R9v0ssr3b9g/0/Zs/sn/mLeXs8v/hAP+p/h8rb9k/6YeX9h/5dfsv/AB\
+Ilzvsv/AY/5AcDotpqzXeohNe8MxuNV0gXJl8JeEJlMzaJ8NCXVZ/GsZVFglKutySztZXL3DRpdauln\
+PbWmunTYide8Mq/2GcmNvCWhvKGFv4vIQzXXjVbkyEpAAzIJwbqEohkg0cXG/4fvdt7qX/Ew2+XrGhD\
+/kL7PL8vQPhGcY/4WFF5O37J0xbbPsWcWv2Xdok9ndbdIhj+17Mabcp5X9o+Xjda+O18vyP+Ewi25+1\
+42fZUz9t2/Z5PtPl63Tk7N2WnL0Xb08vz7sDktatNWW704Pr3hmRzquri2MXhLwhComXRPiWQ7LB41k\
+LI0EQVFtiGRr22e3aRLXSEvNWez1sXduB4h8Ksp1yyUsvg7wqqLGda8SK0zJB46MTwCNInaORlsWSeK\
+OaVbKLTZZtHxBe7r3Tf+Jhu8zWNdH/IX3+Z5mgfFw4x/wALCl87d9r6Yud/23OLr7Vu1vYub3de2jfb\
+923xHp82/wDtbft2eIPFs32jzP8AhP5Nm37Rv87zotn2rzf7Qg8/7fqk88uy0/ux/wAgOWtbPWz9jz4\
+h8Krn+zd2/wAHeFX25/4Q3fv+1eOl8zb5k+7ztu/7LP8Aadn2jWvs2V4YtNWbRPDZh17wzDA2leHTFH\
+P4S8IXMkMLWngcqk8snjWJLh0SSYSM6RLIbSczrELjWRa99ZXu37B/p+zZ/ZP/ADFvL2eX/wAIB/1P8\
+Plbfsn/AEw8v7D/AMuv2X/iRY/hG926B4UP9obduj+Fjn+19m3y7L4c85/4WFH5e37J13RbPsXW2+y5\
+0M55dl/4DH/IDAjtNd2Xede8MjFjp5UHwloZLMfCepuyIZPGoZJFmCRM0Iad5pEnuETVktbeT8LP29P\
+26f2+fhR/wUI8K/sc/sgaD+y34x1Dxz+zZ4U+K8Z+Kfwd8QeIdcvtav8A4g/tY6Vqthpl74A/aE0W20\
+zS7fwr8LFu4kaGeXzr8NbzG3tdJZ/35iusR3w+1436bpSY/tHbv8vwRrFr5eP+EwXzNvmeTs2zbPN+z\
+fZ7bzP7Gu/5W/8Agqfd7/8Agrt4tf7Zvz/wRs+Py7/7T83Pn/Dz/grAdnm/8JrPu8z7Tnb57+d9qz5W\
+o+fv1X47j7McdlvD6rYDG1Mvr18blWHdahHDutCli8xwmGruk8Th8VQjUdGrNU5VcPWhCTUnSmlyv3e\
+HamFoY7F4vF5Vhs7pYDL81xMcLi3i1hqlbDZZjK9D231DF4HFunTr06dRwo4ug58nJKfJKUX9Ay/H7/\
+g4Tbzs/BP9gr5/tOdnwB+Kcf8ArP7a3eX5P7W37r/j7l2eX/q82/lf8ethjPv/AI+f8HBRTN18GP2C4\
+ozr+n3CsfgD8UnQ3g8R6Bc2kaxy/tYuiWr31raKIUUW6RPNFG0cE926/NX/AATZ/wCCZH/BMX9oL/gn\
+zB8afiT4G8AWHi3RfD/xs/4T7xt4jufg5r2t/Bm+1n4X3fhLxjq+q3t14W021tNLg0TwnaeMfDVn4ht\
+PEMnhNvHQ1LT9UuNVmW91T3j9i3xwnwD/AOCZ3/BWTxr+zl4Mvf2cX+CPxH+IPiL4J6TcP8PNS1ayv/\
+hf/wAE/f2EL/wD8Zb+DwhLbeFfF+teLb/wxpnju5vtO0fUtD1258Wyajb3PiGylXVIPM4F4ezfjnPuD\
+8gwnH+fYPE8bSw0cHOWK4aqQj9Zq0KMJV3T4MvThGpXhz2UqnLzclOc4VIU/wBg8RuGp8Af67U/9VOF\
+8xr8A5zLJMwVXJ+L8HH60ljJJ4dy8Sa868HHBVXzRpckfddScadfCzxPWxfH7/g4TXycfBP9gr5Ps2N\
+/wB+Kcn+r/sXb5nnftbfvf+PSLf5n+sxceb/x9X+YJfj3/wAHCTWrRn4J/sHbTBGh2fAb4txzYWPR1G\
+2eH9rfzllxaxZcfvCRcM3zXN9n9YvCP7C3wk0Lw/4U0bUvjN+2z4s1HRtH8LaZf+LPEX/BRv8AbdsvE\
+HiS90yy+HNrdeItctvCf7XejaVZaxdz6dJc3SaZpmkafDPG62djpVtaR2/h6e8/Yl+CzaRNH/wsD9sF\
+86bbJ5X/AA8c/b8kzttfAi+X5H/DY8u7H2TGz7K+PsW37PH9m8vRP06fAPAUK0qcPHbj+tGEnFTjkHB\
+SjNJ2U4qdCE1GW65owla3NGLul+NPi7MnHTw24Li2v+fXGjs//E2advuPyNsfj5/wcFC2uxa/Bj9guW\
+J9Q8QNIy/AH4pRkXM+q+J3vo4/I/axTygl5e3iR+WDsC23lO/2Wwc6Evx+/wCDhNvOz8E/2Cvn+052f\
+AH4px/6z+2t3l+T+1t+6/4+5dnl/wCrzb+V/wAethj9XrP9i34MT2mqs3xE/a+ctqvjSMbP+Cj/AO3w\
+VdRrnxQiXKx/tsTCZ3W4G5j57TNfFn+1Ndt/bv8ALt8MP+C1H7LHif4i6v4X+L37O/8AwUP8DeDl8Ea\
+rrqeLPhh/wVe/b++MGuJ4vvNU1+Cw8H6v4R8WftF+DrewtpdF8Qajfy3g1m9vI45LUHSL2HUNRuZfAz\
+fJvCrIXhlnHj/x9gFilNwlPh/gtwtT5OfmqLDuELe0jb2kouV/dvaVvv8Agfh3xN8SXmFPgXwV4P4lx\
+GVyw8KtGg+LfrPNivbex9lhqnHdOviE/q9X2ksPSqxo2i6zpqpT5/0b1H4+f8HBT32iSXHwY/YLSaLX\
+1uLJU+APxSSOa8W38TOY5Y4/2sWR7UW11fO0LFLd0jgikY28FrG+hF8fv+DhNfJx8E/2Cvk+zY3/AAB\
++Kcn+r/sXb5nnftbfvf8Aj0i3+Z/rMXHm/wDH1f5+KvgT/wAFcf8AgnN+0CuiX+u+P/2jf2a9cXxZqO\
+p2fhf9pj/gqx/wVG8F3eoaTofgnxF8SLbxLD4y0D4na94d0rTL+z168g0pZfEFt4h1G+tY7SxsmudZt\
+bjWPrz4Lfte/sE/Hz44/C79nD4JftHeLviV8ZPip4d0jxT4B8KeFv8Agrr/AMFgLu01LTB8PtN+KLW+\
+reLob6PRPBviCy8GeCLibVtI1XUdN1XQ7yxm0nUrLTtXsrSxsd6PDvhniIe1o+O/iFVpc/s+aPDnBri\
+5+4uVP6tbmvOKst+aP8x+S4vxLx+X1nh8b4L5Tha6p+1cKnCvitCSpWk/aWfEKfs7U5tyeicJ3fuyS2\
+Yvj9/wcJr5OPgn+wV8n2bG/wCAPxTk/wBX/Yu3zPO/a2/e/wDHpFv8z/WYuPN/4+r/ADxU37Vv/BdH4\
+f6P4N1Xx38K/wBi3SvAOreLPgv8O7zXPDn7M3xT8WeIbOL4n+KvDPwm8P3+k+Hbz9s3SIdUv11Lxlpr\
+NG9/piTTFbm7u7O4iSaP9PbX9kbxIn2Ty9P+K37v+zvK3/8ABaD/AIKbW/8Aqf8AhD/I8zb8Qo/s3/I\
+P0vfjy/I23GPJ/syP+zfh39r/APZb/aA8OfAn4ceOPgD4i8Q+FPir4S/aD/Yc13wfB8WP+Ckv7bfx7+\
+C3jTWH+N3wz8K+H/CHxj+EPxSfXbLXvh5NP4itry8bRxZa5oWoaJYPo+pWXkyaVqOtfhLgeGGxk8H44\
+8c08bSoVqlF5jw9wxQy91qcHOlDG18JgMRiKGFqVFGFatSo1KlKm5VIx91uPXwv4m4TP+J+G8jq+E+V\
+VaOc5hg8JOGD4d8SIYucMTiKdCUcNPHcTU8HDEWn+5liqkMMqnK8RKNLna+iYviR/wAFOb++XTofEPw\
+fgutQbVo7H+1P+CaeieHre6lt7HxhqTQRXuo/8FqoYbe4ayhLxxxyFwZFS0WV9P0tbjbl1H/gqeNY1l\
+08U/s+PcHTYlkRP2B/hmhMMd18STbOiWv/AAXAPkiSRZQhhlm2/aYBbRj7Jozaha+H37ZXxJ/an0DVf\
+DeufBf4f/Cr4w/CH42+GPAX7Qf7O3jr4/eJdV8f/DDxxfnxnqujWmq28Pw7m0/xx8K/EWkX+o6l4Y8Z\
+6NJrGheJNHlju7GSS+l1i1j4bR/29/hJ4r1LxDq3gP4C6H8UfDS3GreG7Xx38GPgv+3Z8afhdrt94U8\
+W/Efwrrt14G+Knwu/Yh1vw98QNCg8QpqltDqukahqGlXjaAj21/fxyXjT/TYnwY46hicXgaD4zr4/LJ\
+U4YulhMkwmZwouvGVbB1frWEyWOHnh8fhovE4GtTdShi8PH6zhq1ajOMl+H4Pxdrf2zxBk1bJ45gsnn\
+Q5MRHLOJcFzxrUlKVN4eOXZm3KlVjNOr7eEakZxjGkuSVSp6Da6n/wVVP2TPib9nxM/2dnf+wL8M5Nm\
+7/hD8+Z9q/4Ljr5m3zJN/nbN/wBiuPtPl/adZ+yFY0X7bHhWPyv+MQvGT+X9nzu/ZI/4KYLv8j+yM7/\
+L/wCCey7d/wDZjbtmzb9vl8vy/LtPshXLLwT8Sp25cHx87duE6ct7d8pVv67HtR8Uofb4fcdrWwvE77\
+f9U6j9Wb3xLpv/ABMN/jbwJJ/yF/M8nxzqc/m/8lC87yPO1lvtG/8A4mHleZu87+1LDzd/9oX/ANoy/\
+FOv2dxovieCLxl4HubifS/E8KRW3jfV7mS5mktPiQhjtVOss108rm+EIbc0x1Ww8zedQv8A7R1l7Zbf\
+t/8AoGzZ/a3/ADCfL2eX/wAJ/wD9SBD5W37J/wBMPL+w/wDLr9l/4kWP4ustugeKx/Z+3bo/ikY/sjZ\
+t8uy+I3GP+Fex+Xt+ydNsWz7F0tvsuND8uNuaN1pdf1sfpwW3iXTft13t8beBEf8A4SXUd8knjnU4oX\
+uf+Ei8IeZdxTx6yHl09rj7JLHcuxuZILG6uJJGuLS0khLLxLpv/Ev2eNvAkf8AyCPL87xzqcHlf8k98\
+nz/ACdZX7Ps/wCJf5vl7fJ/su/8rZ/Z9h9n2Lay3Xt2v2Ddt8R6hDs/snft2eIPCUP2fy/+EAk2bftG\
+zyfJi2favK/s+Dz/ALBqhZWW77B/oG/f/ZP/ADCfM3+Z/wAIB/1IE3m7vtf/AE38z7d/y9fav+J6tAO\
+T0LX7OO7vHbxl4HgS41TQprNrjxvq9uDCNF+EsEcjlNZURJHcQ2yymHasLaPqAi2Np1l9ndZ+JdJ/se\
+HZ4w8GRw/2bc4gl8YXcN2sf2Xx7uhezh1VYUuCv29VjCCNm1KyVlK398J9Lw/Zbr3Uv+Jfu8zWNCP/A\
+CCN/meZoHwjGc/8K9l87d9r65ud/wBtxm6+1bdbns7XdpEMn2TfnTbl/N/s7zM7bXx23mef/wAIfLux\
+9kzv+1Pj7Fu+0R/ZvM0S3blfb3fyf/B/DtqGJruv2cl3ZuvjLwPOlvqmuzXjW/jfV7gCE6L8WoJJEL6\
+ywlSS4muViM25Zm1jTxLvbUb37RqXPiXTft1pu8beBHf/AISXT9kkfjnU5YUuf+Ei8X+XdyzyayXi09\
+bj7XLJcowuY4L61uI5FuLu7kmPEFltvdN/4l+3y9Y10/8AII2eX5egfFwZz/wr2Lydv2Trm22fYsZtf\
+su3RNi5stt7aL9g27vEenw7P7J2bt/iDxbD9n8v/hAI9+77Ps8nyZd/2Xyv7Pn8j7BpcaaaPz1/4Gn4\
+gY9l4l03/iX7PG3gSP8A5BHl+d451ODyv+Se+T5/k6yv2fZ/xL/N8vb5P9l3/lbP7PsPs+X4W1+zt9F\
+8MQS+MvA9tcQaX4YheK58b6vbSW00dp8N0Ed0o1lWtXicWImC7WhOlX/l7Dp9h9n6yyst32D/AEDfv/\
+sn/mE+Zv8AM/4QD/qQJvN3fa/+m/mfbv8Al6+1f8T3H8I2W7QPCg/s/du0fwsMf2Rv3eZZfDnjH/CvZ\
+PM3fa+m2Xf9t6XP2rGuGltnf1+/p/XmBmxeJdJ8u+x4w8GKP7N0neG8YXaNJH/wgus+VDCq6qBPcJY+\
+dbSxuGjivbiGxiVLKaaB/wCb/wDbP0Lwd8T/APgvR8PfAHjbx74c0rwT8Rf+Cafi74ceKvE+jeOmtjp\
+mi+OYP+Cn3hLWX03X9dubq3tNdki164/s0XUdxb3E+raaby2uvt13Hc/0sxWuY74/ZM7NN0p8/wBnbt\
+nmeCNYuvMz/wAIe3l7vL87fuh3+V9p+0XPl/2zafz6fHK12f8AByn+zRH9k8v/AIwEun8r+zvJ/wCPf\
+Wf+ClC+Z5H/AAh9v/qvIxv+yjyPs+37Rpnk+XpvxvHkKdTKMtp1o89KeccPqSTteP8AbWX3V2na6ur2\
+e97dD3uHXT+v4qNan7WjUwGaQnFPlcoTyzFwkk7Ss3GTs3FpPo9j88Pj5oP/AAT6+AHixf2UdO/a6/b\
+b+Idn8HNJ8caJc6P+zWn/AASwPg27/wCE++E1z8IfGWu+MJV+BugXXxJ8dSfDzVbrRW8R+ILfUvEOn3\
+NzLLFqdrfXk1zdcB4y/bv+FHw8/wCCf/7Uf7On7JU3xG8daH8ZfAnxGv8A4l/FH9s34r/sneDtVfwp4\
+Y/Z0+C/7Mfhn4f/AAO0X4K/Efw1pPxA8XxeAfgp4BtdMsYNN1PXrmXw1qN7e6f4ileW90L6v1//AIIj\
++Gv2+vj7+2r8VvEvxrufhn4Pk/bL/abtNe8KeHfgR4Z1D4j3njbR/C+u6H4T1bTfjRd+H7C40r4c2s1\
+l4burzwtdaLdLKdL10aVrPh1/EGqXei/kR+yR+zP8Mf2u/wDgmZ+2D+194Q+I/wAKh8Tvht4E/bq8f/\
+GP9lPxV+yL8QfEn7O/wBX40DwxN8P4f2ZLjUvFGjaB4G+MVr4Z+DC3Fv4y0rUPE0+l6N4n0Dw3rGk2M\
+vh3SW1v934Aw/CPBfHGW4jhrw+x/EfG+QcTf2bg+bOcmwOGxmIo5pi8Lg2sLW4frKHsI4GlGnDEY6pT\
+k50a9acaeHq4Wr/YHHnF/hDlOS47gziKedcc8T5Pgs1eKxOaZlmWKynC5rUr1KWHxU8vhQo+2l7PF1s\
+dN061OksyrQoyqYin7atif3M+IH/BZn9trwbd+I9Y8Hfs2aR4y+GHgb4QeEf2gtd8e6n4H8R+FLzQfg\
+drHizwx4G0j4meJfCOkftf6vPpWkXmveB/G19YWGnXGo65J4W8A6p4u/sqz0TS7O4t/p28/a//AOCoR\
+0eZT8Lf2JnU6ZbKYY/jv4auLkqLXwCBGthJ+1WY5JwIYg0JUojWF2iqF0y0EXMftf8Awi+K37Yv7Tfj\
+u7+Gn7BH7Nvxs0D9iTVvhd4F8c6v8c/jD8S/AXiL9ri6v/CX7MP7WNl+zl4a8K/DTwMnh/VfDujz+L/\
+CF5bj4w2/izwNJ4i8fW09npLw3Pia61r9g/gZ8T7P48/s4/Bn48ad4bufDWn/ABn+CXwv+Lljod7DFd\
+3mg2fxH8CfCvxlbaVd6rB4Ktku7m2g8RpDJcJPCkzzGRZWF2H1rxsJ4j1cRmOOwy4WyengMNPlwspZX\
+hfrVSnGcozli60sBRwletH3IzngcNhqMp89SNGlCpTo0viM68U+Fcsy7KsZgPBXhjEPHxbqwxWHwGIl\
+QhNRq4SMpZbiaVX29XDyc69XE4PL4znHkw+BoexrOf4B63/wXG+KPwQXwv44+OE37EXjL4J+Ifif488\
+C+JL/APZ9/a6+D/jPxnDq9ndeO9Q8RWegxSftb6kl5qlhY+KtO1F4bmya1e21nR7TVL7Sn8WQXd1/H7\
++2d8Gf2R/2WvDeg6P8Dfif4n+Oer2ep/APx1H8cr+68H+FPD+iaD8SPA/xx8c+GPhBF+z34W0DU4fFn\
+i7S9Pj8PDxb4r1Xxr/aGm6jqFrpkXhe3T7U+o+wfEzxP+z5+0J+wD+078GPhLpS6X8VtK/4LGeLv2kP\
+gm/xkvvgpoXxYuP2X/jl8GviH4dubDSLyDVLSW4vbW/+Evw/Pj3T9JOnaLDqN74Rn8nUdtmukdF+2Z8\
+H/h9+zv8ACj9j748/ESy+JnjH4ZftZfCDwr8S/HHwn+D37Rvh74Nx/wDCxfgz8LPh9p2lz2sfjn4M/E\
+DRvGltpmp/tTE6JONNvr+Pw8fEFiRB9ovfEFyZ7wrQ8TcrxccP/ZeD4n4bwlepVw1KnRwlHHUfYUsRO\
+FOhGgqmFxcHWl7PEVcPLDYyhQq0VUjVw9RQ+ho5/ldTJcw4lnkeG8DuJuHvYSpVMqw+P+r5zh6OJxNS\
+tSll9CrWi82wCng50X9ZwmGnQxcsTjsTh4YTDVJfn5+yn+0vY/BL4TfEXxz4O+MHxA+E/wC1P4b+N/7\
+MGqfATxL8KbHxDN420nwd4d/Zn/bL+G3xYvdJgXU7Hw9YWCa142+EFpqdxfSf29cwarKdBWSF9furfk\
+Pgp8RviU1ppUfgPxs2gfBr4U/GCzg8OR/ETx54c0Sbwp4m8f6D8etX8J3cA0vVbPW5XuvC3h/xFHquo\
+aHbLpkF9a2cOpPanUdLivO4/ZY/ad+MvwF8Ma7o1v8ADX9nbxh4B+M/h1PGNhY/tZfAf4FfE/wFqmsf\
+s0/B39obQvAHifwpP8e5NJ0fUfGvh2P4h69aadGl5e3Or32oaXoh0jxQ9zY+E9W+SL/4teJPFWnavpP\
+iXQvhFpyR+P8AxB8YrjxP4F+HvwS8CeK9N8UeK9W8HQ6pF4fu/BumaRNeeCbPTPCwg0PwFo93p/hrQm\
+1a8v8AR9J057q9nuPyPOp5LLhHD5WsorZVxLGh7GTr08JicKqOIw044TGYSNXDYTEYbEUY4mdajiKNT\
+E1akcdKWGdBSqwxv51wniM+4S8U8FxLjcbWznKa2Jw+ZV8PioYvD1MxwsamBzeOGxNKKx1OlRzCnQo1\
+IvGVHg6mHoxxGJrexpYerS/0ov8Ag3R+P/7QnxQ/YF0S3/al+Ovw58ZeL/CPjXQtD+D1rf8AxO+HUnj\
+Dw7+zFYfDz4AaB8HV8Zab8LdZjvdKMmt+HPGot7rxXDH4rvrfw5f3t5NcJZaTcxfor+1Frmnx/AfwRb\
+T+JvCxnt/j/wD8E9Vu7VPE11LdK1t+0n8EW2C2uNRO97a0juIrsSqfslwVtoBFavLE38TX/Bvf+3R8L\
+P2FfiX8Z774o6h4n1bwj8cvh78HNNk8NaBZfCRb+7+IPhHXxF8Nbaz0Lxfqq6paXDeA9Q8YpHEs9w2o\
+W+s2dzeW85lS3m/pi1n/AIKZ/s7/ALR3hz4Y/Bjwj4d+J3hfxhrPxz/Yan0KXxn4U8LWukatd+Ff2k/\
+gjqOraVa3vhS91CWyvpNJstU1BHuo7G1ki0WUTXV1ftZyt93k3h/4gcU+EOecdZdwvi8x4fwGXZhVxW\
+LpxUoUaWFhXVarVg5e2hTjClKr7ScIp0Yuolyar7zhr6OnitgfErhvijJ+CsXmvA+UZzleMnmWGhSqY\
+anhaeIwuJr1ZqlXquMcJBzWKcZVIUp0a16slTlMd/wUTi0Hxz8Z/j14B8Q+LdEvvBvxS07/AIIxfCbx\
+/p3hf4m+L9Jv/E/w6+Jv/BRX9u34f/FHwrHq+ieJ7e7TRdU8C+KvFNjqbRXEczaR4pR2lWTULySb+X3\
+9vD/g5b/aTj+Jl38Pv+Ccfj/wr+zX+z78I/FfxA+Enw50v4dfBbwjrPhPx38DfBJ0zw98H/GVjf8Axm\
+stUfR9NvYLj4iyab4Z03wV4MTw1oOu6fpup3Xii/murjTf6p/2/wCx8S2nx0/aA8S+FPhx4y+JGqfDb\
+w3/AMEdfjBdeA/h14csdQ+IHibw18FP+CgH7fnxW8Z6P4H0XUPDmjR674vfwf4C11dN0tb6yn1K8sod\
+MtYpLkxadp3+aX8Rf2Wfjt+zt8RrbwX+0f8AAnx78MPEt54D1Lxv4d8FfF3wD8QPBGr+K9Fa78Z6R4f\
+1Cy8NapceHdbt7W98Q+CfFFrF5iQXMU3h6+WaxkktJ7YfvfjDxc+GvCvgWlWxGGxNHE0qc4YOvD6xLm\
+pcMcBTnWo0pVlTw1WcIxo/WJ0o1q9L29HD1404YuB/FXhnwri+MOM+Lcpymkv7RrZpgqVSrzNRoU8Rh\
+VGlPExpUquI+r89Oq1OMZQhKE48k6lSmj7T8I/8FyP+CtHwp8Wa/wDFDwv/AMFB/jNr/iL4nvqGq6/o\
+Hi3UrT4keD/CN3ceI49V/s7wt8Mvir4Rv/Cvw1RJtK0mSyh8Hada2On6da2GmWzWkFqlhblflLo1zod\
+vfWD+JbZ7vRxp+rxvBa7b2YX02i3MOj3L2tlr1jIVh1eaxlZWuYflhcMswDwOV/OPFXEk8uzqWCwGSx\
+wWGp4fBy5KeAjUgqlTD03WlzYv29fnqVeatNOSppVYqjCFJQhH9AyjhdZ1l0MyjnuV5bJ1Z0HQxOPeH\
+r/uYUGq7pzTXsq3tGoyjOSdWliFyU4RhF/7fV7Zbft/+gbNn9rf8wny9nl/8J//ANSBD5W37J/0w8v7\
+D/y6/Zf+JFj+LrLboHisf2ft26P4pGP7I2bfLsviNxj/AIV7H5e37J02xbPsXS2+y40POutHuR9sx4v\
+nbH9pY8vRPhRHux/wmW3y/s0b+Xu2xbPK37PtNt9n8z7NpH23K8T6VPFoniSRvFTXKR6V4idoH0T4Vx\
+w3CpaeOG8o/YmVoopAkYHkSBkF1bfZnY22jtedcYq6/eLf+9/8ifKnfW1luvbtfsG7b4j1CHZ/ZO/bs\
+8QeEofs/l/8IBJs2/aNnk+TFs+1eV/Z8Hn/AGDVCyst32D/AEDfv/sn/mE+Zv8AM/4QD/qQJvN3fa/+\
+m/mfbv8Al6+1f8T3loNHuftdwD4vnA/ty9AZ9E+FDxsg1rw2BKkc8axJalGkZYo3ayWKGeKGd7ObUJr\
+YtdHuT9jz4vnXP9m58zRPhRJtz/whu7zPtMaeZt3S7/N2b/s1z9o8v7Tq/wBiXKv+fi/8m/8AkQNHw/\
+Zbr3Uv+Jfu8zWNCP8AyCN/meZoHwjGc/8ACvZfO3fa+ubnf9txm6+1bdbns7XdpEMn2TfnTbl/N/s7z\
+M7bXx23mef/AMIfLux9kzv+1Pj7Fu+0R/ZvM0TktF0qd7vUVHipoTHqukJK/wDYnwrkeVm0T4aSGW7+\
+2NiSVUmZH3rArpYTfaUja51mS2nttIu/7NiJ8W3it9hnJR9J+Grzg/Z/F+Fae5tFuGlJWIB2iEwNxbF\
+I2kt9JW8pxVmudfZ79vT+rPyuG/4gstt7pv8AxL9vl6xrp/5BGzy/L0D4uDOf+FexeTt+ydc22z7FjN\
+r9l26JsXNltvbRfsG3d4j0+HZ/ZOzdv8QeLYfs/l/8IBHv3fZ9nk+TLv8Asvlf2fP5H2DS+B1rSp0u9\
+OU+KmmMmq6ukT/2J8K43iZdE+JcgltPsbYjlZIVRNizqiX8P2ZJGttGkudWfR7n7XbgeL5yP7csgWTR\
+PhQkaoda8SAyvHBG0T2oRY2aKR1smimgimnSzh0+a5nlj/z8X/k3/wAiB1NlZbvsH+gb9/8AZP8AzCf\
+M3+Z/wgH/AFIE3m7vtf8A038z7d/y9fav+J7j+EbLdoHhQf2fu3aP4WGP7I37vMsvhzxj/hXsnmbvtf\
+TbLv8AtvS5+1Y1zOtdHuT9jz4vnXP9m58zRPhRJtz/AMIbu8z7TGnmbd0u/wA3Zv8As1z9o8v7Tq/2L\
+K8MaVPLonhuRfFTWySaV4ddYE0T4VyQ26vaeB28ofbWZpYow8gPnyFnFrc/aXU3OsNZnLH/AJ+L/wAm\
+/wDkQOtitcx3x+yZ2abpT5/s7ds8zwRrF15mf+EPby93l+dv3Q7/ACvtP2i58v8Atm0/n0+OVrs/4OU\
+/2aI/snl/8YCXT+V/Z3k/8e+s/wDBShfM8j/hD7f/AFXkY3/ZR5H2fb9o0zyfL0395Y9Iu9l3/wAVbe\
+DFjp5AbSfhqSxPhPU2ZYzJaAxyiQLG7xB5nuHjuLiOPVEtrSX+f342afKn/ByL+zZbf8JA00j/ALBZd\
+dRTS/AULw7dY/4KNlIYrbT91gWcRDyXYPcQreINPW4SHTXl+P46iv7Kyz30v+Fjh/v/ANDrL/L5/wDB\
+0PbyD/fsRpf/AGLMv/Vfij7u/Y6+J3h3wP8AtHftvfss+P8ATf8AhB/i3qn7Uvxl+NXw/wBI1RNBmtf\
+iN8NfHHhq68Tafq/he50jweBDrdpplt9qvtJuUsdRtrKFbwRINO1Q+E/Yv+Cm1rt/4J3ft9H7Ht8n9m\
+j9pNM/2bs8jyfBsMezd/whkX2Xy/P27d9j5X2jZ5Fh532bUfM/iB+yf4S/aX1P9qjR9c8cat4W8c+Df\
+2j9K8UfCf4qeGNK+G2m+Mfht40sv2Y/gre6drehX+iXdtcNpkl9pmkG90+2u447pILCS0mh1HTPDOoD\
+yv8AaL1j4o+J/wDgkX+2bqfxn8XeHNe+J+g/AL9tb4f+N7rwpo3gK18L6/r/AMMNT8afDKfXdFNna2l\
+xbQ3h8Li9UWNvbWqytcrYWNvYz3tnY/0z4dYfJM+4n8PuO8qxX1TNq3GmFw+c5bPnajjcVnuKxNHG5d\
+Vkn7TBYuGGr+2oVpqtgcVBw5quHxFCVP8AR/FjD8PcU8OVfEvJsU8BnmJ+p4XiDKqvO408xx2W1sXQz\
+LK6z5/aZdjqeExLr4atP6xl2MpumpV8LicNKl798af+CX37Onx++J3iP4q6xqv7RHw71z4vWPg3Q/2h\
+NE+B/wAePi78JvBn7Sfhbw/4b+Hvg3Q/C/xk8L+D9HFvrOnQ+Dr6/wBKFzpQ0/VLiw8RTW8+o36z2p1\
+XyH/gpD8bPEX7Bv7HPwQ+HH7MVt8LfhDrPxP+IXwe/Yt+DvxE+KNxHpvwu/Zr0fXPh1Zy6N8TNaXWvA\
+06a/Y+H/CvgN4LOG+u3tUudWttU1RtYsIbzT/Ffqnx1/4KK/sa/sxePdX+GXxl/aM1rRfGngvwd4U+I\
+Hj/AEvwr8CNV+Ldr8NvBviPUvBOj6Jr/wAUdd+F3w11rT/h3ZXOpXdhEg8RXWmSTHWLMzpGviCRl+mv\
+FngD4Y/Hv4Tvovi278D/ABq+Evj7w94a1xdF1/wl8EfiH4A8a6Of+Ff+KfDOqpbXWmX9p4isftdvpmo\
+WN0sE5aXT/tsQWabUWsv59r4bD4ilmeGyfGUMFm1SLUqlOMZVac53cZVIpKSbbk05Wd+aS11PlsozTG\
+ZdmPB+a8bZVjeJOD8JWjOlg8TWxNPDYrD4d06dajhKs701GEY0qc1RvFKMKU7Rsl/mP6H4T8V/He0+O\
+uh6v8evAd18erb4s/DjxXYXnxW+JPwp8HeKvHXg+20/9odPi341T9ov9o/x1oreGNesfG/i/wCH6614\
+KsfGOkTeKbnx/J4gn8N69F4OXUtG0NcT9nv41/CT4FeDv2j/ANob4q/B/wALeAfgPNdfBzTP2nfi98c\
+30DxL4l8UaP8AC7w74h8Q/Ajwd8BP+CfXxLi8KfBPSPEvwR8deGGsNZ1yG71VbvwnqNpJY/2Dr+nT+E\
+XXiW58LeL28NeErvW7TS7e519JYtPg00eL5NNT+1IbDTPFXguRrvS7Tx+v2Cf+2biGJpUndoLeWCIOJ\
+vCvF/jb9pz4h6P4u1nxVp0vxe8Mfs+6FYfC+X4tXXw60j4rfDfwH4U0PxxpXhXTZbD4hTadfWHhnwkN\
+T8YeG9P0y2svO0mdvGlk9nbR3d5Z3Ev454cYjNszxmLyKviadH61HCYetzY2pQrZlKeJrUKajNYOssL\
+KE6jxSqVJ8tNU4zjUw8k4V/8AQb6Q2C8MuHsgo4qlWzBR4nxOPxeX4PDZHhcTgcjWGoZHjcVh51K2f4\
+CnjVHBzeD93DYd1Z+3UqmYSVD2XoWh6pF8TP2Wvg38H7PXrW+1Xw98V/Dk17pcsvh/xjpOj6Zc+Kviq\
+JNT1fwhoHw30/X9BkE/ia0jVr3X9Qsb6DU3Wf7FD9max+gf2b7H43fEHX/E/wCwP8Pj+xbb3nxq8XaN\
+8PPD/ij40/Ab4ND4gQ6/8bviv8M/2cdFi+F3jvxt8NPE/jyxudEudc8I6va6f4IuV1Tw/pXhPXPE2l2\
+8upRardXn502/xa0nT/HEvjHwh8NPBvgi70rSLdtN0zwz4i1i28IyaloOg2djd6rd2Pi2a6vtZGqXel\
+T6reacLyGF7/UWXSrfTraGx063/Qz9nj4OftZfs6/EL9mH9u68+Ef7Sg0L7Z4d8WQa5a+D/jl8FNE+I\
+Phj4h6RNquo6H4D+P3hvTLmVX8S/C3X/FFrHqenq7C1vptRhXULOKW2T9CqYzi6h4icQ1uLcDPiCWY0\
+8RTy/CYilXzapSxM8Q69ClRr4SOLxccHQw9OeHoVadWjSqwlC1OcqSU/zrhinwVxf4XcP8M+GWCxGYe\
+INOphKGZ4ieY1q0auUYbDYfL60cDl3E+KoYSvj8RVxVXFUMpy+GIhlMaVT6pi8HgqyjhfAP2pvh94g+\
+F/i3wt4b8TeOfgR4k1LxF8BvhXJ4bsdJ8L+E/CO600nwL4d0S3vPH1t4X1ONPht8WpIvCcE12+syw3v\
+i03tr4z11Lm68W3GoXP2L/wSw+LHxf8GfGb9j7x3+01+0Je6F+yt4e+Lfg/R/hJYfGf9ozQo/AHgy58\
+MfHT4E+J/Hmq+Efh34v8du/gXwzb6VdtJeazFpVlpMlxp+pWx1D7XpeoR2n58/Fb4w+HPjb46MX7RcN\
+94X1T4ceFj8K9Hh+EPw28N6PrVreeEPEGi6bpmqeJl1a60268YaiNB0rxFbXt74h1K41a3ku9L06y8n\
+R9Os9O0j7c/YH/AGa/gV8cbLw3oHxV+NXxD+GbfEnxj4V+HXjm50m++HKPrfwv8R/G7wD4R8X6/e618\
+QdS1Oy0Lwhpvg7T9RNh4t0zTXjtdd8Ny6fe295ZzO9p9p4ecN8VUMmzziOpglj8bmmR8RUMxw+Cp5bg\
+6mGw9LIsdgMwxbw7xGXOi1VxOBrLD0MFi8VjcNUx8qNGrUoqkuHwzyfiviXjjhXFcPUqOc8QcCZXicS\
+sJSzaFbHKU6eGwOKweNwtXETtXwdTHYtRw9DG4XB4jB0ZfV1GtTxTxX+iV4xs/L/bz+NDfYfK8v4K/w\
+DBPMbv7K8jy8fH/wD4Klx43/8ACCWvk4+zbceZbY+y+XsX7P8AZdK/iv8A+Djr46WPxR/4LMf8K1tvB\
+WifDfVv2Vfhf4d+Edx8Sodd1658R/ElfG/g/XPj7pq6poFnp+n2/hPQNHi+LGsaVZRWWhzai13Jdzaz\
+qradf6Jonhb+jbwH8QPHP7Pv7f3iL9mn9rP4x2eueO/F3gT9jDwl+z38W4tH+HcUfxg8C+CPi/8At1y\
+eG18c6w+q31xoXxVvNQ8c6hp9vBOssmqT+HPIbU9YuZPD2p+Jv5ov+DjzxL468X/8FiLtNasrO/8ACX\
+wb+G3w5+B/hHXdF0fS7a+1KLXfDHiv40MuvWXhqeaG51AeIPjDryRXVtDHYw6XaWduJHWzkuZP136Tn\
+BOa5ZktDD0Es5y7EcK5XXwWPwsKs8NjsJ/Y+UYBYrCe0pJzjLEXw06dSEZ0K7nQrQjXpypH8o+B/BGc\
+8KfScnjKdOOf5BgM74czXCZnhfrEcBmGWYfN1gv7Sw1dRpV44ejjF7PFKXsK2ErUa+HruhWpTUfwsu7\
+DS/EPw8+G0dr4Z09/D9poXxt1l5kPjBorCw8LTXmsQKpg19cyX0+lQTSR304R54RFazWYKrRXG3mq30\
+Hwi+E2mafZXF811ovxokuYUkezUQwHVFuLszzQlL22ttNu9QuXhQ7me0jG9XAVivwXi/D1MdxDDEfXZ\
+vBwynIKVN0KqjF1KWTYOOI5/Zuzqwqfu5ppODgoP4eWP6j4jcWYDCYXhT6tw3l2JzavgMtqYupiMspO\
+EY1OHsgqYfDYaXsoR9jRjOpUVNVakqSxChy0qfsub/aUvb3d9v8A9P37/wC1v+Yt5m/zP+E//wCp/m8\
+3d9r/AOm/mfbv+Xr7V/xPcfxde7tA8Vn+0N27R/FJz/a+/d5ll8Ruc/8ACwpPM3fa+u6Xf9t63P2rOu\
+F74gvW/tD/AIlusPu/tfprugSeZv8A+FhYxn4uS+bv+0rj/Xb/AO0Rn7V9qb+28vxTrt3NovieN7PVI\
+kl0vxOjXEuu6LJEiy2nxIUzSeR8Wp5JYyLoMdguHkGoDaLo3RGt/RRV5R82uqP5wOstr3be3bfb9u7x\
+HqE2/wDtbZu3+IPCU32jzP8AhP49+77Pv87zpd/2Xzf7Qn8j7fpZZXu37B/p+zZ/ZP8AzFvL2eX/AMI\
+B/wBT/D5W37J/0w8v7D/y6/Zf+JFj23iC9F9dt/ZusLu8S6jL5n9u6AgcN4i8IS/avMHxcj3qwgMnm+\
+dKWFmZft85gF9phZeIL1f7P/4lusJt/sjrrugR+Xs/4V7nOPi5F5Wz7M2f9Ts/s44+y/ZV/sRWAPD97\
+tvdS/4mG3y9Y0If8hfZ5fl6B8IzjH/CwovJ2/ZOmLbZ9izi1+y7tEns7rbpEMf2vZjTblPK/tHy8brX\
+x2vl+R/wmEW3P2vGz7Kmftu37PJ9p8vW8TQtdu47u8ZbPVGLapoTyImu6LG1k0ei/CWPyZvM+LUIjkV\
+LISfuzEiJajm1ktSNDdZ67ero8Kf2RrKEabcp5J1jw/GVza+PR5XkD4mxBSftIGz7KoP9oAfZ5PtLR6\
+zbXutd+X8n/n+fZgaXiC93Xum/8TDd5msa6P8AkL7/ADPM0D4uHGP+FhS+du+19MXO/wC25xdfat2t7\
+Fze7r20b7fu2+I9Pm3/ANrb9uzxB4tm+0eZ/wAJ/Js2/aN/nedFs+1eb/aEHn/b9U5PXddu5LuzZrPV\
+FK6prrxo+u6LI160mi/FqPyYfL+LUwkkZL0yfvDKjpdHm6kugNc1LnxBem+tG/s3WG2+JdPl8z+3dAc\
+IF8ReL5ftRkPxck2KonEnm+dEVF4Jft8BnN9qcWem2vmv6XzA2LK92/YP9P2bP7J/5i3l7PL/AOEA/w\
+Cp/h8rb9k/6YeX9h/5dfsv/Eix/CN7t0Dwof7Q27dH8LHP9r7Nvl2Xw55z/wALCj8vb9k67otn2Lrbf\
+Zc6GWXiC9X+z/8AiW6wm3+yOuu6BH5ez/hXuc4+LkXlbPszZ/1Oz+zjj7L9lX+xMvwtrt3DovhiNLPV\
+JUi0vwwi3EWu6LHE6xWnw3UTR+f8WoJIowLUsN4t3jGnncLU2oGiFna+n3r+v8uoG3FdYjvh9rxv03S\
+kx/aO3f5fgjWLXy8f8JgvmbfM8nZtm2eb9m+z23mf2Nd/z6fHK63/APByn+zRJ9r8z/jAS6Tzf7R87/\
+j41n/gpQ3l+f8A8Jhcf63z87PtR8/7Ru+z6n53mal++UWu3ojvh/ZGsjdpukpj+2PD6+Zs8C6zbmID/\
+hZq+YUMgt9m2YIZxbi3tlkOj3X84v7Zup6Tp/8AwXu+B/jrx58PPin4x+H+mfsYeEvCusr4A8B+PPix\
+qUPiLxP4i/4Ke634O02S0+E/iHW7uzub2Xwtq9/b750EsPhu9upEvoY5pdT+U41jTnl2Ve2m6WHjnGQ\
+SqzSi3TpQznL5VarU50octKmpVJOdSnBRi5TqQinJfRcLUJYrN3hoUq1epiMLmEI08NQqYrE1ZTwGJj\
+GlhsLSTq4nEVZNU6GHpr2lerKFKHvTR8yft6ftn6D8Cf8AgtV4O+N/jvwj4kn+Bv7Anjf9o6++KvjPw\
+t418Dar4w8UeMf2wv2CPgL4I8B/Dnwz8OdY+K1ndzzSz6boeoWNxPqhHiC3tPGN7YadqWmfD7xbrDfX\
+eh/trXP7Uf8AwS//AOCsngnxX8MNY+EPxP8AhZ8LP2nvH3jDw+PHdl8SPBV7on7VuneL/j74Fk8I/En\
+S/EUFr42Mej6zdRTSwWd3Be2VnpXiCyudS0rWNNutO3vFHwx+GOm/tM+NP2oPgTH+0D8HfHmumUeH9b\
+vP+CSPxe+K3xA8IQN8N7/4Z6pZeHPin8QYLrV9K03UdB0q0jltrRoLdLbxLeWrx3SXOpvrvjvxD8Kp4\
+H/Zq+MHwF0H4yftFfB74IfGrVNR8BeMvBnwa/4IvXnwisvEcvxs1/4cfCiafTbPTLLStOl8c6rp82ka\
+dZyTtNe3dxpmm2K3F9cLp5s/oeCfEePB3GvDLo5bPGcLZPxBhMxxVSnmPCcamMjhM0xuJhiacauf0al\
+OUsPjFCnSrVIuEabjWlNzp/Vf2HNOF54/gTNOH8FwjxOs3zaOUVqdfE8I8b4aNCtgMDXwsqFbDw4cx1\
+C3+2Ynmq0saqNSpUp1FGhDDz+t+i/ty/Efxt+yF+0/+0toHhL9pH/gnh4Tg/4KY/D/AOElrDon7Wuo+\
+LNG8ZfB/wAU+Ffh78Nf2fbjxf4vXwd4F8WaT4z/AGfrvwn4Mli0+L4lal4a8IW/ia/1OK3EEWneINN1\
+D6E0b/gp3+xH+xV8I/g5+ydpvxQ8RftAJ8C/2ffg18MZfiP8JpPAuueDtYHgr4ffDLwpavJqF18c1tH\
+1SWx8L2lzdwWC6lZ2Et5Fpzzi/sp7Lw/+BXxg/a914/ET4+eBf+Ci37dX7Uf7J3j740fBnQvgPeXFh/\
+wT98D+DfBn7S/7H3h7xZ4uuvAOv2WkfGq4t9d+GvjW2vviH8UtP1zSLO6lhsrtIn0bxJqlssFx4c/DG\
+f8Abd8R+HJV0Xwt4t8Jahodv4Tg8JQXd54c/ZtuLldO1FbDUdSMMmu+KbmaLxBbahfahbW+smV9Thgt\
+Vjtb6GzjihtFk2M4T4E4kzPHeI2Fni8qqRUKFLI8fkHEc51sRN4qM5Ry7jTCxo0FGVadadOo5U8VVp4\
+TEU6FSh7OX9B+BXAHhd4hZTjafjTXzdYbg6ll1HD4KGExWQSxWKxeCdH21bE4jh2ljcQstwWW4LCRw0\
+XiIU4zhia2Lo1MZ7Cr438XH+E1h4M+OXx++F3xg+L/AIjuR+2j4/8Ahz8LvBvxI8O+DIfFOpfBLULXX\
+vFnhb4gfEb4teHfidO8/wAVXtm+zarpun+G7vSrqfV77UIfE+fLs5vvj9jb4ead+zV8APj3cRftC/Fe\
+Px78bND+Gnw+T4S/C3w58L9Z8HeF/Bd7+0D+zl8Vvin8UNO1f4tfGjR9MvfizafDH4WfEPRdL0W98Oi\
+0ujqFsJ/FFoJnhj/Pv4xeNPgZqHw9+G3gz4e61q1rbeINN1b4ifF/TdF1X4c6PcaX8cJfEfxK8A31vF\
+rOu/E/VV1jRNT+F0fg3UJJrNbCyUeIvshsDeWd9d6h9v8Awr/4KZeAvhx8I/Bvh3W/2d/2YviJr1kdf\
+0a81XxX41+OFp49k0+xkum0PVfEcPw6/a20Dwwtp/Z3iOPTdOXT7NLtovAQl1e18y5lvtd+14Bx3gRx\
+9neYYDiPAVOGcLmGUyq162Z0Mrkp42TwuHnD6zjeNKKxDnhpN0sLicXiqVLlxfs8twUp4pVfs+HOGvB\
+6hg62E8V8y4m4iy7KsJg8NlKyCo6WNy7MHUzGea5hShj8DQwtGlUlTyf2NSdKoqsqGHcfrNJx9l+gf/\
+BL7xf+yz8AP2pvi3+0j+2v4C8dfG7xdofxz8HeK/2P/HXib/hVmpeMvCGkaM/xO0DVfHXi34ZeD/2gL\
+fwZ4S+MF7oPhb4A3Iu9PbWLrTtS8GtLpPiWxltVvb/+hf4wf8FeP+CePx++Hep/DP4meBfjHreh6xpk\
+tpZXtx4U+Dmr6t4Q1bUvD3h3w1F4x8FSeIvj1dW2ieM7HTr3Uv7Ov1tg9u8kQVIomSPSv5IZv+Cs/wA\
+N7mawuf8AhjX9keIRalBfpEvxN/aOVJSJNZkFpd+f+320kFqRqDKz7op0FlA4nSWWeS6Lj/gqZ4P8R6\
+bqOhaH+yN+yto+rXuialFY63onxM+OUuvaRNbaTYz/ANsaLaeIP267ywu9bt00sz21tc2F5BNczPB9h\
+uBHbW0H9C8GcKfR9yPHZFg+GvEHD082w1ejTwVSjUyVYiNV1FHD06NLBeIcP4blGjQoYeg7U1CjTpy0\
+g/s8tyD6GGX5lgOIavDXihSzfK6lKvHNqmMwNGrTqUoU+bHVpYONKmqj5PbYmrSoJ1nzVJwnOcub5Z/\
+aS+ENr8SEv779mQ2Nr4fT9oL9p/xEtz4i8ZeDfBnjrV7bTvjprVt8Htf8bT6ZqttZ+IPG9j4TOuWsVy\
+CINPbWrw2VxHayNsxPhl4E+LPhD45fDnUNeubvWNE1jW7hG13TPH6ahY6L4JtvDk0+leANY8K6LrDWF\
+vpq+LdTtru1dmmknu7N7iSMXJmV/WvgJ+1Da2+i2R8R3fhWw0DWPiP8UZrk2viLwvaazo2oeIPiVrPi\
+GyOuWmr/ABOs20nRJPt+YtQjgurYm18p50BjvIPd5PidP8Q7T/hH/BUmt2HheKXQvDnjf4heH9c8PPe\
+6dda74ektNJ0bwLqttrOoWGp6wdVvtNt9VuElkl0a3vgkMUd7cRmz/rVfRGrePGJ4Z8QsB4k0OHfZ5d\
+hOV4fI6NCjVy6qsHWnWr06edvE4yeMqQnFV5VpOtmNSdN0asqVPCw/ZOA8L9Hml/qn4iZFxTxFj/ECt\
+PhDEvKKWIhUp4nM+G8rwrUaeCq5W6WHoY7DwxWIzrM61WH1an/aGZyxWDhDF1Jfe3gX9pG88bap4q+G\
+nx1tB8WfgH/wjPwW8AJr10b2++JPw7uP2d9Q/a98TeBrD4K67N42s7M3mieN/wBoP7PdTalHq1pHpt5\
+qHheGQwWt9ot1zf7dv7Pf7VvjXxZrXi7Svid8OfG3xO+Jvwt8Oahp/wAQrDxd4+g0r9u34K6FLY674T\
+i8RWmu+JZbjQ/2l9D0bwN8N1n8F6oiSeLZ/CWjTWkNx8QDoeofFb0f4TfAXwX8VPh3P4W+AOkSeFvi5\
+8OfC0b237P1rNbXFj8V/C3hjSPFl14v8bfCfxDrPxDmvNT+Jn2W1stR1XwZLBfXmrz3msa34dv5454/\
+Clp+bX7aX7QX7Qfgz9n7UPgz8JrwWnhLx/4luPF/jBLKw8GW/jbSJPCd1puq3XijwJ4/luJ9c8Ka5Lp\
+ehw6ZdjS7vbfaRrV9aXVtcxXLtP8Ao30iuIvD/hThHjLxA/sz2eX8DzwEMwy2phaFHFUp4+vgMrwWbY\
+dVqkMNRliGsNLHOjiJZfmtHCVKPtv7Uy3DYnCcXiH4DcNYTKeNvEHh+tm2T8e4GU8y4p4bySWIhD+0c\
+wrVcZDH5NRWXyq1lKc1hZYijSp4HiLCZdH608HnOU0MZlfxD4c8R/tCeDvEOg+LvCOveDPC3ivwtrOl\
++I/DHifw5qnjfQ/EPhzxDod9Bqei69oOtaZPFc6RrNnqVrbXFrdW8sc9vPbxyxSJIisCvE/gP4j+N/x\
+r8S+Pb7xV4yvfHusLZ+IPHniXxN4s8fTar408Q6/rvh/xJ8QL3UdQ8T654gYeItZlh0HX557eaeXWLr\
+VLmOwjhub+U2oK/wAt+JPpl8FZf7Krm3hlh8enWrYeEpPCVGpUqOExEv4kbRjKnjaEopSb1bkkuVy/I\
+eA/Cqn4tcJZLxlDFcSexzGnU5aeLqe2nTlRxNfCYmEJvCy5oU8ZhcRQ5+WnzzoyvCLTiv8AYdvbLb9v\
+/wBA2bP7W/5hPl7PL/4T/wD6kCHytv2T/ph5f2H/AJdfsv8AxIsfxdZbdA8Vj+z9u3R/FIx/ZGzb5dl\
+8RuMf8K9j8vb9k6bYtn2LpbfZcaHsXtlt+3/6Bs2f2t/zCfL2eX/wn/8A1IEPlbfsn/TDy/sP/Lr9l/\
+4kWP4ustugeKx/Z+3bo/ikY/sjZt8uy+I3GP8AhXsfl7fsnTbFs+xdLb7LjQ/x2O69T/Jo2Lay3Xt2v\
+2Ddt8R6hDs/snft2eIPCUP2fy/+EAk2bftGzyfJi2favK/s+Dz/ALBqhZWW77B/oG/f/ZP/ADCfM3+Z\
+/wAIB/1IE3m7vtf/AE38z7d/y9fav+J6W1luvbtfsG7b4j1CHZ/ZO/bs8QeEofs/l/8ACASbNv2jZ5P\
+kxbPtXlf2fB5/2DVCyst32D/QN+/+yf8AmE+Zv8z/AIQD/qQJvN3fa/8Apv5n27/l6+1f8T1AY/h+y3\
+Xupf8AEv3eZrGhH/kEb/M8zQPhGM5/4V7L5277X1zc7/tuM3X2rbrc9na7tIhk+yb86bcv5v8AZ3mZ2\
+2vjtvM8/wD4Q+Xdj7Jnf9qfH2Ld9oj+zeZokHh+y3Xupf8AEv3eZrGhH/kEb/M8zQPhGM5/4V7L5277\
+X1zc7/tuM3X2rbrc9na7tIhk+yb86bcv5v8AZ3mZ22vjtvM8/wD4Q+Xdj7Jnf9qfH2Ld9oj+zeZolv4\
+X6x/JgQeILLbe6b/xL9vl6xrp/wCQRs8vy9A+Lgzn/hXsXk7fsnXNts+xYza/ZduibFzZbb20X7Bt3e\
+I9Ph2f2Ts3b/EHi2H7P5f/AAgEe/d9n2eT5Mu/7L5X9nz+R9g0vH8QWW2903/iX7fL1jXT/wAgjZ5fl\
+6B8XBnP/CvYvJ2/ZOubbZ9ixm1+y7dE2Lmy23tov2Dbu8R6fDs/snZu3+IPFsP2fy/+EAj37vs+zyfJ\
+l3/ZfK/s+fyPsGlwAWVlu+wf6Bv3/wBk/wDMJ8zf5n/CAf8AUgTebu+1/wDTfzPt3/L19q/4nuP4Rst\
+2geFB/Z+7do/hYY/sjfu8yy+HPGP+FeyeZu+19Nsu/wC29Ln7VjXNiyst32D/AEDfv/sn/mE+Zv8AM/\
+4QD/qQJvN3fa/+m/mfbv8Al6+1f8T3H8I2W7QPCg/s/du0fwsMf2Rv3eZZfDnjH/CvZPM3fa+m2Xf9t\
+6XP2rGuAE8VrmO+P2TOzTdKfP8AZ27Z5ngjWLrzM/8ACHt5e7y/O37od/lfaftFz5f9s2n5R/EKy2/8\
+FbrL/QNmz4afsdf8wny9nl/Dj/g4b/6kCHytv2T/AKYeX9h/5dfsv/Ei/VyK1zHfH7JnZpulPn+zt2z\
+zPBGsXXmZ/wCEPby93l+dv3Q7/K+0/aLny/7ZtPyj+IVlt/4K3WX+gbNnw0/Y6/5hPl7PL+HH/Bw3/w\
+BSBD5W37J/0w8v7D/y6/Zf+JF4nEf+64L/ALDst/8AUzDnjZ9/uFH/ALDct/8AVlhD9bb2y2/b/wDQN\
+mz+1v8AmE+Xs8v/AIT/AP6kCHytv2T/AKYeX9h/5dfsv/Ei/Lr/AILJ61F4K/4J4/H3xnear428I6R4\
+K+J/7PvijxL4n+GYg0T4leHPB/hX9sX9mjVvGWofDjWbnwlbJoHxAtvCsGsf2LO1xpf2LU57VgNLLiK\
+//UW9stv2/wD0DZs/tb/mE+Xs8v8A4T//AKkCHytv2T/ph5f2H/l1+y/8SL4k/wCCgPiuD4b/ALO914\
+5uPCet+Kx4V/as/Y4vrfwn4a0/w3D4i8S39v8At5/so2+m+FNCm8ZaBpmj2GsXuoXlrY2x1fUNG0u2m\
+1VP7RbSbOWaO/7czi55bmEE2nOhVV0uZq9OSuorVvyW+x93wfXp4bi3hfEVqio0cPmOCnObqqioRhia\
+UpSdaVo0lFJv2raVO3O9Efx/f8N7fBD44+KP+CUmqftQeHPH3xYuP2avhb4k1z9qPxXaaN8PfGXxO+M\
+V/wCGviLqPgn4f/Bvx8vjL4fWlp8TND0zXfhfpN9q99qOoanba9p/xh8QyPt8RTatd6z+pVz/AMFPv+\
+CMJsJIh/wTvdHa2ggEw/ZH/ZKwsn2fwx+98yLWEcITazkuLhTm++adme6fU+E+MPxr/Z2+DH7dX/BJH\
+/gpN4W8I23w1/Yh+Jn7PfjL4c2PhTw18Mx4T8Q/B3UrdfE91481Xxp8L9D8DjTLXSrLxV+0NpY1X+wP\
+7fuby60rXru1h8QfaNGn8U/Pf7H/AI8+H8nw18caSnjDwdJqtz/wRP8A2yvCFnpq6xokmoTeLX/ah+M\
+XxM/4Re2tBokkn/CRH4aSHxB9iQ21y2hS/wBqeXNYSZu/594zr5vk2fYWeX1Mplg8wX1f608ppVXicT\
+g8uyLF1OerWxNSdSv/AMLcabi5KapUKMvejVjyf7JeEnCfBXHHgxkOZZ7w9xgsPwphKE8PDA8WZnleG\
+orN8943/tHDqlhsvhQbyWrw/Qji8RRhDCyqZlGhGhgPqns63in/AAUj/bP/AOCdHx2+C+n+CP2W/wBh\
+m++GvxXtfi43i7V/G9t+zT+z/wCAYLvwVaWPxbtj4WufGHw7sZNRu1e78TeEXNrHH9iRfCjtIyvY6fa\
+Wngfgj49/su/Gj4j2PjL9sL4GT2XhC/j1W/8AiB4V/Z8/Zs+C3wms7DS7Hxxq/jPwT8Avg7oGiXujt4\
+X8ItftZ3PjL4l30938R9W0nRrL4baDqGh6HZa34q8Q/wB8vwh+IPgD4yfDLSPin8Lda0rxl8P/ABt/w\
+l+veF/E2jaZItlqGnS+IPiqpJin+HNpNpl/b3FhPBd2lzFZ3en3ekT2l5DYXWnzR6B6ne2W37f/AKBs\
+2f2t/wAwny9nl/8ACf8A/UgQ+Vt+yf8ATDy/sP8Ay6/Zf+JF+iZFwvxHlVXMc4yfifKK2Lz+jhY/Wp8\
+PYfEqFKhGr7KeB5sc6eH9rCu3OpQt7VRoybk6cGfy1L6X3BWQZXDw+zTwI4iwWA4axmac2Fr8eV6GaU\
+MXi6kFi6ONxtbhZ4+dWhicNSqKnXaq4XE0X7H2ClVpz/hV/YM/4KIf8E7/AIG+A9G+Bv7Rf7Gnhb4x6\
+X4R+I2rXfwa+PNh+zV8Cr7xt8Wfh5qPiDx5fyaf8WdJ+I1/eTaf40tda8RWUVstvrGsaeNPW20aWCca\
+HYX+sfZvxy/4Kr/8EzNG+A3xsH7Nn7JPin4D/tC638Evij4I+Cnxi8G/s+fs8fDfxN4E+Kfjv4ew+Af\
+BWu6T4/8Ah/q6a34QnbxJrFvEdQsZ1nhi1h5mneJr2XUvqr4//wDBJD9p/SPBnxD/AGS/2cPFP7O3jb\
+9in4nePrXxX8Kfht+1dH8dtR+JH7KvxJvm+JtreR/BH4geB/Bct6mgw3i3+oW5vZZmvZr2XTdT0DU55\
+vF134j/AD7/AGnP+CX3/BW/wJ+zf8bviX8bP247X4kfCP4Z/Cfxh8WfiB4Gu/2iP2rPFg8S+Fvhx4c0\
+/wCIN/p1poHjH4ZQaRq+rGEWb2SX11b2bXlvA7XcKTWNxP8ApmJ8LP7Yx0s9qeLfD2XSq1fbThPhenQ\
+lOL5ajqfuce5YXESk5qvCmvZ0q0XUw05U5QUPpY+JngDxdhM/q43+1cJmfEcqiw0X4g5vhMPRWJwtGE\
+XPKXk2MoStipV3Wy6qvq1OKjhoYnHUH7d/Mj/8E84/2iv+Ce/iH/gpD+y9P8ULfVde+PH7XPiXx58Ov\
+HniDxb458aeOvgb4n/ak8U3vgfxbqfiuSfV5ZfiNpHhDxnocvjKTV9du7DU9O02fVru9sdZsJW8Xfjz\
+onxIv/AkFvFIr33h2/8AFfgh9T00CFpY5R4u0OJdR0151IgvUQrvXKJcpEqSMkkdvcW/7mfsEf8ABNT\
+/AIK8fFD4FX+rfCr9ry++BOhaJ8e/2kfhvrHwu1P9oz9onRL/AMK+O/h5+0F4o8A+ObG5s/g14Q17w9\
+dSJ4ra4X7RpeqX0d0IRIju91ZLdfg/+0Z8PfH/AMDvEXibwJ8ZvDOueBPHPgzxZ4Mk8W6J4mt5ItRs0\
+uPEXhrXbXVvNUumq6RfaJe2Wo2GoW0k9nqen6nbahYXFzZ3UE8n97eAfE+PymHCmX5TxRHNeIMieXyw\
+0cPdTp0KlHDQWHeFdNSlH2qmpe9WjVhiIUJwp+yj7bXwr49q5H4c53hKXiDhM2zfhTKa+JpSoYh3wWX\
+zy2Klh68K0IudChUjV58RKrWp1aOIp0asaMaUHX/VLwne65JpVp8VvAj65DpHh/XNCk074g+HLfU7K3\
+8OeKb4eLtZ8JJF4ksdGi/sDxM//CH69c2EZltrwN4TvZIVjbTpzp939tjxf4M/aOh8GfFS50W5+Hf7Q\
+sWstpHxa1nw54R0T/hVXxCHiB/FY1L40z6TaWunr8O/iHPLYaBb6tp1lZtomp3f23W0k0e5uX0+L5E+\
+Engj9vTXv2V/2tPA/wAPPBMsXwQ8U+GvBvxN/aA+HE8Pwu1zxZcfDX4U6xceINC8V6p4Y8QG48SWVjp\
+WpjVLzxB/wjcIttOtTZp4rcQWsTp4r8Dfh5+1nrhb4f8AwQ+G9n4iufE3izw54E0rTNX1X4ZeA/A03j\
+7xVoHiaTwf8O7n4geO44tB8N+K9f0TwP4pj8P6Pd3trLrV34anttNgnu1fYvpRePXDXE/EeJ+jh4weG\
+9fIXxhk83SznBVsVjMTRq0I0swqZfjsgo4Whi6+AljMDQxGI9lmE/q+GqYPHwdKtQWLo/6HZZ4yZbj6\
+VfxO414HxuRYPw5nTnUx+DljMPjcPgcXgcHifZZjh69HB1MLHHYl/W8Hl+IrVJyp0csxtBf2hGmqRJ4\
+C0vSpLHWtL1XTtS1bVLaxm1+LT/AkegX8t1YaPpml6Vb32rRWKtqy29vqF3FAd7JGu5YyI5oxKVetYf\
+2lda+HnjLxtd/DmHwzpnw++Ktt8DfiHoGsv8IvDfxS+HXxSex1bVdN8N+L/hsyr4k8MtNB4B19IL250\
+5NNnvPCupaUbptRs9RsYiv8UvHjwmw/BHH1fIa3EuS8IZhhMJgY4nKMdlfF3D+IwNSGEowi3gc8w+Z5\
+g446jGnmPtqmMlSnPF1I4ShhsDDC0Y/0p4V+NfhjxzwvHiPw94R4t4r4YzCvXqQxuTYLBZvhauInUdT\
+EqeJpZpUhDERqTar0bxqRq80q8fbyqyl/p93Wk+CX+2bNI8Ktv/tLy9miaQN3m/8ACZeTsx8Posbvt2\
+nbceTj7RBj7Nsj/sXK8T2Hg2HRPElxa6d4Zimj0rxFNbTwaNpUUkcn2Txw9rLBJH8PIzE4a900xlREV\
+M8BUWxSP+xe+vb3d9v/ANP37/7W/wCYt5m/zP8AhP8A/qf5vN3fa/8Apv5n27/l6+1f8T3H8XXu7QPF\
+Z/tDdu0fxSc/2vv3eZZfEbnP/CwpPM3fa+u6Xf8Abetz9qzrn9eRkk1ZNNPTX/gH/JIZ0Gk+CVu7h20\
+jwqI21y9uEZtE0gobWTWvDc8cqg/D6QCA21reMqiGNQkMoFjArPZamWuk+CU+x79I8Krs/s3zN+iaQd\
+vlf8Ib52/Pw+lzt+w6juz52fs8+ftO+T+2uptr3be3bfb9u7xHqE2/+1tm7f4g8JTfaPM/4T+Pfu+z7\
+/O86Xf9l83+0J/I+36WWV7t+wf6fs2f2T/zFvL2eX/wgH/U/wAPlbfsn/TDy/sP/Lr9l/4kSvHs/v8A\
++ABwOi2Hg1rvUUn07wyy2eq6RCqS6NpTrbRponw0uJ4lV/h5KEQTQas7j9+Cy3LMbkyyjWZ7bRfBqab\
+FE+jeGVmFjPGyNoulGUStb+L1VSx8GSkyF73TwD9pY5uIcTxlEk0ff8P3u291L/iYbfL1jQh/yF9nl+\
+XoHwjOMf8ACwovJ2/ZOmLbZ9izi1+y7tEns7rbpEMf2vZjTblPK/tHy8brXx2vl+R/wmEW3P2vGz7Km\
+ftu37PJ9p8vW6bVm2m7cvXy06eS+5bWA5LWrDwat3pyQad4ZVbzVdXhZItG0pFuY30T4l3EETKnw8iD\
+oZp9JdB+4AZrZlNsYoho2rPpPglru3ddI8KmNdcsrh2XRNICC1j1rxJPJKwHw+jBgFtdWbMphkUpNED\
+YzqqWWmaPiC93Xum/8TDd5msa6P8AkL7/ADPM0D4uHGP+FhS+du+19MXO/wC25xdfat2t7Fze7r20b7\
+fu2+I9Pm3/ANrb9uzxB4tm+0eZ/wAJ/Js2/aN/nedFs+1eb/aEHn/b9UnmWl7tLbXZfd31A5a10nwSn\
+2PfpHhVdn9m+Zv0TSDt8r/hDfO35+H0udv2HUd2fOz9nnz9p3yf21leGLDwbNonhu4utO8MyzSaV4dm\
+uZ59G0qWSST7J4He6lnkk+HkhlctZakZCwlLGCcsLkvJ/bXfWV7t+wf6fs2f2T/zFvL2eX/wgH/U/wA\
+Plbfsn/TDy/sP/Lr9l/4kWP4RvdugeFD/AGht26P4WOf7X2bfLsvhzzn/AIWFH5e37J13RbPsXW2+y5\
+0M5ltrbtfqtunQDAj0XwaEuwdG8MgvY6fHGDoulZaWLwnqdlMqZ8GNiQX80EbENCTM6MZ7lwNXtfym8\
+fWfhI/8FaLG2hsPDn2eb4afsc4gj0nTEhk+0/Dv/g4FkXES+AIl+d20JhxDytof9GMMP9ifr/FdYjvh\
+9rxv03Skx/aO3f5fgjWLXy8f8JgvmbfM8nZtm2eb9m+z23mf2Nd/lH8Qr3d/wVusv9P37/hp+x1/zFv\
+M3+Z8OP8Ag4b/AOp/m83d9r/6b+Z9u/5evtX/ABPfD4icVhcFo/8Afst6/wDUbh/I8bPv9wo/9huW/w\
+Dqywh+ol1pPgl/tmzSPCrb/wC0vL2aJpA3eb/wmXk7MfD6LG77dp23Hk4+0QY+zbI/7F+dP2p/gR8Ff\
+j38FvF/wq+I3w60Xx54H8VePfh9e654S0qeHwnqeu6X4f8Ajb8J/GVvHpHiPStC0u40W7B8Myz20sN9\
+pmxrJl8m1jeSz1P60vb3d9v/ANP37/7W/wCYt5m/zP8AhP8A/qf5vN3fa/8Apv5n27/l6+1f8T3H1O9\
+2mR/7Q2bvHemzb/7X8vd5nxA+H8vn+b/wsKHzN32ff5vny7/s3m/b7nyPtume4lQm1Cvho4qhLSdKql\
+OlUg9JU6kLLmpzXuzjdc0W1c+ly7H4rKswwOaYGtLD43La1LEUakJThKFWjONSnOM6coVISjOKkpQnG\
+cWk4yi0mvxp+Nf/AASq/Y8+KvwE034H+G/gJ8V/hgngfQrqw+DHiHSPiq3iSy+E+q3Y8Ny3l1pHg/xL\
+8WJrHUtC1C80KU63p7mKTVI70zfb7bV4hq7/AMmmqf8ABOv9rr4WfHHxr8IvCthYeHPjz8L9Ft/ix4F\
+8Cv4y8T2Xjf4n6Jot3ca3c+N/2Zte0IxL4+1eyj0e51RLC0vovERGiX1vp+nS61pGtWcH+jzZXu37B/\
+p+zZ/ZP/MW8vZ5f/CAf9T/AA+Vt+yf9MPL+w/8uv2X/iRfHn7Y/wCyX8Pv2vPhbYeH/EOsah4L+JXgG\
+W28W/A/4z+FdQeLx/8ABz4g2lt8PZLHxD4aubXx0k82nvc6PYLqWmJ5Iu49GgkgOmarpGlaj4U+A4z4\
+Ny3NcBiJ5Dw9g8JjJwtUw8OelTxPLyunUpVJVGsHmNBwi8LjYKKkk8Hjo18BVnSj/Z/0cPpa5z4cYif\
+BvGuMeI4EzipOUMbUp18xxOSYmu71a3sateVbH5JjJN/2zk8KkZzUpZjlrpZpS/2v+Fj9lb9o79qP4Z\
+SfEnVfhPpfw01PQotCm8U+MPgRF47/AGhPC2j3zaVpCWPjv41+A/Dfw9+KmhTza7YaTpNzfeIdP0/UR\
+bWGk6jcavZeH4PDHhc3Pg396vht4Q/4Kb/GjwF4b+KHwy0n9h/xn4C8caY+r+HvEejftJ/t+raX1pcy\
+atb3cTwS/H+KfSdTtr681W1u7K4it73Tb2yayure1u9PWG2+If2hv2dvip8QPil4uR9OPwv/AOCnfwj\
+1PxB8RfF2g/D7VJNJ8M/tu6D4c1zxp4gl/at/Zb1zTdZtli+PVvPo91ea54a0eC3l8RyaRea3oFjZeL\
+rHxH4bu/Lv2cv299W+C/h/xbP4G/aF+OP7LOp+PNSGteP/AIffBf8AZw+CPxx+DHirxbZaT4n064+Jn\
+hPw/wDE743eG4PgzqWsWE8VtrGgaJpl1pfmafLcabd2ugnQ/BuhfjXA3ipg/DrF4jJeL+BMo4jymq5K\
+jVxWCpU8RTqUFGnOEHicVhqdCtB8kMbl9evFUp8uJwkpQq3xX+kviX9HPKPHHhehxz4PvLqPHip5dPH\
+UcdSzPOcLPDYjDwhh8T7bh7D4jH5hlmPo0p4vI+JMHluJWMjTxGX5phsHjMPio5V+rl78Cf8Agrgt3p\
+Jk8D/sdxSS6wJYEtv2kf2944Lm6gttd1JYb6IftB4lsAZ7yTySPLZ4LaNkaKCKNM3xR+yz/wAFUfG3h\
+bxD4I8XfCn9iXxD4S8W+H9T8K+JtA1X9or9vi703XPDutadbaRq+j6nBJ+0L/pVlc6ZbiCdGJ82Oa4D\
+lvtVx53x9qP/AAVn+LUuo6LK3/BRj9reVrbxPb3STS/8E7v2O45reUT+MFF9Ci/tXOJtQVryZ0RpEHn\
+aldMLqN0Fze3bb/grZ8W1+yY/4KN/tcx7f7P2+V/wTp/Y3/dbP+EQ2+Tj9q5PufZoPK/1f/ILsseTkf\
+2d+oP6R/hTZc3hLkzUlovYZPor2t/yP+6bP54o/Qg+kjTqqpRhwfSq0JRalHIvFVSjJKMoyi1wjdNXT\
+T0aauujf0N8FvgD/wAFp/A37JHxS8A/s73v/BOj4V+JLj4yftHeJ/DWteIx8Zvit8XbfxVf/tEa14n8\
+TyaV4r+Nvh3xvpHiF9U1m01mC3m8XSalIY5b5r6e2kuo7qb5Dvv+CVX/AAVn/bk8F/DKf/goZ8Tf2P8\
+Aw1qHhb4neFZoPjf4b8D293+01J8NL7RPDZ0P4cJ4b+Cfhbwv4E8bfDqL4g/Z7pm1y5tfFWn6rqGr39\
+lq9xpl5dWGq878D/8AgrH8WLLwhexQ/wDBRH9q7T1PxX+NN0IdO/4J4fsd3ESyXXxy1a9e6R5P2orQi\
+6klEc7IEVY57O2jSZlVLiy8X+Nn/BTD9oPxR4r/AGaotB/bv/af1jQ9B+JXwkn8UNffBD4bfAq30+wt\
+vGHwxjtreTwL8I/jXq2l/HqAWdvqUFvp3i6aysI44Vsc2+n69rS2v3Xh99JzD4TjzhjLeHuH8LQzzF1\
+aOQ0YTpZM8NTrZjUw+WLGaY3EY2FTBJuph5unONB806mH1m4/i+A+gd9IrNuBsm45q8Y8P8G5vV4ZWP\
+8Ar+Bynj/DydWGTSxThWeYcK4bCYuOMm40MRTxWKq/WacnShDEzqKhiPVP2zv+CBHxK/Zz+D+u/E/4c\
+fHbT/j9pvh+w1ubxloumfCzVvBGu6BpUNpfGy8SWtrc+MdTTV/DayWedUn8yCfSbfVLO+ltZ7GLWrnR\
+fw8k+Fk/hXw3441C+0TxJ4f1Hw3rfhG30GHWtf8AAmqad408KarovjjV/FWuW19beIbR/C93oWqaN4e\
+tI9Ne1vZ9b/4S+5vYZbJdMa3u/vD9tz4tzfEL4n6z420X44fHDxz4/wDFXj3xzeeM/Gvjnw34e8OprP\
+hhvCHw1uPArL4L8JePtf8A+EZ1dPEmr/Fe0liGrXWlR6NpWgQaYluqXNlX55+L/Fum+P8AQ/Etr8XfG\
+2nWOn+H9D8TaPpiatZ+LdMvNV1S4+G2ra7/AMIRqdxp2iXsw13XdX0qaw0rUY7dtMjn8SWtzqWsWlr9\
+surb7rxD8fuBeDeOeJcqzzAcS5344eGEsVkOAxmCw+S4PKMVKvmeFhjJY+jmGGzDFYeVGNOvHBYnCUM\
+txdXCyWCzLCZdWxGKrUv9HeGPBbNeFfCXBU/EfjaGbZ9iKsswrZisuoZB7Slh8sxWNngMTDFyzDGSwl\
+KbvCtgsjynMsZCnhIPBynHE83FfFbxjfeMtP8AB3irwToOlaZ8a/A8EOm3esi/gu9M+NHhy3/tkx2nx\
+MsLrxW6SeJrLTrrSrGzvLFLW1uLLw1p4v7YalBJrcpXLeFNI+HNv8WLl9b0ax8c+Ffh/H8NrXwhr3gn\
+WtWmsrHXNb8E+F9b+K3gy7n1G80ceK9c0jUdai0aXULY/wBlyT6Tcz6Vc6pp91Z60pTy3NvB/wCk/jc\
+w4o+kx4i4DhTjXhung8vwss6x2GhiMRgFho1aFKnWwuT4irXpYJSVFrEVmqFWVShQpxhB1K3xnBHh94\
+k8RYPN+J/C7xhzDw1yXPsxxs69LKcfjqNPNsZh67wmJz3FYXG5Bi4UsTj69CpGGIoOLzLAYfBZjiv9p\
+xNSFP8A1qr2bX2/tDHiLR23/wBr4zDey7/M/wCFhYz/AMXhl87d9sjz/rvM+1n/AI+ftg/tvL8U3Gtf\
+2L4nafX9LmgOl+J2mSL7Wks0T2nxILpHcP8AF6cCR0vFAcrcBjeFit2LvGt9Ze/23/p/m/8AUW87/ko\
+P/U//AGn/AI/P+4x/r/8At6/5jtY/i7+3P7A8V7/vf2P4p8z/AJKJ1+xfEb7R/wAfHzdf7Y/1vP8Az8\
+8/27XzsXaUfJroj/AQLabX1vrtz4i0dQ3iXUZw3k3qFlfxF4QmExl/4XDH5jFbZ387zpN5txN9vn+zm\
++0wsptfX+z8+ItHXZ/ZGcQ3sWzy/wDhXucf8Xhi8nb9jkx/qfL+yD/j2+xn+xNi2/tv7bd7P9b/AMJH\
+qHmf8lB/4/f+Eg8Jed/x7/vv+Pz+zv8AW/8AEw/57/6f/ZVFl/bf+geV/wBQnyf+Sg/9SB9m/wCPP/u\
+D/wCo/wC3X/mBUrgcnoVxrQu7wR6/pcbxapoS3Bf7XtMsei/CVt8KL8XoDYxrBaouxjGUexMm61FuF0\
+J1m/iBdHhjOv6MpGm3KeWLO9jALWvj1Qn2f/haUW0E3aDZ9lXd9rK+RJ9rEes6Xh/+3PtupeX0/tjQv\
+I/5KJ0/sD4R/Z/+PXj739kf8e3H/Pr839h1PZ/2p/ZEPlf8e39m3O3/AJHH/UfZfHe//j0/0T/V/wBr\
+fc/0f/np+7/turb91vty/k/8vz7sDE1241o3dmJNf0uR5dU11bcp9r2iWTRfi02+ZG+L05vo2gunXYp\
+kLvfCTddC4K67qXM2vtfWjjxFo7BfEunzlvJvXKqniLxfMZvN/wCFwyeWwW5R/O86PYbgzfb4PtAvtT\
+PEH9ufbdN8zp/bGu+f/wAlE6f2B8XPtH/H1x97+1/+Pnj/AJ+vm/tyti5/tv7bab/9b/wken+X/wAlB\
+/4/f+Eg8W+T/wAfH77/AI/P7R/1X/Ew/wCeH+n/ANq1F3ptp5L+n8wMeym19f7Pz4i0ddn9kZxDexbP\
+L/4V7nH/ABeGLydv2OTH+p8v7IP+Pb7Gf7Ey/C1xrX9i+GGg1/S4YBpfhhoUl+1vLDElp8NyiSXCfF6\
+AGREs2BcLbhTZhgtoLTGidZZf23/oHlf9Qnyf+Sg/9SB9m/48/wDuD/6j/t1/5gVY/hH+3P7A8KbPvf\
+2P4W8v/konX7F8Ofs//Hv83X+x/wDVc/8APtz/AGFRd2tp9y/r/PqBmxP4gEd8P7f0Yb9N0lAPsd6u8\
+x+BdZtChH/C0l80K8oi2bZvLEhtfItjJ/ZF1+VfxBuNXb/grRaK2uadJcP8NP2PvLlDXLwnzfh3/wAH\
+Cpi3wH4rztcZS6uA2JJfOOpIw88TsviH9bYv7U8u+2/d/s3SvN/5HH/Uf8IRrH2f/VfL/wAgr7T/AK7\
+/AEf/AJ9f+JL9rr8o/iF/bf8Aw9usvN/6Jp+x153/ACUH/onH/Bw39p/4/P8AuMf6/wD7ev8AmO14fE\
+bthcF/2HZb/wCpuHPGz7/cKP8A2G5b/wCrLCH6q3s2vt/aGPEWjtv/ALXxmG9l3+Z/wsLGf+Lwy+du+\
+2R5/wBd5n2s/wDHz9sH9t5d9ca1G80k+v6W0b+OLSVTF9rtXLy+PPAMlvctcP8AF5RMnmwLK8nmyGdb\
+UsuoSmH+0NL6y9/tv/T/ADf+ot53/JQf+p/+0/8AH5/3GP8AX/8Ab1/zHax9T/tzMnlf67/hO9N8z/k\
+on/H5/wALA+H/ANo/48/3/wDx9/2f/rf9P/5+f9N/suvdi7Sj5NdEeyFlNr6/2fnxFo67P7IziG9i2e\
+X/AMK9zj/i8MXk7fscmP8AU+X9kH/Ht9jP9iZt4/iBtHmjGv6MxOm2yeWbO9kBK2vgJSn2f/haUu4A2\
+jjZ9lbb9kC+RH9kMejdVZf23/oHlf8AUJ8n/koP/UgfZv8Ajz/7g/8AqP8At1/5gVZ15/an9kTeb/x7\
+f2bbbv8Akcf9R9l8CbP+Pv8A0T/V/wBk/f8A9H/55/u/7Eoh8UfVAfIH7Tn7JPw8/a98I6Tpfj7XtQ8\
+N+KPh74+13xl8L/i18PtTTRfi78MvFGneMvHOr3moeBfGVx8SdQGmwaheaZpn2m3e2vY3MdjeRLLrNp\
+pGp3nz/wCKP+CXPw88U674l8U+Jvi+vifxN4i1bxDr/iDxF4g/ZZ/4Jx63rviLXdUvPGeo6nrWt6ve/\
+s53Fxq+rXuoJHPc3MslxNczarJKXuXuLZtU/TjT/wC3PsWred1/tjxx5v8AyUTp/b/xS8//AI/+fu/2\
+v/ruP+fj5f7crYvf7b/0/wA3/qLed/yUH/qf/tP/AB+f9xj/AF//AG9f8x2vnsfwvkOZ4qtjcZlsJ4r\
+EcntJxlUpOp7NONN1FSnBTlCLcIyknKMPcTUUkv1Thjxt8UuDsmwPD/D/ABdVwuTZXLESwtCrQwmMhh\
+Fi506uKhhXjMPiJYajiK1KFetQoSp0aldOvKDrSnOX5E6n/wAEoPg3DqWgwt8QtLk+1eKYLOOVP2T/A\
+PgmzEsKFvGTSXcqx/s2ulygtLCNgHkSBHvRcPdxRfZ7q+0Lb/gk18Hm+y7viLo6b/7P34/ZI/4Jrrs8\
+z/hE/Mx5n7Nsezb9svMb/L2/YR5nkeTd/wBmfqdrn9uf214T3/63/hO7bZ/yUT/j8z8SfJ/1377/AI/\
+v7Q+5/p//AD7/APEx/tOtiy/tv/QPK/6hPk/8lB/6kD7N/wAef/cH/wBR/wBuv/MCrj/1I4X0/wCEvb\
+/p9iP/AJafRL6S/jar2423/wCpdlPkv+gDyR+HfwI/4JS/CG/8GX80vj/SbU/8Le+OVoyN+yX/AME4W\
+KrafHrXbEzBtQ/ZktnjVke6kVSqRRi2VUkEEE82n/MX7TP/AARl1bxf4u/ZL8b/AAi8bfCl/BHw/wDi\
+b8K/EfxUt/G3wx/Z6+HviH/hH77xl8I9Wt4fCegfAf8AZ+sdI+K+qQWOjeJSbXxql3paXdtYWc1tb22\
+q6xYT/vNovwR8aaL9pg8I/Hb4ueE9J1fxNrviy30LR9I8EXOnaZqnjzxTo/jLVRp82q/BO+vJIDr/AI\
+qspo991cyD7FAsMkudLNz59qXw1+IkfgfQ5rj9oL4vXEBufhAJbSXRfhatuv22TSH0lg0vwRRt1npxm\
+S28+QoyjMQurD7QxeTcI5NQzLJK6yKrLHYDF4HExqRq05p4jC4qhXhJ08RiJUqkJVaacqdak6c43jUh\
+Z2Py3J/pcfSP4E4Gjgfq2Nx2KyDh3FZZKbwfCU8JNSyatltarTX1uhiHBQnOpRlOFOqmoSnS5lKm/wA\
+TvjH4S+KH/BOb4jfEDwb8SdO034//ALAv7TPiHXP+El8Pf2Jpel6Va6rfz+JJorvTfD3gvxhYaX8OPj\
+NosMC3Wkrpb6ZpOvWGi20+ltYS2Ns3h/8Ak0m1/wCNfgzUf2jdmiyro40iwvPEXxMtNU+J1tr/AIF+F\
+/ifwj4u+EPxR0DW9d8P+N7LRNA+GHiu8+K2m6ZrNxqKahJfzapYWVrqtrba3qWm63/pNfEz9mfX/ir4\
+L8WfDv4mfHH4s+MvBfiay1Cw8SaBrPhz4ava6hFbz+K7w3Cyv8BI5dP1OHUNK1W7tbyOS3u7C8n+2RT\
+2t1bX01n/AAL6d+zD+3R8UrM6vpH7Pn7bVh4N8f8AhG98a+FfB3jz4XaL4v16/wDAVxLrtzYx6nNon7\
+GX2DxFIumylbi/isrSyae58yRLJpfs8P7j4sZ14V/SF4c4WpeKvHOJ8HfErh363GGNhlNbNcl4hX1bC\
+8mNxWEy+slk+c4f+z8Fhq2bQg4ywj5KdCvP6rRwH+sH0PvpL/8AEX+H+KMn4m8P834U8RcDPLMRm2Po\
+47h/DZRxHQw2X5plNCrj8tfEmGw0sXWweMlQzejShTpZhSwGWSqyng8Ksuo/j98NfEPxo8dfHfx94p0\
+zw7q3xesNO8AaBdXvh7UNX1XxN4v1P4GfA/wzZ+E9D174cTahPd3N/wCFvCXwt+H7iJUkuNL0Xw74Yb\
+TvNiNpZNEV9z+KP2Q/jD8QPBnwu8UeK/C/j++8DfFTx9Z/BL9nfUdR+HXhC28HeKPiT4oEPh3TPBHw0\
+1G0/ZYNl428dXd5o1varpfh+4bW72XwhLDDZyi0iWIr8r8NoeCeHwuZ4vP8i4P8T4Y6WH+pYrOMzq5H\
+jaeDoYeNClKpQxmBxkKqxbhLE05QxMsRToTo08dRwtdLD0/054D6RHhC8Twf4T8YVcLk8MZmGMxtDHL\
+ghewzLH4/EYzGUcPgsRisZPLKFCtWeH+pQxdWh7ShPFQhQq4qvSj/AKhF7qFkn9of8SnWE2f2v08D6+\
+mzyv8AhYWcY+FsPl7fsDY/1Gz7EMfZfs6/2Hl+Kbq0l0XxPAmlaojvpfieJTL4M1q1ijYWnxIQGSaf4\
+Wwx2samyOWfyEiFkC32UWw/sPrL2y2/b/8AQNmz+1v+YT5ezy/+E/8A+pAh8rb9k/6YeX9h/wCXX7L/\
+AMSLH8XWW3QPFY/s/bt0fxSMf2Rs2+XZfEbjH/CvY/L2/ZOm2LZ9i6W32XGh98bc0brS6/rY/wALQtt\
+QsmvrtP7J1htviXUbfZ/wg+vsFMfiLwhb+R5Z+FsmxVN0E8ryYgouTH9ggExsdULLULJ/7P8A+JTrD7\
+/7I6+B9fff5v8Awr3Gc/C2bzN329c/6/f9tOftX2hv7c2Lay3Xt2v2Ddt8R6hDs/snft2eIPCUP2fy/\
+wDhAJNm37Rs8nyYtn2ryv7Pg8/7BqhZWW77B/oG/f8A2T/zCfM3+Z/wgH/UgTebu+1/9N/M+3f8vX2r\
+/ierQDk9CurQXd47aVqji71TQpY9ngzWp2ZZNF+EsGJkj+FsxSRnuD8snnPIl6H/ANKjux/bjrPVLJ9\
+Hhl/s3WWB025k80+DPEDk7bXx63mecfh5KWI+wk7vtTkfYwftEf2dZNF0vD9luvdS/wCJfu8zWNCP/I\
+I3+Z5mgfCMZz/wr2Xzt32vrm53/bcZuvtW3W57O13aRDJ9k35025fzf7O8zO218dt5nn/8IfLux9kzv\
++1Pj7Fu+0R/ZvM0S3blfb3fyf8Awfw7ahia7dWhu7N10rVEFpqmuyyb/BmtQMqx6L8WoMQpJ8LYS8iv\
+bj5Y/JeNLIv/AKLHaH+w9S51CyW+tE/snWF3eJdPt9n/AAg+vqGMniLxfb+QYx8LY96sbUp5XkyhhbC\
+P7BOIRY6WeILLbe6b/wAS/b5esa6f+QRs8vy9A+Lgzn/hXsXk7fsnXNts+xYza/ZduibFzZbb20X7Bt\
+3eI9Ph2f2Ts3b/ABB4th+z+X/wgEe/d9n2eT5Mu/7L5X9nz+R9g0uNNNH56/8AA0/EDHstQsn/ALP/A\
+OJTrD7/AOyOvgfX33+b/wAK9xnPwtm8zd9vXP8Ar9/205+1faG/tzL8LXVpFovhiB9K1R3TS/DETGLw\
+ZrV1FIxtPhuhMc0Hwtmjuo2N6MMnnpKL0lftQuT/AG51llZbvsH+gb9/9k/8wnzN/mf8IB/1IE3m7vt\
+f/TfzPt3/AC9fav8Aie4/hGy3aB4UH9n7t2j+Fhj+yN+7zLL4c8Y/4V7J5m77X02y7/tvS5+1Y1w0ts\
+7+v39P68wM2LVLIx3x/s3WTs03SZM/8IZ4gOzzfAus3okB/wCFeN5ZYQmbduhLmITm4uWQaxaflX8Qb\
+i2H/BWi0nGl6iiQ/DT9j7Knwjq8My/Zvh3/AMHCqNstm+GUMg2mJNu1YcCwdk+zLYyHQP1titcx3x+y\
+Z2abpT5/s7ds8zwRrF15mf8AhD28vd5fnb90O/yvtP2i58v+2bT8o/iFZbf+Ct1l/oGzZ8NP2Ov+YT5\
+ezy/hx/wcN/8AUgQ+Vt+yf9MPL+w/8uv2X/iReHxHb6rgr/8AQdlv/qbhzxs+/wBwo/8AYblv/qywh+\
+qt7qFkn9of8SnWE2f2v08D6+mzyv8AhYWcY+FsPl7fsDY/1Gz7EMfZfs6/2Hl311aXDzQppWqFo/HFo\
+hWXwZrSIotPHngHzLdRP8LZFDhZjGkAhiYtciCPT4HuBY6p1l7Zbft/+gbNn9rf8wny9nl/8J//ANSB\
+D5W37J/0w8v7D/y6/Zf+JFj6nZbjIn9n79vjvTYdn9keZt8v4gfD+LyPK/4V7N5e37Rs8ryItn2nyvs\
+Ft5/2LU/djbmjdaXX9bHshZahZP8A2f8A8SnWH3/2R18D6++/zf8AhXuM5+Fs3mbvt65/1+/7ac/avt\
+Df25m3mqWSaPNL/ZusqBpttJ5o8GeIEI3WvgJvM84fDyIqT9uB3fakJ+2E/aJPtDSa11VlZbvsH+gb9\
+/8AZP8AzCfM3+Z/wgH/AFIE3m7vtf8A038z7d/y9fav+J7nXlrt0iaT7Jsxpts/m/2d5eN1r4EbzPP/\
+AOEPi25+153/AGpM/bd32iT7T5mtkPij6oDEtbq0trTVUfStUUrqnjOX914M1plRW1r4pToC8HwtiEU\
+iJa/Mv7h4Xstj/ZZLX/iR6l7qFkn9of8AEp1hNn9r9PA+vps8r/hYWcY+FsPl7fsDY/1Gz7EMfZfs6/\
+2GafZbLLVv+Jfs2ax44P8AyCPK2bNf+KRzj/hXsHlbfsnXEOz7FnNv9l3aHsXtlt+3/wCgbNn9rf8AM\
+J8vZ5f/AAn/AP1IEPlbfsn/AEw8v7D/AMuv2X/iRJ2u7Jpev/AA5PWbq0bWfDG3StUUReOLRHR/BmtQ\
+s4luPiNYC3ihk+FsZuXaSNUMCQysUtWB0+eO2ax0vUstQsn/ALP/AOJTrD7/AOyOvgfX33+b/wAK9xn\
+Pwtm8zd9vXP8Ar9/205+1faG/tw1yyxrXhNf7Pxnx3bQ7P7I253n4kweR5f8Awr1N277P5fleU+/7N5\
+P2C48j+z9M2LKy3fYP9A37/wCyf+YT5m/zP+EA/wCpAm83d9r/AOm/mfbv+Xr7V/xPTTTR+ev/AANPx\
+Ax7LULJ/wCz/wDiU6w+/wDsjr4H199/m/8ACvcZz8LZvM3fb1z/AK/f9tOftX2hv7c8k13UbS28CaPE\
+9hqoe2v/AIIxu8PhTW5IlaT+yZy0VzB4HjR45PKMgeOWNZ9gmD6hgalB7nZWW77B/oG/f/ZP/MJ8zf5\
+n/CAf9SBN5u77X/038z7d/wAvX2r/AInvkOsW+34f6Efs2zZd/A85+w+Xs87+x587v+EXh8rzNnmZ3w\
++bs87OobP7Sg9DKrf2jgdNfbUfu9rDy/rszwOK/wDkl+JP+xfjP/UeoejXuoWSf2h/xKdYTZ/a/TwPr\
+6bPK/4WFnGPhbD5e37A2P8AUbPsQx9l+zr/AGH/AC6/DLwrqkP7PXw78QS/tLftG+DvCqfsmaHq918c\
+dJ/ZT/4LM3ll8PdKsfBGpXv/AAkGna7pX7QcHhK60pdN0jUdXg1S00aPwOU8IiYaVaaZDJa2X9D/AO2\
+H8Ttf/Z//AGU/2qvjt4U0LSNR8U/BL9nv4/fFvw3pmv6BeXGhX2v/AA0+HHxk8Y6PY63Z6d4S0y4m0h\
+9R8N20dzHBeabN5Nq6xXOnPbLLoH8fP7L37QeteJ/hn8L/ABH4u/ZZ/wCCRmny3f7Kmgar4LW88Pfsc\
+axqXi3xLqWgadf6SnxY0zxl+1z4Yn8G65O1zL/aOp3EV3r+jSNNHH4ZkdJV0v8AGvEnEUsLWyatiMre\
+Pozo5hSjKVPGyhCpUp0JRd8DUo1E1GnJtyqxgvd5lK5/oB9C/KM1zrG8dYbJ+K3w1iMN/ZeKqKFbIqU\
+sRRoPH0pQ5c8weMhUfPi6ahCjSnGzqTxVGtQpuK/Lj9tzUvixP/wTV/Z68NfDyz+JPxw8C+KPjl8SYf\
+HUbeBf2po/C37L3xB8L6PZ33w88A+DtWHi+L4c+JPEvibRPGfiXxgLnRdEXxFozTX1hrd5c6b4h8m8K\
+/Yb9pD9kH4Kfs8ftc+NfhJF8Of2frj4Hjx14R1/QPEXxE/aL8N3nxt8MWHjP4S+B/FifDuT4W6n+2f8\
+KZW+H0Pi7VL6KzvfEMdpq66PqMWpSeJfEEZsZ9XK+H4K8UPFjwuyb/VjhWpDIqOCrToYlUc14hwccTi\
+cIoYaWJcYSpUKvtIU4KNWgnTcVGEeVQjTh/b3i19H3wE+kPxPS8XeKPE7ivFUeO8LSzjLaODyjhGosv\
+y7N5SzKjl1WWGxkatOrhJ4mpGeHx0p46nOU6uKlUq15Yiv/ZzdRRj7Xi+018f2jjZpXgiPft/4TDHl/\
+ZdYby93lx7PJ37Pttv9m8z7No32vG8WRRjw/wCKMX2mtjRvEmCuk+BUDYsvG+Cgg1kqgby49nlFgn2y\
+3+zlxbaN9r0r3T7J/wC0P+JtrD7/AO1+njjX33+b/wALCzjHxSm8zd9vbH+v3/bRj7V9oX+3MvxTa2k\
+Wi+J501XVHdNL8TyqJfGetXUUjG0+JDgSQz/FKaO6jY3pyr+ekovQG+1C5H9uf0hGV2k7JN/yo/xANu\
+CKM3VwDfaaoGtXih20rwQ6Mo1jw6onSOfWFiS2ZXd1ijZrFY7aaKGZ7KfUprctYoz9kzfaamf7Ozv0r\
+wRJs3f8IfnzPtWsL5m3zJN/nbN/2K4+0+X9p1n7JBbafZLfXb/2trC7vEuo3G//AITjX1DGTxF4QuPP\
+8w/FKPerG1D+b50oYWxk+3ziE32lllp9kn9n/wDE21hNn9kdfHGvps8r/hXuM5+KUPl7fsC5/wBRs+x\
+HP2X7O39hrm9P/AUBm6FFGb3V832mrnWdHzv0nwK/l7vD/wAMsiU3GsqZivmPv+0bC4s7gXAjW51g2t\
+u2jQ6dGxurJT9imPlPYeFnmBEHiwhGnudSW5aQmNAHaMTg3kBRGkttIW6paFa2hu7xG1XVEFpqmhRR7\
+PGetQMqx6L8JZ8zPH8UoS8ivbn5pPJeNLIJ/osdoP7DdZ6XZJo8MX9payoGm3MflHxn4gQjda+PV8vy\
+T8Q4ipP24jb9lQn7YB9nk+0LHrVOWjta3u9F2/4f+noBrsUYvdIxfaa2NZ1jGzSfAqeZt8P/ABNwIjb\
+6yxhLeWmz7PvKC8txbiRbbRzdbM8UYurcC+01gdas1LrpXghEVTrHiJTO8cGsNE9sqojtFIy2LR3MMU\
+0yWUGmzXGJrtraC7s0XVdUcXeqa7FJv8Z61OzLJovxanzC8nxSmKSM9wPmj855EvSn+lR3Z/tzUudPs\
+mvrR/7W1htviXT7jf8A8Jxr7BTH4i8X3HnmQfFKTYqm6L+b50QUXIk+3wCYX2qTzbW67+6vw+Xpr94E\
+9rFGfsmb7TUz/Z2d+leCJNm7/hD8+Z9q1hfM2+ZJv87Zv+xXH2ny/tOs/ZMbwnFGfD/hfN9pq50bw3k\
+tpPgVwubLwRkuJ9ZCuF8yTf5pUP8AY7j7QUFzrP2TSstPsk/s/wD4m2sJs/sjr4419Nnlf8K9xnPxSh\
+8vb9gXP+o2fYjn7L9nb+w8vwta2kui+GJ31XVEd9L8MSsIvGetWsUbC0+G7kRwwfFKGO1jU2QwqeQkQ\
+siF+yi2P9hnN16/4Vbz/wCBp9wF2ONNl1/pVkMWWnkA2HhYlyfC2pSFEMmpBo5FdRE7xBp3nlS4uEj1\
+aO1tZPyg8fxRj/grdp2L7TXx8NP2NcbNK8ER79vw4/4OC8eX9l1hvL3eXHs8nfs+22/2bzPs2jfa/wB\
+VItLshHfD+0tZG/TdJjx/wmfiAb/K8C6zZCMD/hYa+YVExh27ZihlEBt7ZnGj3f5V/EG3tj/wVotIBq\
+mouk3w0/Y+yx8XavNM32n4d/8ABwq7bLlvibNIdxlTbtabIv3VPtK30g1/w+IpP6rgr2/37Leif/Mbh\
+zxs+/3Cj/2G5b/6ssIfrbdRRj7Xi+018f2jjZpXgiPft/4TDHl/ZdYby93lx7PJ37Pttv8AZvM+zaN9\
+rxtWijKEG+01APGekKHfSfAskbKPHPgpRMkd1rKwpbsrs6RRO1kkdvLHbzPaTajLBpXun2T/ANof8Tb\
+WH3/2v08ca++/zf8AhYWcY+KU3mbvt7Y/1+/7aMfavtC/25l31raW7zTJquqBpPHFo5aXxnrTowu/Hn\
+gHzLhTP8Uo1LlYTIk4mlYNbCePUJ3txfaX7sZXaTsk3/Kj2TbtYoz9kzfaamf7Ozv0rwRJs3f8IfnzP\
+tWsL5m3zJN/nbN/2K4+0+X9p1n7JRuY0GnSMLqyY/YoT5SWHhZJiTB4TJQT22pNcrIDI4LrGZybOcui\
+yXOrraz2Wn2Sf2f/AMTbWE2f2R18ca+mzyv+Fe4zn4pQ+Xt+wLn/AFGz7Ec/Zfs7f2Hm3ml2T6PNF/a\
+WssDpttH5Q8Z+IHJ22vgJfL8kfEOUsR9hA2/ZXI+xkfZ4/s7R6KRk+aO266L/ACANLijFlqWL7TXxrP\
+jPHl6T4Fi348QfEPAjFlrLiMt5abfJ3FDeW5gDtbaOLvZuoox9rxfaa+P7Rxs0rwRHv2/8Jhjy/susN\
+5e7y49nk79n223+zeZ9m0b7XiWtraXNpqrvquqMW1TxnF+68Z60quq618UoEJSD4pSiWR0uvmb9+8z3\
+u9/tUl1/xPNS90+yf+0P+JtrD7/7X6eONfff5v8AwsLOMfFKbzN329sf6/f9tGPtX2hf7cXNbRapd4q\
+/6/mBm61FGNX8Kj7dppB8ZxLuXSfAqoFNv4/QzNHFrJia3VUWRonYWTRXEUU8yWMOnzT7NrFGfsmb7T\
+Uz/Z2d+leCJNm7/hD8+Z9q1hfM2+ZJv87Zv+xXH2ny/tOs/ZMTWbW0XWfDG3VdUYS+OLR3d/GetTMgi\
+uPiNfi4imk+KUhtnWSRXM6TRMEumJ1CCO5a+1TUstPsk/s//ibawmz+yOvjjX02eV/wr3Gc/FKHy9v2\
+Bc/6jZ9iOfsv2dv7DOba3Xf3V+Hy9NfvAntYoz9kzfaamf7Ozv0rwRJs3f8ACH58z7VrC+Zt8yTf52z\
+f9iuPtPl/adZ+yeT6oiDwD4fxc2j4vPgvgJZeHI2fddaG7CNrW/ZoyjARyeSGMsrrNfCG/WGB/UbLT7\
+JP7P8A+JtrCbP7I6+ONfTZ5X/CvcZz8UofL2/YFz/qNn2I5+y/Z2/sPyTXdOtLnwJo8r3+ql7m/wDgj\
+I6Q+K9bjiZo/wCyYCsVtB44kRI4/NMYSOKRYN4hCafkabP35W75jge/tqPRbe1hf59vvujwOK1fhbiV\
+PZ5fjP8A1HqHW/FP4beCfi78OviT8J/iJZ6X4m+H3xP8FeOvh3458PeR4a0lPEPg3xpoXj7w14m0Yaj\
+4c8SQ3mlreaJfXUCz6fcRXNsNUt5NPmEtpoj3P5R+FP8AgkfZfDPwlr3wY+Gv7f37bNl8Kn+BE3wGn+\
+H3j7xn8Bfi34Ti+Et7o/jPwfbeE/Deg+LvBNzbeEhb+GfDdrZWOoabCuqWEGrsmk38Qa0Gp/sVe6fZP\
+/aH/E21h9/9r9PHGvvv83/hYWcY+KU3mbvt7Y/1+/7aMfavtC/25l3FraSa1r8B1XVGQaX5oK+M9aaV\
+2vLv4vI4eZfilLJcRsJ12K3npm9Yx/aTeN/bnhYvLsBj506mNwsMRLDqSjzRTXvrlknG6jJOLklzKVr\
+u1uZs/TOFeOeKuCauJrcM5r/Zs8Z7N1P3OHrqXspc9P3cRRrRXLO01ZL34U5u8qVNx/Bz9qTSPhr8Iv\
+ite/Cz4x/8FLf2z/ht4o+Klx4O/aO8R6f8EPh18E/h5JrwtvDHgb4CRX6fEvwL8P7Wfcnhv4f2NtdaH\
+NqMlmlxottrWo6Sl3e3t1bFe4fHb4i/tZ6V/wAFFr/4U/sfeCPgl4l8WS/sR/B34i+JPFP7Rv7Rnj7w\
+P4cs9G0v4wfELQ7Dwx4b8KeBPFV74g13WJ/E9n4cF3qkUcOjaFZhv7TNpfTaRb2JXweZ5Y8yryqUaGU\
+R9jOvTlGrk+a4urGUcRUSdTFYbPMHRq1KsOTET5aMXTlWcKn7yMm/6Bw3jHxnwxk/DuCp4nF4WNXAYS\
+olRzPJ8rhKPsacKTjg1lSqQoxw8aNKhOo6inTpr2dRxjyx/Z+9vd32/wD0/fv/ALW/5i3mb/M/4T//A\
+Kn+bzd32v8A6b+Z9u/5evtX/E9x/F17u0DxWf7Q3btH8UnP9r793mWXxG5z/wALCk8zd9r67pd/23rc\
+/as64XsOvr/aGPDujrs/tfGZr2LZ5f8AwsLGf+LPReTt+xx5/wBT5f2Q/wDHt9jH9iZfim31r+xfE6z\
+6BpcMA0vxOszxfa3lhiS0+JAd47d/hDADIiWakIWtwpsypa0FpnRP0mKvKPm11R/KJ1lte7b27b7ft3\
+eI9Qm3/wBrbN2/xB4Sm+0eZ/wn8e/d9n3+d50u/wCy+b/aE/kfb9LLK92/YP8AT9mz+yf+Yt5ezy/+E\
+A/6n+Hytv2T/ph5f2H/AJdfsv8AxIse2h19r67Q+HdHYL4l1GAL5165VU8ReEIRCYv+FPSeWwW5dPJ8\
+mPYbgQ/YIPtBsdTLKHX2/s/Ph3R23/2RnE17Lv8AM/4V7nH/ABZ6Xzt32yTH+u8z7WP+Pn7Yf7bVgDw\
+/e7b3Uv8AiYbfL1jQh/yF9nl+XoHwjOMf8LCi8nb9k6Yttn2LOLX7Lu0SezutukQx/a9mNNuU8r+0fL\
+xutfHa+X5H/CYRbc/a8bPsqZ+27fs8n2ny9bxNCt9aN3eGPQNLkeXVNCa4D/a9olk0X4SrshdfhDOb6\
+NoLpG3sJC73xj23QuA2uus08QNo8Mh0DRmJ025fzBeXsgJW18esH+0f8Ktl3AG0Q7/tTbfshbz4/sgk\
+0a2vda78v5P/AD/PswNLxBe7r3Tf+Jhu8zWNdH/IX3+Z5mgfFw4x/wALCl87d9r6Yud/23OLr7Vu1vY\
+ub3de2jfb923xHp82/wDtbft2eIPFs32jzP8AhP5Nm37Rv87zotn2rzf7Qg8/7fqnJ67b60LuzMmgaX\
+G8Wqa61uE+17TLHovxaXZM7fCGA2MawWrtvURlHsRHttRbltC1LmHX1vrRB4d0dQ3iXT4CvnXqFlfxF\
+4vhMPlf8Kej8xitsieT5Mm825h+wT/ZxY6ZFnptr5r+l8wNiyvdv2D/AE/Zs/sn/mLeXs8v/hAP+p/h\
+8rb9k/6YeX9h/wCXX7L/AMSLH8I3u3QPCh/tDbt0fwsc/wBr7Nvl2Xw55z/wsKPy9v2Trui2fYutt9l\
+zofzL+x/4t/a68c/Cix1H9rb4A+B/g/8AF2z8V3OkzaL4U8Rafrvh7xL4YEnw0vfD3irTLXQvDPisaI\
+s1rrdxYS2dzrWpXNxcaTLqJRINbgsNR+hvC1vrX9i+GFg0DS5oDpfhhYXl+1pLNE9p8NwjyW6fCGcCR\
+0vGJQNcBjeBQ12LvOt8mBxUcwwWHxtOjVw8MTGMlTr050K0OZfDUo1FGpCUXpJNaPZtNN+3xLkVfhjP\
+834exOYYHNq2UV6lB4rLcbh8xwGI5HZVsJjcJUqYfE0KitOnUhPZ2nGE1KEduK6xHfD7XjfpulJj+0d\
+u/wAvwRrFr5eP+EwXzNvmeTs2zbPN+zfZ7bzP7Gu/yP8Ai94p0Xw3/wAFVLrxL4l8T6XoPh3QfhB+yV\
+rmv6/rnia003RdG0XTfhd/wcQ3+q6xrGq3/wARWgsdLgsZJ5ri4mkkiSKd5JHuEuGbXP1XiTxAY74/2\
+Box2abpLg/bL1thk8C6zdlyf+FWt5QZ4hLv3Q+YIzdefcmP+17X8C/+Cj9vqy/tLftZM+h6dHOn7Cnw\
+82xqlyIlEX7Mn/ByCIi0x+FMBgIjtbgtiOHyW01FBtxAzeHvI4rqujllGulzOjisvlZ6X5cXh3b52Ph\
+OJ6rw+USrpczo4nL5pd3HMMK7fOx+t97+3/8AsNN9v/4zd/ZQff8A2t/zdB8IJN/mf8J//wBVwm83d9\
+r/AOm/mfbv+Xr7V/xPfUfAvxv+Efxp0XVfE/wa+MXw5+LHh3SfitZ6Bq/iL4ZfE/wz450XTfEcXi74V\
+69caNqOs+FfitLBa62NH1TRb54pbp5zbX9reNd3ERiv9O/nl/4Jm+BP2dvjp+wX4S+LPxA+L/xT8P8A\
+xF+AmgfGPwToXxG8eftMeLdI8S/snXOvfATSfA/j5PhBf2vgK00jQ/Ai+BtL8FaxpFrc2+o23hf+35N\
+Pt743lnfanb/f/wDwSu1z4heMfhV8btc8deDbnS9eu/2j/gvayv4h+Kug/HzxD4g0/Sf2R/8Agnjo/h\
+DxprHxY8HfDS+0z4gX/ibw1DoWvXWoWsjASeM5I2tGmd7XWPH4e4mzDNKuTSxNPDvDZ7S9tQdD2kuWC\
+pKcnWm5ShTqKpzU40pa1IJ1Yz5qWIo0f6q8TPCPhnhGjx3h8mxmaLNfDjHxy/MYZnHCUPaYipja2Hpr\
+A4ePJisThpYWNDF1MfGCpYarUjhatJ0sVluOx3682V7t+wf6fs2f2T/zFvL2eX/wgH/U/wAPlbfsn/T\
+Dy/sP/Lr9l/4kWdeXW7SJo/te/Om2yeV/aPmZ22vgRfL8j/hMJd2PsmNn2V8fYtv2eP7N5eiQWUOvt/\
+Z+fDujtv8A7Izia9l3+Z/wr3OP+LPS+du+2SY/13mfax/x8/bD/bebeJ4gXR5pBoGjKRpts/mG8vYwC\
+1r4CYv9o/4VbFtBN253/al3faw3nyfazJrP3cPij6o/nU0tPvd9lq3/ABMN+/WPHA/5C/m79+v/ABSG\
+M/8ACwp/N3fa+mZt/wBtxi4+1bdc2L293fb/APT9+/8Atb/mLeZv8z/hP/8Aqf5vN3fa/wDpv5n27/l\
+6+1f8T3k7W31qO01UQaBpZRdU8ZsTL9rs2SVda+KTTIET4QxiOOOe0Kq+YDssvMK2Zttuh6l7Dr6/2h\
+jw7o67P7Xxma9i2eX/AMLCxn/iz0Xk7fscef8AU+X9kP8Ax7fYx/YiaabWmnmgDXL3OteE2/tDOPHdt\
+Nv/ALX3Y2H4kz+f5n/Cwn27ftHmeb5qbPtPnfb7fz/7Q1PYsr3b9g/0/Zs/sn/mLeXs8v8A4QD/AKn+\
+Hytv2T/ph5f2H/l1+y/8SLk9Zt9a/tnwwsmgaXG3/CcWkUEafayszyXHxGt2tpVb4QxeWhtoJAIxBOZ\
+HtBanT5liNnpWpZQ6+39n58O6O2/+yM4mvZd/mf8ACvc4/wCLPS+du+2SY/13mfax/wAfP2w/22Wem2\
+vmv6XzA2LK92/YP9P2bP7J/wCYt5ezy/8AhAP+p/h8rb9k/wCmHl/Yf+XX7L/xIvIdYuN3w/0Ifad++\
+7+B4x9u8zf5P9jwY2/8JRN5vl7/AC8bJvK3+TjT9/8AZs/o1lDr7f2fnw7o7b/7Izia9l3+Z/wr3OP+\
+LPS+du+2SY/13mfax/x8/bD/AG35Jrq63H4E0fyNF0poI7/4I+RLNdXdpKYpv7JnR5Y0+HSi0kl8tJC\
+omQSbTMJNR8salD6GVL/hRwL/AOn1Hqv+fsP6vsjwOK/+SX4k/wCxfjP/AFHqHud7e7vt/wDp+/f/AG\
+t/zFvM3+Z/wn//AFP83m7vtf8A038z7d/y9fav+J7jzXu7X/EQ/tDfu0eE4/tfzN/m3vxh5x/wsKbzN\
+/2vrtm8z7b1vPtONbL2HX1/tDHh3R12f2vjM17Fs8v/AIWFjP8AxZ6Lydv2OPP+p8v7If8Aj2+xj+xM\
+u4t9aTWtfZdA0tZ10va6N9rhiiihu/i8bd0uB8IYiJN9rIHQrALcWCsrW5tyNC4EtJendd1/X/DM98+\
+EPjh+xh+zf+0/+1PB4g+NXhrxTrupx/ss2XwymvPDnxx+NHwsj1DwB4g8c6KviTwZrUfwt+OXh2HXdA\
+u47q5F5aXs08bLaQ+dbaeLC3k0gr6W02PXX/aOVDoWku//AApLwm/ki5vJl23HjvwqGl8v/hWE5LSG4\
+YBvshFx54BudS8/ytRKXE+QZJiKuVVauTYSpVqYKhKUp4ejzSlK8pSblC8nKTcnJ3bbbbe5+gw414x4\
+aw+XYPhzizM8gwdbC0Kk6WCx+KwtOdRpxdSVOhVpxlNxioubTk0kr2SPoW9stv2//QNmz+1v+YT5ezy\
+/+E//AOpAh8rb9k/6YeX9h/5dfsv/ABIsfxdZbdA8Vj+z9u3R/FIx/ZGzb5dl8RuMf8K9j8vb9k6bYt\
+n2LpbfZcaHnXXibw5/pn+n+FU/5CX3PE/w7fy/+Ry+59l01fM2Z+Xydm/+z4Ps3l/aNH+yZXifxDoNx\
+oniSCC58Myzz6V4ihhgg8S/DueR5ZbTxwkcMCW2ljz3DsojEIHmGxgFuE+06OLS4wldbPXuv8z8+O+t\
+rLde3a/YN23xHqEOz+yd+3Z4g8JQ/Z/L/wCEAk2bftGzyfJi2favK/s+Dz/sGqFlZbvsH+gb9/8AZP8\
+AzCfM3+Z/wgH/AFIE3m7vtf8A038z7d/y9fav+J7y0Hibw59ruP8AT/Crf8Ty9+RvE/w7VE/4nXhv/R\
+lkn01ongX/AFayxqtkyXcskMKWcOow3Ba+JvDn+h/6f4Vf/kG/f8T/AA7TzP8AkTfv/atNby9+Pm87f\
+s/tCf7T5n2fWPta5JeX3r/MDR8P2W691L/iX7vM1jQj/wAgjf5nmaB8IxnP/CvZfO3fa+ubnf8AbcZu\
+vtW3W57O13aRDJ9k35025fzf7O8zO218dt5nn/8ACHy7sfZM7/tT4+xbvtEf2bzNE5LRfEOgxXeovJc\
++GQlxqukTQPL4l+HcS3cS6J8NIGmU3WlnCNPBNG5mMmxrm5W5Mn2XWBdT23ibw5/ZsX/Ez8Mv/oM/75\
+vEfghJT/o/i/8AeGG5tGuVkGchWkM5NhCEdZLjSWtKcJWa0u+Xqu3r5r1voBv+ILLbe6b/AMS/b5esa\
+6f+QRs8vy9A+Lgzn/hXsXk7fsnXNts+xYza/ZduibFzZbb20X7Bt3eI9Ph2f2Ts3b/EHi2H7P5f/CAR\
+7932fZ5Pky7/ALL5X9nz+R9g0vgda8Q6DLd6c8dz4ZKW+q6vNO8XiX4dyraRNonxLgWZja6WMos88Ma\
+GEx72trZbYx/atHFrqz+JvDn2u3/0/wAKr/xPLL5F8T/Dtkf/AInXiT/Rmkg01Ykgb/VtLIrWSpaRST\
+QvZzadDbz7OWmm/mtfTXX/AD0A6myst32D/QN+/wDsn/mE+Zv8z/hAP+pAm83d9r/6b+Z9u/5evtX/A\
+BPcfwjZbtA8KD+z927R/Cwx/ZG/d5ll8OeMf8K9k8zd9r6bZd/23pc/asa5nWvibw5/of8Ap/hV/wDk\
+G/f8T/DtPM/5E37/ANq01vL34+bzt+z+0J/tPmfZ9Y+15XhjxDoNvonhuCe58MxTwaV4dhmgn8S/DuC\
+RJYrTwOkkM6XOlnyHLqwkEwPlm+nFwH+zawLs9nLe2nqrfffr07gdbFa5jvj9kzs03Snz/Z27Z5ngjW\
+LrzM/8Ie3l7vL87fuh3+V9p+0XPl/2zafiD+3/APBv9ozWP2svH3iP4dfsW/Fv9pn4YfEL9nb4QfD3x\
+Jf/AAv+I37MnwqbR4NF8M/8Fg/hN8RNEn1H456/4fvtL8Rw6J+194F1fTLiz0LUdOaDwvqcU9xp15p9\
+raaf+zEfibw5su/+Jn4ZP+g6fyfEfggFP+KT1MeYgktC0kj/AOvZYis6TQpBcPJqr211HBJ4h0Ea3rk\
+7XPhmKCXSoIY518S/Dt4zLDd/E95oYXtdLTznhS4gOISu4W9sbYRfatHNrw5plcM2wk8JUqyoxbpzjO\
+n7JyhOnKE4TSqwq0nyzjF8tSnOnKyjOMotxfNisJQxtFUMTT9rR9pSqOL2k6NWFaCfeLnTjzLrG66n8\
+mNr/wAE4fiToljb6VpH/BKP/gqFoWlaNF8QYdM0mx/4KYfsM6fpWkRfETwxq3gr4iRxabZeJ4YIF1fw\
+b4fsNI1wJHH/AGlpnhG4sLvNrHFFp/6Afst6r+2N+x78Pte+Gvw9/wCCQH7aPivQtb+KuieLJLz4qft\
+qfsC/ELxPpt5oml/BH4ZeHfA1nq83jGKSLQtO8MfDHwZo9laSxvFpy6nFbW8NvpuNNm/eO68TeHP9M/\
+0/wqn/ACEvueJ/h2/l/wDI5fc+y6avmbM/L5Ozf/Z8H2by/tGj/ZMrUfEOgzB0hufDNy48YafM0K+Jf\
+h3iOK38a+C7idA0+lvE1pDBFJmaNFsvJnmmhijs4NRjn+EynwwweS4mOKyriDH4TEJcqlGGUyaTSjZK\
+WWSSfKlFNK/L7q0dj9O4n8WvEfjTAvLeLOMcx4hy+VRVZUcVjcVWpyqRc5KU4yrNTtOcppSuvaP2lud\
+KS/OW1/bM/wCChn+ibf8Agin+0HP/AMg7bs/ap/YDf7R/yJ+zy/M+Icnmedi22bvN3/8ACSW/mef9ou\
+v7To3P7Zf/AAUK/s6Td/wRc+P0CfYoc3r/ALV37BCQovkeE8XTTR/E6OQRsBbuGE6uR4hgJldp7p9S/\
+T218TeHP9D/ANP8Kv8A8g37/if4dp5n/Im/f+1aa3l78fN52/Z/aE/2nzPs+sfa6Nz4m8Of2bL/AMTP\
+wyn+gwfvl8R+CHlH+j+EP3ghtrRblpDjJVZBODfzB3aS31Zrv6SPD2bKUX/rrmS1X/LvJf8A50nwHtY\
+f9A8Pvqf/ACw/Myz/AGyP+Cg8drqCxf8ABFj9oPYdS8VSSPJ+1J+wJa/ZZpdY8fS3cMiL8QototbiS9\
+jZ08sEeF7iSIwiG0OmaV1+2Z/wUM/0vd/wRT/aDg/5CO7f+1T+wGn2f/kcN/meX8Q4/L8nNzv2+Vs/4\
+Ru48vyPs9r/AGZ+jVj4h0GG01JJrnwzau2q+LplQ+Jfh2WWK41v4hzwTRi10uPzUMEsckRhC+atpbtb\
+lPtOjm01brxN4c/0z/T/AAqn/IS+54n+Hb+X/wAjl9z7Lpq+Zsz8vk7N/wDZ8H2by/tGj/ZF/q9m+z4\
+0zNPzp5Kn939kh7WH/QPD76n/AMsPy+1X9sj/AIKDvqnh5pv+CLH7QdtLF4sgktbRv2pP2BGe+uyfG8\
+Y0ZfL+ISpFcSJLexKrxtA8vh+W3a1ljW3tLLStf2zP+Chn+ibf+CKf7Qc//IO27P2qf2A3+0f8ifs8v\
+zPiHJ5nnYttm7zd/wDwklv5nn/aLr+0/wBGtX8Q6DJq3hp47nwyyW/jCCafyvEvw7kiiiI8eQBJ5YNL\
+EUNo888NuZpF+xKIoHmiezn06CDVtfE3hz/Q/wDT/Cr/APIN+/4n+HaeZ/yJv3/tWmt5e/Hzedv2f2h\
+P9p8z7PrH2s/1ezfT/jNMz1/6d5Lr6f8ACTr/AJ6B7WH/AEDw++p/8sPzQtf2zP8AgoZ/om3/AIIp/t\
+Bz/wDIO27P2qf2A3+0f8ifs8vzPiHJ5nnYttm7zd//AAklv5nn/aLr+0+Auf2sP+ChuseELPTNK/4I4\
+fHqFra18A6lZ6pP+09+wlNAkfh3S4datbq60+H4vWssdte2umtebVuLdvs8Mk073U8a3kX63Wvibw5/\
+of8Ap/hV/wDkG/f8T/DtPM/5E37/ANq01vL34+bzt+z+0J/tPmfZ9Y+1854f8QaDb6DZQT3vhyGeHw5\
+4ehmhm8Q+CIpbWWLwRfRyAxyWIJn3hpZEiEc8c9utvcM+qvbXMWtDI86w9WFelxtmUalGUZRfsckklK\
+MlKN1LKHF6q9mrO1mmro5cdh8HmOCxmXYzCRqYTH0qlGrFVK9OUqdWDhNKdOrCpBuMmlOEozi3eMlJJ\
+r8vp/2vf+CqP+k+Z/wR8+J0P/H75ufjX+w/D5OP+El+0Z2ftGL5HlbdWzt2eV/Yj7PL+w2/2PNb9rr/\
+AIKljWNXlf8A4JBfE+OdtNt47q3Pxm/YhgFpDFdePmMxuE/aLQKQ768pRSht/wDhHGZRF9ltvsf67XX\
+ibw5/pn+n+FU/5CX3PE/w7fy/+Ry+59l01fM2Z+Xydm/+z4Ps3l/aNH+yZUniHQRreuTtc+GYoJdKgh\
+jnXxL8O3jMsN38T3mhhe10tPOeFLiA4hK7hb2xthF9q0c2vSsuz7X/AIzHGf8AhDw53X/Uk/rTueV/q\
+/lf/UZ/4ds4/wDngfj5bftG/wDBVAfESPx9F/wSM+KUzS+C9L8HxaT/AMLm/YlnilEOuaDrVvqKTy/t\
+MvG8kxudJiKC3LzjWIjNNOt26XJX7MWvibw5/of+n+FX/wCQb9/xP8O08z/kTfv/AGrTW8vfj5vO37P\
+7Qn+0+Z9n1j7WVeKw/E2J9h7TjLFVvYQjTjfAcNe7CHwxX/CGr2vu7va72OmplWBrey9rPGT9hCNON8\
+0zbSEW3GP+/a2u9Xdvq3ZHU3t7u+3/AOn79/8Aa3/MW8zf5n/Cf/8AU/zebu+1/wDTfzPt3/L19q/4n\
+uP4uvd2geKz/aG7do/ik5/tffu8yy+I3Of+FhSeZu+19d0u/wC29bn7VnXCivTjuvU9A2La923t232/\
+bu8R6hNv/tbZu3+IPCU32jzP+E/j37vs+/zvOl3/AGXzf7Qn8j7fpZZXu37B/p+zZ/ZP/MW8vZ5f/CA\
+f9T/D5W37J/0w8v7D/wAuv2X/AIkRRSAx/D97tvdS/wCJht8vWNCH/IX2eX5egfCM4x/wsKLydv2Tpi\
+22fYs4tfsu7RJ7O626RDH9r2Y025Tyv7R8vG618dr5fkf8JhFtz9rxs+ypn7bt+zyfafL1soq38L9Y/\
+kwIPEF7uvdN/wCJhu8zWNdH/IX3+Z5mgfFw4x/wsKXzt32vpi53/bc4uvtW7W9i5vd17aN9v3bfEenz\
+b/7W37dniDxbN9o8z/hP5Nm37Rv87zotn2rzf7Qg8/7fqhRUAFle7fsH+n7Nn9k/8xby9nl/8IB/1P8\
+AD5W37J/0w8v7D/y6/Zf+JFj+Eb3boHhQ/wBobduj+Fjn+19m3y7L4c85/wCFhR+Xt+ydd0Wz7F1tvs\
+udDKKAJ4rrEd8PteN+m6UmP7R27/L8Eaxa+Xj/AITBfM2+Z5OzbNs837N9ntvM/sa7gmvd2v8AiIf2h\
+v3aPCcf2v5m/wA29+MPOP8AhYU3mb/tfXbN5n23refaca2UVct3/hj+SA2L293fb/8AT9+/+1v+Yt5m\
+/wAz/hP/APqf5vN3fa/+m/mfbv8Al6+1f8T3H1O92mR/7Q2bvHemzb/7X8vd5nxA+H8vn+b/AMLCh8z\
+d9n3+b58u/wCzeb9vufI+26YUVMd16gbFle7fsH+n7Nn9k/8AMW8vZ5f/AAgH/U/w+Vt+yf8ATDy/sP\
+8Ay6/Zf+JFnXl1u0iaP7Xvzptsnlf2j5mdtr4EXy/I/wCEwl3Y+yY2fZXx9i2/Z4/s3l6IUU4fHH1X5\
+gQafe77LVv+Jhv36x44H/IX83fv1/4pDGf+FhT+bu+19Mzb/tuMXH2rbrmxe3u77f8A6fv3/wBrf8xb\
+zN/mf8J//wBT/N5u77X/ANN/M+3f8vX2r/ielFSBj65e51rwm39oZx47tpt/9r7sbD8SZ/P8z/hYT7d\
+v2jzPN81Nn2nzvt9v5/8AaGp7Fle7fsH+n7Nn9k/8xby9nl/8IB/1P8Plbfsn/TDy/sP/AC6/Zf8AiR\
+FFABZXu37B/p+zZ/ZP/MW8vZ5f/CAf9T/D5W37J/0w8v7D/wAuv2X/AIkXLeGbr/inLD/TPv8AhXwun\
+/IS/wBZs+HepWuz/kcv323zfJ2/6Rs837N5Fv5n9j3ZRVR2n6fqgOpvb3d9v/0/fv8A7W/5i3mb/M/4\
+T/8A6n+bzd32v/pv5n27/l6+1f8AE9x5r3dr/iIf2hv3aPCcf2v5m/zb34w84/4WFN5m/wC19ds3mfb\
+et59pxrZRSW0vT9UBsWV7t+wf6fs2f2T/AMxby9nl/wDCAf8AU/w+Vt+yf9MPL+w/8uv2X/iRFFFc1f\
+7Hz/QqO/3fmj//2Q=='
+ $end 'DesignInfo'
+$end 'ProjectPreview'
diff --git a/_unittest_solvers/example_models/T45/components.json b/_unittest_solvers/example_models/T45/components.json
new file mode 100644
index 00000000000..3af202036b6
--- /dev/null
+++ b/_unittest_solvers/example_models/T45/components.json
@@ -0,0 +1,19 @@
+{
+ "components": [
+ {
+ "reference_designator": "U1",
+ "part_type": "io",
+ "solder_ball_properties": {
+ "shape": "cylinder",
+ "diameter": "244um",
+ "height": "406um"
+ },
+ "port_properties": {
+ "reference_offset": "0.1mm",
+ "reference_size_auto": true,
+ "reference_size_x": 0,
+ "reference_size_y": 0
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/_unittest_solvers/example_models/T45/expression_catalog_custom.toml b/_unittest_solvers/example_models/T45/expression_catalog_custom.toml
new file mode 100644
index 00000000000..dce3f726b87
--- /dev/null
+++ b/_unittest_solvers/example_models/T45/expression_catalog_custom.toml
@@ -0,0 +1,13 @@
+[e_field_magnitude]
+name = "EField_magnitude"
+description = "E field magnitude"
+design_type = ["HFSS"]
+fields_type = ["Fields"]
+solution_type = ""
+primary_sweep = "Freq"
+assignment = ""
+assignment_type = ["Line", "Face", "Solid"]
+operations = ["Fundamental_Quantity('E')",
+ "Operation('Mag')"
+]
+report = ["Field_3D", "Rectangular Plot"]
diff --git a/_unittest_solvers/example_models/T45/fields_calculator_solved.aedtz b/_unittest_solvers/example_models/T45/fields_calculator_solved.aedtz
new file mode 100644
index 00000000000..8e79c239299
Binary files /dev/null and b/_unittest_solvers/example_models/T45/fields_calculator_solved.aedtz differ
diff --git a/_unittest_solvers/example_models/T45/maxwell_fields_calculator.aedtz b/_unittest_solvers/example_models/T45/maxwell_fields_calculator.aedtz
new file mode 100644
index 00000000000..cf87ea18eaf
Binary files /dev/null and b/_unittest_solvers/example_models/T45/maxwell_fields_calculator.aedtz differ
diff --git a/_unittest_solvers/example_models/T45/ports.json b/_unittest_solvers/example_models/T45/ports.json
new file mode 100644
index 00000000000..51f910ad913
--- /dev/null
+++ b/_unittest_solvers/example_models/T45/ports.json
@@ -0,0 +1,35 @@
+{
+ "ports": [
+ {
+ "name": "COAX_U1_AM17",
+ "reference_designator": "U1",
+ "type": "coax",
+ "positive_terminal": {
+ "pin": "AM17"
+ }
+ },
+ {
+ "name": "COAX_U1_PCIe_Gen4_TX2_CAP_N",
+ "reference_designator": "U1",
+ "type": "coax",
+ "positive_terminal": {
+ "net": "PCIe_Gen4_TX2_CAP_N"
+ }
+ },
+ {
+ "name": "CIRCUIT_U7_VDD_DDR_GND",
+ "reference_designator": "U7",
+ "type": "circuit",
+ "distributed": true,
+ "positive_terminal": {
+ "net": "VDD_DDR"
+ },
+ "negative_terminal": {
+ "nearest_pin": {
+ "reference_net": "GND",
+ "search_radius": 5e-3
+ }
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/_unittest_solvers/example_models/T45/stackup.json b/_unittest_solvers/example_models/T45/stackup.json
new file mode 100644
index 00000000000..692870ac08e
--- /dev/null
+++ b/_unittest_solvers/example_models/T45/stackup.json
@@ -0,0 +1,95 @@
+{
+ "stackup": {
+ "materials": [
+ {
+ "name": "copper",
+ "conductivity": 570000000
+ },
+ {
+ "name": "Megtron4",
+ "permittivity": 3.77,
+ "dielectric_loss_tangent": 0.005
+ },
+ {
+ "name": "Megtron4_2",
+ "permittivity": 3.77,
+ "dielectric_loss_tangent": 0.005
+ },
+ {
+ "name": "Solder Resist",
+ "permittivity": 4,
+ "dielectric_loss_tangent": 0
+ }
+ ],
+ "layers": [
+ {
+ "fill_material": "Solder Resist",
+ "material": "copper",
+ "name": "1_Top",
+ "thickness": "0.5mm",
+ "type": "signal"
+ },
+ {
+ "fill_material": "Megtron4",
+ "material": "copper",
+ "name": "Inner1",
+ "thickness": "0.017mm",
+ "type": "signal"
+ },
+ {
+ "material": "Megtron4",
+ "name": "DE2",
+ "thickness": "0.088mm",
+ "type": "dielectric"
+ },
+ {
+ "material": "Megtron4",
+ "name": "DE3",
+ "thickness": "0.1mm",
+ "type": "dielectric"
+ },
+ {
+ "fill_material": "Megtron4",
+ "material": "copper",
+ "name": "Inner2",
+ "thickness": "0.017mm",
+ "type": "signal"
+ },
+ {
+ "fill_material": "Megtron4",
+ "material": "copper",
+ "name": "Inner3",
+ "thickness": "0.017mm",
+ "type": "signal"
+ },
+ {
+ "fill_material": "Megtron4",
+ "material": "copper",
+ "name": "Inner4",
+ "thickness": "0.017mm",
+ "type": "signal"
+ },
+ {
+ "fill_material": "Megtron4",
+ "material": "copper",
+ "name": "Inner5",
+ "thickness": "0.017mm",
+ "type": "signal"
+ },
+ {
+ "fill_material": "Megtron4",
+ "material": "copper",
+ "name": "Inner6",
+ "thickness": "0.017mm",
+ "type": "signal"
+ },
+ {
+ "fill_material": "Solder Resist",
+ "material": "copper",
+ "name": "16_Bottom",
+ "thickness": "0.035mm",
+ "type": "signal"
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/_unittest_solvers/test_00_analyze.py b/_unittest_solvers/test_00_analyze.py
index a591033740c..b1606b1e9a1 100644
--- a/_unittest_solvers/test_00_analyze.py
+++ b/_unittest_solvers/test_00_analyze.py
@@ -10,7 +10,7 @@
from pathlib import Path
-from pyaedt import is_linux
+from pyaedt.generic.settings import is_linux
from pyaedt import Icepak
from pyaedt import Hfss3dLayout
from pyaedt import Circuit, Maxwell3d
@@ -37,28 +37,28 @@
def sbr_platform(add_app):
app = add_app(project_name=sbr_platform_name, subfolder=test_subfolder)
yield app
- app.close_project(save_project=False)
+ app.close_project(save=False)
@pytest.fixture()
def array(add_app):
app = add_app(project_name=array_name, subfolder=test_subfolder)
yield app
- app.close_project(save_project=False)
+ app.close_project(save=False)
@pytest.fixture()
def sbr_app(add_app):
app = add_app(project_name="SBR_test", solution_type="SBR+")
yield app
- app.close_project(save_project=False)
+ app.close_project(save=False)
@pytest.fixture()
def hfss_app(add_app):
app = add_app(project_name="Hfss_test")
yield app
- app.close_project(save_project=False)
+ app.close_project(save=False)
@pytest.fixture(scope="class")
@@ -108,18 +108,25 @@ def init(self, local_scratch, icepak_app, hfss3dl_solve):
@pytest.mark.skipif(is_linux or sys.version_info < (3, 8), reason="Not supported.")
def test_01a_sbr_link_array(self, sbr_platform, array):
assert sbr_platform.create_sbr_linked_antenna(array, target_cs="antenna_CS", field_type="farfield")
- sbr_platform.analyze(cores=6)
+ profile = sbr_platform.setups[0].get_profile()
+ assert profile is None
+ sbr_platform.analyze(cores=4)
+ profile = sbr_platform.setups[0].get_profile()
+ assert isinstance(profile, dict)
+ assert not sbr_platform.get_profile("Invented_setup")
+
ffdata = sbr_platform.get_antenna_ffd_solution_data(frequencies=12e9, sphere="3D")
ffdata2 = sbr_platform.get_antenna_ffd_solution_data(frequencies=12e9, sphere="3D", overwrite=False)
ffdata.plot_2d_cut(quantity="RealizedGain", primary_sweep="theta", secondary_sweep_value=[75], theta=20,
- title="Azimuth at {}Hz".format(ffdata.frequency), quantity_format="dB10",
+ title="Azimuth at {}Hz".format(ffdata.frequency), quantity_format="dB10", show=False,
image_path=os.path.join(self.local_scratch.path, "2d1_array.jpg"))
assert os.path.exists(os.path.join(self.local_scratch.path, "2d1_array.jpg"))
ffdata2.polar_plot_3d_pyvista(quantity="RealizedGain",
rotation=[[1, 0.0, 0.0], [0.0, 0.0, 1.0], [0.0, 1.0, 0.0]],
- image_path=os.path.join(self.local_scratch.path, "3d2_array.jpg"), show=False,
+ image_path=os.path.join(self.local_scratch.path, "3d2_array.jpg"),
+ show=False,
convert_to_db=True)
assert os.path.exists(os.path.join(self.local_scratch.path, "3d2_array.jpg"))
@@ -176,7 +183,7 @@ def test_02_hfss_export_results(self, hfss_app):
setup.props["Frequency"] = "1GHz"
exported_files = hfss_app.export_results()
assert len(exported_files) == 0
- hfss_app.analyze_setup(name="test", cores=6)
+ hfss_app.analyze_setup(name="test", cores=4)
exported_files = hfss_app.export_results()
assert len(exported_files) == 39
exported_files = hfss_app.export_results(
@@ -214,7 +221,7 @@ def test_03a_icepak_analyze_and_export_summary(self):
monitor_quantity=["Temperature", "HeatFlowRate"],
monitor_name="test_monitor2",
)
- self.icepak_app.analyze("SetupIPK", cores=6)
+ self.icepak_app.analyze("SetupIPK", cores=4)
self.icepak_app.save_project()
assert self.icepak_app.export_summary(
self.icepak_app.working_directory, geometryType="Surface", variationlist=[], filename="A"
@@ -321,14 +328,14 @@ def test_04a_3dl_generate_mesh(self):
@pytest.mark.skipif(desktop_version < "2023.2", reason="Working only from 2023 R2")
def test_04b_3dl_analyze_setup(self):
- assert self.hfss3dl_solve.analyze_setup("Setup1", cores=6, blocking=False)
+ assert self.hfss3dl_solve.analyze_setup("Setup1", cores=4, blocking=False)
assert self.hfss3dl_solve.are_there_simulations_running
assert self.hfss3dl_solve.stop_simulations()
while self.hfss3dl_solve.are_there_simulations_running:
time.sleep(1)
def test_04c_3dl_analyze_setup(self):
- assert self.hfss3dl_solve.analyze_setup("Setup1", cores=6)
+ assert self.hfss3dl_solve.analyze_setup("Setup1", cores=4)
self.hfss3dl_solve.save_project()
assert os.path.exists(self.hfss3dl_solve.export_profile("Setup1"))
assert os.path.exists(self.hfss3dl_solve.export_mesh_stats("Setup1"))
@@ -406,13 +413,13 @@ def test_06_m3d_harmonic_forces(self, m3dtransient):
use_number_of_last_cycles=True, last_cycles_number=3,
calculate_force="Harmonic")
m3dtransient.save_project()
- m3dtransient.analyze(m3dtransient.active_setup, cores=2, use_auto_settings=False)
+ m3dtransient.analyze(m3dtransient.active_setup, cores=4, use_auto_settings=False)
assert m3dtransient.export_element_based_harmonic_force(start_frequency=1, stop_frequency=100,
number_of_frequency=None)
assert m3dtransient.export_element_based_harmonic_force(number_of_frequency=5)
def test_07_export_maxwell_fields(self, m3dtransient):
- m3dtransient.analyze(m3dtransient.active_setup, cores=2, use_auto_settings=False)
+ m3dtransient.analyze(m3dtransient.active_setup, cores=4, use_auto_settings=False)
fld_file_3 = os.path.join(self.local_scratch.path, "test_fld_3.fld")
assert m3dtransient.post.export_field_file(quantity="Mag_B", solution=m3dtransient.nominal_sweep, variations={},
output_dir=fld_file_3, assignment="Coil_A2", objects_type="Surf",
diff --git a/_unittest_solvers/test_26_emit.py b/_unittest_solvers/test_26_emit.py
index bde7c4b6a38..3ccc018fcb5 100644
--- a/_unittest_solvers/test_26_emit.py
+++ b/_unittest_solvers/test_26_emit.py
@@ -5,18 +5,19 @@
from _unittest_solvers.conftest import config
import pytest
-
-from pyaedt import Emit
-from pyaedt import generate_unique_project_name
-from pyaedt.emit_core.emit_constants import EmiCategoryFilter
-from pyaedt.emit_core.emit_constants import InterfererType
-from pyaedt.emit_core.emit_constants import ResultType
-from pyaedt.emit_core.emit_constants import TxRxMode
-from pyaedt.generic import constants as consts
from pyaedt.generic.general_methods import is_linux
-from pyaedt.modeler.circuits.PrimitivesEmit import EmitAntennaComponent
-from pyaedt.modeler.circuits.PrimitivesEmit import EmitComponent
-from pyaedt.modeler.circuits.PrimitivesEmit import EmitComponents
+from pyaedt.generic import constants as consts
+
+if (3,7) < sys.version_info <(3, 12):
+ from pyaedt import Emit
+ from pyaedt import generate_unique_project_name
+ from pyaedt.emit_core.emit_constants import EmiCategoryFilter
+ from pyaedt.emit_core.emit_constants import InterfererType
+ from pyaedt.emit_core.emit_constants import ResultType
+ from pyaedt.emit_core.emit_constants import TxRxMode
+ from pyaedt.modeler.circuits.PrimitivesEmit import EmitAntennaComponent
+ from pyaedt.modeler.circuits.PrimitivesEmit import EmitComponent
+ from pyaedt.modeler.circuits.PrimitivesEmit import EmitComponents
TEST_SUBFOLDER = "T26"
TEST_REVIEW_FLAG = True
@@ -29,7 +30,8 @@ def aedtapp(add_app):
@pytest.mark.skipif(is_linux, reason="Emit API fails on linux.")
-@pytest.mark.skipif(sys.version_info < (3,8), reason="Emit API is only available for Python 3.8+.")
+@pytest.mark.skipif(is_linux, reason="Emit API fails on linux.")
+@pytest.mark.skipif(sys.version_info < (3,8) or sys.version_info >=(3, 12), reason="Emit API is only available for Python 3.8+.")
class TestClass:
@pytest.fixture(autouse=True)
diff --git a/_unittest_solvers/test_31_Q3D.py b/_unittest_solvers/test_31_Q3D.py
index 9b68473a1c8..1d92c2a22fc 100644
--- a/_unittest_solvers/test_31_Q3D.py
+++ b/_unittest_solvers/test_31_Q3D.py
@@ -188,7 +188,7 @@ def test_07B_create_source_tosheet(self):
assert len(obj_list[self.aedtapp.nets[0]]) == 0
def test_08_create_faceted_bondwire(self):
- self.aedtapp.load_project(self.test_project, close_active_proj=True, save_active_project=False)
+ self.aedtapp.load_project(self.test_project, close_active=True, set_active=False)
test = self.aedtapp.modeler.create_faceted_bondwire_from_true_surface("bondwire_example", self.aedtapp.AXIS.Z,
min_size=0.2, number_of_segments=8)
assert test
@@ -270,7 +270,7 @@ def test_13_matrix_reduction(self, add_app):
assert q3d.matrices[0].get_sources_for_plot(first_element_filter="Box?", second_element_filter="B*2") == [
"C(Box1,Box1_2)"
]
- self.aedtapp.close_project(q3d.project_name, save_project=False)
+ self.aedtapp.close_project(q3d.project_name, save=False)
def test_14_edit_sources(self, add_app):
q3d = add_app(application=Q3d, project_name=self.test_matrix, just_open=True)
@@ -306,7 +306,7 @@ def test_14_edit_sources(self, add_app):
sources_dc = {"Box1:Source1": ["20v"]}
assert q3d.edit_sources(None, None, sources_dc)
- self.aedtapp.close_project(q3d.project_name, save_project=False)
+ self.aedtapp.close_project(q3d.project_name, save=False)
def test_15_export_matrix_data(self, add_app):
q3d = add_app(application=Q3d, project_name=self.test_matrix, just_open=True)
@@ -370,7 +370,7 @@ def test_15_export_matrix_data(self, add_app):
assert not q3d.export_matrix_data(file_name=os.path.join(self.local_scratch.path, "test.txt"), c_unit="H")
assert q3d.export_matrix_data(file_name=os.path.join(self.local_scratch.path, "test.txt"), g_unit="fSie")
assert not q3d.export_matrix_data(file_name=os.path.join(self.local_scratch.path, "test.txt"), g_unit="A")
- self.aedtapp.close_project(q3d.project_name, save_project=False)
+ self.aedtapp.close_project(q3d.project_name, save=False)
def test_16_export_equivalent_circuit(self, add_app):
test_matrix2 = self.local_scratch.copyfile(
@@ -415,7 +415,7 @@ def test_16_export_equivalent_circuit(self, add_app):
output_file=os.path.join(self.local_scratch.path, "test_export_circuit.cir"), model="test_14")
assert not q3d.export_equivalent_circuit(
output_file=os.path.join(self.local_scratch.path, "test_export_circuit.cir"), model="test")
- self.aedtapp.close_project(q3d.project_name, save_project=False)
+ self.aedtapp.close_project(q3d.project_name, save=False)
def test_17_export_results_q3d(self, add_app):
q3d = add_app(application=Q3d, project_name=self.test_matrix, just_open=True)
@@ -429,7 +429,7 @@ def test_17_export_results_q3d(self, add_app):
q3d.analyze(cores=6)
exported_files = q3d.export_results()
assert len(exported_files) > 0
- q3d.close_project(q3d.project_name, save_project=False)
+ q3d.close_project(q3d.project_name, save=False)
def test_18_set_variable(self):
self.aedtapp.variable_manager.set_variable("var_test", expression="123")
diff --git a/_unittest_solvers/test_45_workflows.py b/_unittest_solvers/test_45_workflows.py
index 7e830c56294..7097a61b170 100644
--- a/_unittest_solvers/test_45_workflows.py
+++ b/_unittest_solvers/test_45_workflows.py
@@ -3,14 +3,16 @@
import shutil
import pyaedt
-from pyaedt import is_linux
-# from _unittest_solvers.conftest import local_path as solver_local_path
+from pyaedt.generic.settings import is_linux
from _unittest.conftest import local_path
+from _unittest_solvers.conftest import local_path as solver_local_path
push_project = "push_excitation"
export_3d_project = "export"
twinbuilder_circuit = "TB_test"
report = "report"
+fields_calculator = "fields_calculator_solved"
+m2d_electrostatic = "maxwell_fields_calculator"
test_subfolder = "T45"
@@ -150,6 +152,150 @@ def test_07_twinbuilder_convert_circuit(self, add_app):
assert main({"is_test": True})
- circuit = pyaedt.Circuit()
- assert len(circuit.modeler.schematic.components) == 10
+ def test_08_configure_a3d(self, local_scratch):
+ from pyaedt.workflows.project.configure_edb import main
+
+ configuration_path = shutil.copy(os.path.join(solver_local_path, "example_models", "T45", "ports.json"),
+ os.path.join(local_scratch.path, "ports.json"))
+ file_path = os.path.join(local_scratch.path, "ANSYS-HSD_V1.aedb")
+ local_scratch.copyfolder(os.path.join(solver_local_path, "example_models", "T45", "ANSYS-HSD_V1.aedb"),
+ file_path)
+
+ assert main({"is_test": True, "aedb_path": file_path, "configuration_path": configuration_path})
+
+ def test_08_advanced_fields_calculator_non_general(self, add_app):
+ aedtapp = add_app(application=pyaedt.Hfss,
+ project_name=fields_calculator,
+ subfolder=test_subfolder)
+
+ assert isinstance(aedtapp.post.fields_calculator.expression_names, list)
+ name = aedtapp.post.fields_calculator.add_expression("voltage_line", "Polyline1")
+ assert name == "Voltage_Line"
+ name2 = aedtapp.post.fields_calculator.add_expression("voltage_line", "Polyline1")
+ assert name == name2
+ assert not aedtapp.post.fields_calculator.expression_plot("voltage_line_invented", "Polyline1", [name])
+ assert aedtapp.post.fields_calculator.expression_plot("voltage_line", "Polyline1", [name])
+ assert aedtapp.post.fields_calculator.delete_expression(name)
+ assert aedtapp.post.fields_calculator.delete_expression()
+ assert not aedtapp.post.fields_calculator.is_expression_defined(name)
+ assert not aedtapp.post.fields_calculator.add_expression("voltage_line", "Polyline1_invented")
+ assert not aedtapp.post.fields_calculator.add_expression("voltage_line", "inner")
+ assert not aedtapp.post.fields_calculator.add_expression("voltage_line", 500)
+
+ from pyaedt.workflows.project.advanced_fields_calculator import main
+
+ assert main({"is_test": True,
+ "setup": "Setup1 : LastAdaptive",
+ "calculation": "voltage_line",
+ "assignment": ["Polyline1", "Polyline2"]})
+
+ assert len(aedtapp.post.all_report_names) == 6
+
+ assert not main({"is_test": True,
+ "setup": "Setup1 : LastAdaptive",
+ "calculation": "",
+ "assignment": ["Polyline1", "Polyline2"]})
+
+ assert not main({"is_test": True,
+ "setup": "Setup1 : LastAdaptive",
+ "calculation": "voltage_line_invented",
+ "assignment": ["Polyline1", "Polyline2"]})
+
+ aedtapp.close_project(aedtapp.project_name)
+
+ def test_09_advanced_fields_calculator_general(self, add_app):
+ aedtapp = add_app(application=pyaedt.Q3d,
+ project_name=fields_calculator,
+ subfolder=test_subfolder)
+
+ initial_catalog = len(aedtapp.post.fields_calculator.expression_names)
+ example_file = os.path.join(solver_local_path, "example_models",
+ test_subfolder,
+ "expression_catalog_custom.toml")
+ new_catalog = aedtapp.post.fields_calculator.load_expression_file(example_file)
+ assert initial_catalog != len(new_catalog)
+ assert new_catalog == aedtapp.post.fields_calculator.expression_catalog
+ assert not aedtapp.post.fields_calculator.add_expression("e_field_magnitude", "Polyline1")
+ assert not aedtapp.post.fields_calculator.load_expression_file("invented.toml")
+
+ from pyaedt.workflows.project.advanced_fields_calculator import main
+
+ assert main({"is_test": True,
+ "setup": "Setup1 : LastAdaptive",
+ "calculation": "voltage_drop",
+ "assignment": ["Face9", "inner"]})
+
+ assert len(aedtapp.post.ofieldsreporter.GetChildNames()) == 2
+
+ aedtapp.close_project(aedtapp.project_name)
+
+ aedtapp = add_app(application=pyaedt.Maxwell2d,
+ project_name=m2d_electrostatic,
+ design_name="e_tangential",
+ subfolder=test_subfolder)
+ name = aedtapp.post.fields_calculator.add_expression("e_line", None)
+ assert name
+ assert aedtapp.post.fields_calculator.expression_plot("e_line", "Poly1", [name])
+
+ assert main({"is_test": True,
+ "setup": "MySetupAuto : LastAdaptive",
+ "calculation": "e_line",
+ "assignment": ["Polyl1"]})
+
aedtapp.close_project(aedtapp.project_name)
+
+ aedtapp = add_app(application=pyaedt.Maxwell2d,
+ project_name=m2d_electrostatic,
+ design_name="stress_tensor",
+ subfolder=test_subfolder)
+ name = aedtapp.post.fields_calculator.add_expression("radial_stress_tensor", None)
+ assert name
+ assert aedtapp.post.fields_calculator.expression_plot("radial_stress_tensor", "Polyline1", [name])
+ name = aedtapp.post.fields_calculator.add_expression("tangential_stress_tensor", None)
+ assert name
+ assert aedtapp.post.fields_calculator.expression_plot("tangential_stress_tensor", "Polyline1", [name])
+
+ aedtapp.close_project(aedtapp.project_name)
+
+ def test_10_push_excitation_3dl(self, local_scratch, desktop):
+ from pyaedt.workflows.hfss3dlayout.push_excitation_from_file_3dl import main
+
+ project_path = shutil.copy(os.path.join(local_path, "example_models",
+ "T41",
+ "test_post_3d_layout_solved_23R2.aedtz"),
+ os.path.join(local_scratch.path, "test_post_3d_layout_solved_23R2.aedtz"))
+
+ h3d = pyaedt.Hfss3dLayout(project_path, version=desktop.aedt_version_id, port=str(desktop.port))
+
+ file_path = os.path.join(local_path, "example_models", "T20", "Sinusoidal.csv")
+ assert main({"is_test": True, "file_path": file_path, "choice": ""})
+ h3d.save_project()
+ assert not h3d.design_datasets
+
+ # Correct choice
+ assert main({"is_test": True, "file_path": file_path, "choice": "Port1"})
+ h3d.save_project()
+ # In 3D Layout datasets are not retrieved
+ # assert h3d.design_datasets
+ h3d.close_project(h3d.project_name)
+
+ def test_11_cutout(self, add_app, local_scratch):
+ from pyaedt.workflows.hfss3dlayout.cutout import main
+
+
+ app = add_app("ANSYS-HSD_V1", application=pyaedt.Hfss3dLayout, subfolder=test_subfolder)
+
+ assert main({"is_test": True, "choice": "ConvexHull",
+ "signals": ["DDR4_A0"],
+ "reference": ["GND"],
+ "expansion_factor": 3,
+ "fix_disjoints": True, })
+ app.close_project()
+ def test_12_export_layout(self, add_app, local_scratch):
+ from pyaedt.workflows.hfss3dlayout.export_layout import main
+
+
+ app = add_app("ANSYS-HSD_V1", application=pyaedt.Hfss3dLayout, subfolder=test_subfolder)
+
+ assert main({"is_test": True, "export_ipc": True, "export_configuration": True, "export_bom": True })
+ app.close_project()
diff --git a/doc/source/_static/logo.png b/doc/source/_static/logo.png
new file mode 100644
index 00000000000..2e9d129d87e
Binary files /dev/null and b/doc/source/_static/logo.png differ
diff --git a/doc/source/conf.py b/doc/source/conf.py
index 4e3a6246035..adcdfbfcdd0 100644
--- a/doc/source/conf.py
+++ b/doc/source/conf.py
@@ -353,16 +353,16 @@ def setup(app):
},
}
-# Add button to download PDF
-html_theme_options["icon_links"].append(
- {
- "name": "Download documentation in PDF",
- # NOTE: Changes to this URL must be reflected in CICD documentation build
- "url": f"https://{cname}/version/{switcher_version}/_static/assets/download/pyaedt.pdf",
- # noqa: E501
- "icon": "fa fa-file-pdf fa-fw",
- }
-)
+# # Add button to download PDF
+# html_theme_options["icon_links"].append(
+# {
+# "name": "Download documentation in PDF",
+# # NOTE: Changes to this URL must be reflected in CICD documentation build
+# "url": f"https://{cname}/version/{switcher_version}/_static/assets/download/pyaedt.pdf",
+# # noqa: E501
+# "icon": "fa fa-file-pdf fa-fw",
+# }
+# )
html_static_path = ["_static"]
diff --git a/doc/source/create_documentation.bat b/doc/source/create_documentation.bat
index bb57ace6ba6..c3c306b674d 100644
--- a/doc/source/create_documentation.bat
+++ b/doc/source/create_documentation.bat
@@ -1 +1,2 @@
+set PYAEDT_DOC_RUN_EXAMPLES=1
sphinx-build -b html -a . ../../../PyAEDT-docs_dev -j 4
diff --git a/doc/source/index.rst b/doc/source/index.rst
index b805fb58c85..b68931e800f 100644
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -6,6 +6,10 @@ PyAEDT documentation |version|
`Source Repository `_ |
`Issues `_
+.. figure:: _static/logo.png
+ :align: center
+ :width: 640px
+
PyAEDT is a Python client library that interacts directly with the Ansys Electronics Desktop (AEDT) API,
enabling straightforward and efficient automation in your workflow.
diff --git a/doc/source/logo.svg b/doc/source/logo.svg
new file mode 100644
index 00000000000..6ca2fafefa0
--- /dev/null
+++ b/doc/source/logo.svg
@@ -0,0 +1,102 @@
+
+
+
+
diff --git a/examples/01-HFSS3DLayout/Dcir_in_3DLayout.py b/examples/01-HFSS3DLayout/Dcir_in_3DLayout.py
index 1d50229b835..50937948d9d 100644
--- a/examples/01-HFSS3DLayout/Dcir_in_3DLayout.py
+++ b/examples/01-HFSS3DLayout/Dcir_in_3DLayout.py
@@ -98,7 +98,7 @@
# Analysis DCIR in AEDT
# ~~~~~~~~~~~~~~~~~~~~~
# Launch AEDT and import the configured EDB and analysis DCIR
-desktop = pyaedt.Desktop(aedt_version, non_graphical=False, new_desktop_session=True)
+desktop = pyaedt.Desktop(aedt_version, non_graphical=False, new_desktop=True)
hfss3dl = pyaedt.Hfss3dLayout(local_path)
hfss3dl.analyze()
hfss3dl.save_project()
diff --git a/examples/01-HFSS3DLayout/HFSS3DLayout_Via.py b/examples/01-HFSS3DLayout/HFSS3DLayout_Via.py
index 483e06aa081..8bc57f40882 100644
--- a/examples/01-HFSS3DLayout/HFSS3DLayout_Via.py
+++ b/examples/01-HFSS3DLayout/HFSS3DLayout_Via.py
@@ -32,7 +32,7 @@
# ~~~~~~~~~~~
# Launch AEDT 2023 R2 in graphical mode.
-h3d = pyaedt.Hfss3dLayout(specified_version=aedt_version, new_desktop_session=True, non_graphical=non_graphical)
+h3d = pyaedt.Hfss3dLayout(version=aedt_version, new_desktop=True, non_graphical=non_graphical)
###############################################################################
# Set up variables
diff --git a/examples/01-HFSS3DLayout/Hfss3DComponent.py b/examples/01-HFSS3DLayout/Hfss3DComponent.py
index daeb0177ae3..ad29c9bc499 100644
--- a/examples/01-HFSS3DLayout/Hfss3DComponent.py
+++ b/examples/01-HFSS3DLayout/Hfss3DComponent.py
@@ -52,7 +52,7 @@
# ~~~~~~~~~~~
# Launch HFSS application
-hfss = pyaedt.Hfss(new_desktop_session=True, specified_version=aedt_version, non_graphical=non_graphical)
+hfss = pyaedt.Hfss(new_desktop=True, version=aedt_version, non_graphical=non_graphical)
hfss.solution_type = "Terminal"
diff --git a/examples/01-Modeling-Setup/Configurations.py b/examples/01-Modeling-Setup/Configurations.py
index 34fd7b1eedb..ee397799237 100644
--- a/examples/01-Modeling-Setup/Configurations.py
+++ b/examples/01-Modeling-Setup/Configurations.py
@@ -55,8 +55,8 @@
project_full_name = pyaedt.downloads.download_icepak(pyaedt.generate_unique_folder_name(folder_name="Graphic_Card"))
-ipk = pyaedt.Icepak(projectname=project_full_name, specified_version=aedt_version,
- new_desktop_session=True, non_graphical=non_graphical)
+ipk = pyaedt.Icepak(project=project_full_name, version=aedt_version,
+ new_desktop=True, non_graphical=non_graphical)
ipk.autosave_disable()
###############################################################################
@@ -115,7 +115,7 @@
# ~~~~~~~~~~~~~~
# Create an Icepak project and import the step.
-app = pyaedt.Icepak(projectname="new_proj_Ipk")
+app = pyaedt.Icepak(project="new_proj_Ipk")
app.modeler.import_3d_cad(file_path)
###############################################################################
diff --git a/examples/01-Modeling-Setup/HFSS_CoordinateSystem.py b/examples/01-Modeling-Setup/HFSS_CoordinateSystem.py
index da40f1b1d3c..bafa2513ab6 100644
--- a/examples/01-Modeling-Setup/HFSS_CoordinateSystem.py
+++ b/examples/01-Modeling-Setup/HFSS_CoordinateSystem.py
@@ -32,14 +32,14 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Launch AEDT 2023 R2 in graphical mode.
-d = pyaedt.launch_desktop(specified_version=aedt_version, non_graphical=non_graphical, new_desktop_session=True)
+d = pyaedt.launch_desktop(version=aedt_version, non_graphical=non_graphical, new_desktop=True)
###############################################################################
# Insert HFSS design
# ~~~~~~~~~~~~~~~~~~
# Insert an HFSS design with the default name.
-hfss = pyaedt.Hfss(projectname=pyaedt.generate_unique_project_name(folder_name="CoordSysDemo"))
+hfss = pyaedt.Hfss(project=pyaedt.generate_unique_project_name(folder_name="CoordSysDemo"))
###############################################################################
# Create coordinate system
diff --git a/examples/01-Modeling-Setup/Optimetrics.py b/examples/01-Modeling-Setup/Optimetrics.py
index 2e3143e9e94..3ed3a177148 100644
--- a/examples/01-Modeling-Setup/Optimetrics.py
+++ b/examples/01-Modeling-Setup/Optimetrics.py
@@ -34,7 +34,7 @@
# Initialize the ``Hfss`` object and create two needed design variables,
# ``w1`` and ``w2``.
-hfss = pyaedt.Hfss(specified_version=aedt_version, new_desktop_session=True, non_graphical=non_graphical)
+hfss = pyaedt.Hfss(version=aedt_version, new_desktop=True, non_graphical=non_graphical, solution_type="Modal")
hfss["w1"] = "1mm"
hfss["w2"] = "100mm"
@@ -74,12 +74,12 @@
setup = hfss.create_setup()
hfss.create_linear_step_sweep(
- setup_name=setup.name,
+ setup=setup.name,
unit="GHz",
start_frequency=1,
stop_frequency=5,
step_size=0.1,
- sweep_name="Sweep1",
+ name="Sweep1",
save_fields=True
)
diff --git a/examples/01-Modeling-Setup/Polyline_Primitives.py b/examples/01-Modeling-Setup/Polyline_Primitives.py
index 3d91003ffd6..869fa62b32f 100644
--- a/examples/01-Modeling-Setup/Polyline_Primitives.py
+++ b/examples/01-Modeling-Setup/Polyline_Primitives.py
@@ -32,8 +32,8 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~
# Create a :class:`pyaedt.maxwell.Maxwell3d` object and set the unit type to ``"mm"``.
-M3D = pyaedt.Maxwell3d(solution_type="Transient", designname="test_polyline_3D", specified_version=aedt_version,
- new_desktop_session=True, non_graphical=non_graphical, )
+M3D = pyaedt.Maxwell3d(solution_type="Transient", design="test_polyline_3D", version=aedt_version,
+ new_desktop=True, non_graphical=non_graphical, )
M3D.modeler.model_units = "mm"
prim3D = M3D.modeler
diff --git a/examples/02-HFSS/Array.py b/examples/02-HFSS/Array.py
index 57db00411d4..6226fc58fc1 100644
--- a/examples/02-HFSS/Array.py
+++ b/examples/02-HFSS/Array.py
@@ -40,11 +40,11 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Launch HFSS and save the project.
project_name = pyaedt.generate_unique_project_name(project_name="array")
-hfss = pyaedt.Hfss(projectname=project_name,
- specified_version=aedt_version,
- designname="Array_Simple",
+hfss = pyaedt.Hfss(project=project_name,
+ version=aedt_version,
+ design="Array_Simple",
non_graphical=non_graphical,
- new_desktop_session=True)
+ new_desktop=True)
print("Project name " + project_name)
diff --git a/examples/02-HFSS/Create_3d_Component_and_use_it.py b/examples/02-HFSS/Create_3d_Component_and_use_it.py
index d04c7c6480d..20e10cfb9d1 100644
--- a/examples/02-HFSS/Create_3d_Component_and_use_it.py
+++ b/examples/02-HFSS/Create_3d_Component_and_use_it.py
@@ -30,7 +30,7 @@
# PyAEDT can initialize a new session of Electronics Desktop or connect to an existing one.
# Once Desktop is connected, a new HFSS session is started and a design is created.
-hfss = Hfss(specified_version=aedt_version, new_desktop_session=True, close_on_exit=True)
+hfss = Hfss(version=aedt_version, new_desktop=True, close_on_exit=True)
##########################################################
# Variables
@@ -100,7 +100,7 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~
# PyAEDT allows to control multiple projects, design and solution type at the same time.
-hfss2 = Hfss(projectname="new_project", designname="new_design")
+hfss2 = Hfss(project="new_project", design="new_design")
##########################################################
# Insert of 3d component
diff --git a/examples/02-HFSS/Flex_CPWG.py b/examples/02-HFSS/Flex_CPWG.py
index 90b5e26d3a8..b69b0267d9b 100644
--- a/examples/02-HFSS/Flex_CPWG.py
+++ b/examples/02-HFSS/Flex_CPWG.py
@@ -33,9 +33,9 @@
# ~~~~~~~~~~~
# Launch AEDT 2023 R2 in graphical mode.
-hfss = pyaedt.Hfss(specified_version=aedt_version,
+hfss = pyaedt.Hfss(version=aedt_version,
solution_type="DrivenTerminal",
- new_desktop_session=True,
+ new_desktop=True,
non_graphical=non_graphical)
hfss.change_material_override(True)
hfss.change_automatically_use_causal_materials(True)
diff --git a/examples/02-HFSS/HFSS_Choke.py b/examples/02-HFSS/HFSS_Choke.py
index cfdc790d040..90d0699617b 100644
--- a/examples/02-HFSS/HFSS_Choke.py
+++ b/examples/02-HFSS/HFSS_Choke.py
@@ -43,10 +43,10 @@
# ~~~~~~~~~~~
# Launches HFSS 2023 R2 in graphical mode.
-hfss = pyaedt.Hfss(projectname=project_name,
- specified_version=aedt_version,
+hfss = pyaedt.Hfss(project=project_name,
+ version=aedt_version,
non_graphical=non_graphical,
- new_desktop_session=True,
+ new_desktop=True,
solution_type="Terminal")
###############################################################################
diff --git a/examples/02-HFSS/HFSS_Dipole.py b/examples/02-HFSS/HFSS_Dipole.py
index a1e66b8aad1..d6585e37ae8 100644
--- a/examples/02-HFSS/HFSS_Dipole.py
+++ b/examples/02-HFSS/HFSS_Dipole.py
@@ -34,14 +34,14 @@
# ~~~~~~~~~~~
# Launch AEDT 2023 R2 in graphical mode.
-d = pyaedt.launch_desktop(aedt_version, non_graphical=non_graphical, new_desktop_session=True)
+d = pyaedt.launch_desktop(aedt_version, non_graphical=non_graphical, new_desktop=True)
###############################################################################
# Launch HFSS
# ~~~~~~~~~~~
# Launch HFSS 2023 R2 in graphical mode.
-hfss = pyaedt.Hfss(projectname=project_name, solution_type="Modal")
+hfss = pyaedt.Hfss(project=project_name, solution_type="Modal")
###############################################################################
# Define variable
@@ -153,7 +153,7 @@
# method with an arbitrary name.
hfss["post_x"] = 2
-hfss.variable_manager.set_variable(variable_name="y_post", expression=1, postprocessing=True)
+hfss.variable_manager.set_variable(name="y_post", expression=1, is_post_processing=True)
hfss.modeler.create_coordinate_system(origin=["post_x", "y_post", 0], name="CS_Post")
hfss.insert_infinite_sphere(custom_coordinate_system="CS_Post", name="Sphere_Custom")
diff --git a/examples/02-HFSS/HFSS_FSS_unitcell.py b/examples/02-HFSS/HFSS_FSS_unitcell.py
index 182ea23c047..6c0768dc67f 100644
--- a/examples/02-HFSS/HFSS_FSS_unitcell.py
+++ b/examples/02-HFSS/HFSS_FSS_unitcell.py
@@ -34,14 +34,14 @@
# ~~~~~~~~~~~
# Launch AEDT 2023 R2 in graphical mode.
-d = pyaedt.launch_desktop(aedt_version, non_graphical=non_graphical, new_desktop_session=True)
+d = pyaedt.launch_desktop(aedt_version, non_graphical=non_graphical, new_desktop=True)
###############################################################################
# Launch HFSS
# ~~~~~~~~~~~
# Launch HFSS 2023 R2 in graphical mode.
-hfss = pyaedt.Hfss(projectname=project_name, solution_type="Modal")
+hfss = pyaedt.Hfss(project=project_name, solution_type="Modal")
###############################################################################
# Define variable
diff --git a/examples/02-HFSS/HFSS_Spiral.py b/examples/02-HFSS/HFSS_Spiral.py
index 4ba80a21c52..37a591f0edc 100644
--- a/examples/02-HFSS/HFSS_Spiral.py
+++ b/examples/02-HFSS/HFSS_Spiral.py
@@ -35,8 +35,8 @@
# Launch HFSS 2023 R2 in non-graphical mode and change the
# units to microns.
-hfss = pyaedt.Hfss(specified_version=aedt_version, non_graphical=non_graphical, designname="A1",
- new_desktop_session=True)
+hfss = pyaedt.Hfss(version=aedt_version, non_graphical=non_graphical, design="A1",
+ new_desktop=True)
hfss.solution_type = "Modal"
hfss.modeler.model_units = "um"
p = hfss.modeler
diff --git a/examples/02-HFSS/HFSS_eigenmode.py b/examples/02-HFSS/HFSS_eigenmode.py
index c7de9106ab5..a770bd22d62 100644
--- a/examples/02-HFSS/HFSS_eigenmode.py
+++ b/examples/02-HFSS/HFSS_eigenmode.py
@@ -57,14 +57,14 @@
# ~~~~~~~~~~~
# Launch AEDT 2023 R2 in graphical mode.
-d = pyaedt.launch_desktop(aedt_version, non_graphical=non_graphical, new_desktop_session=True)
+d = pyaedt.launch_desktop(aedt_version, non_graphical=non_graphical, new_desktop=True)
###############################################################################
# Launch HFSS
# ~~~~~~~~~~~
# Launch HFSS 2023 R2 in graphical mode.
-hfss = pyaedt.Hfss(projectname=project_path, non_graphical=non_graphical)
+hfss = pyaedt.Hfss(project=project_path, non_graphical=non_graphical)
###############################################################################
# Input parameters for eigenmode solver
diff --git a/examples/02-HFSS/Probe_Fed_Patch.py b/examples/02-HFSS/Probe_Fed_Patch.py
index 626620508bf..1409fe0e4f0 100644
--- a/examples/02-HFSS/Probe_Fed_Patch.py
+++ b/examples/02-HFSS/Probe_Fed_Patch.py
@@ -60,12 +60,12 @@
# -----------
#
-hfss = pyaedt.Hfss(projectname=proj_name,
+hfss = pyaedt.Hfss(project=proj_name,
solution_type="Terminal",
- designname="patch",
+ design="patch",
non_graphical=non_graphical,
- new_desktop_session=True,
- specified_version=aedt_version)
+ new_desktop=True,
+ version=aedt_version)
hfss.modeler.model_units = length_units
diff --git a/examples/02-HFSS/Waveguide_Filter.py b/examples/02-HFSS/Waveguide_Filter.py
index 163f893c281..092f17f9e0c 100644
--- a/examples/02-HFSS/Waveguide_Filter.py
+++ b/examples/02-HFSS/Waveguide_Filter.py
@@ -61,11 +61,11 @@
project_name = os.path.join(project_folder, general_methods.generate_unique_name("wgf", n=2))
# Instantiate the HFSS application
-hfss = pyaedt.Hfss(projectname=project_name + '.aedt',
- specified_version=aedt_version,
- designname="filter",
+hfss = pyaedt.Hfss(project=project_name + '.aedt',
+ version=aedt_version,
+ design="filter",
non_graphical=non_graphical,
- new_desktop_session=True,
+ new_desktop=True,
close_on_exit=True,
solution_type="Modal")
diff --git a/examples/02-SBR+/SBR_City_Import.py b/examples/02-SBR+/SBR_City_Import.py
index 2b727fea10c..818733d24d0 100644
--- a/examples/02-SBR+/SBR_City_Import.py
+++ b/examples/02-SBR+/SBR_City_Import.py
@@ -35,10 +35,10 @@
# Each design is connected to a different object.
app = Hfss(
- designname="Ansys",
+ design="Ansys",
solution_type="SBR+",
- specified_version=aedt_version,
- new_desktop_session=True,
+ version=aedt_version,
+ new_desktop=True,
non_graphical=non_graphical
)
diff --git a/examples/02-SBR+/SBR_Doppler_Example.py b/examples/02-SBR+/SBR_Doppler_Example.py
index 2e92b5f1cce..f5e7a68a7b0 100644
--- a/examples/02-SBR+/SBR_Doppler_Example.py
+++ b/examples/02-SBR+/SBR_Doppler_Example.py
@@ -45,10 +45,10 @@
# Instantiate the application.
app = pyaedt.Hfss(
- specified_version=aedt_version,
+ version=aedt_version,
solution_type="SBR+",
- new_desktop_session=True,
- projectname=project_name,
+ new_desktop=True,
+ project=project_name,
close_on_exit=True,
non_graphical=non_graphical
)
diff --git a/examples/02-SBR+/SBR_Example.py b/examples/02-SBR+/SBR_Example.py
index ca5e2ed1c13..41e6f8a16a1 100644
--- a/examples/02-SBR+/SBR_Example.py
+++ b/examples/02-SBR+/SBR_Example.py
@@ -37,17 +37,17 @@
# a different object.
target = pyaedt.Hfss(
- projectname=project_full_name,
- designname="Cassegrain_",
+ project=project_full_name,
+ design="Cassegrain_",
solution_type="SBR+",
- specified_version=aedt_version,
- new_desktop_session=True,
+ version=aedt_version,
+ new_desktop=True,
non_graphical=non_graphical
)
-source = pyaedt.Hfss(projectname=target.project_name,
- designname="feeder",
- specified_version=aedt_version,
+source = pyaedt.Hfss(project=target.project_name,
+ design="feeder",
+ version=aedt_version,
)
###############################################################################
diff --git a/examples/02-SBR+/SBR_Time_Plot.py b/examples/02-SBR+/SBR_Time_Plot.py
index 6384ef137ff..94d6c625e0f 100644
--- a/examples/02-SBR+/SBR_Time_Plot.py
+++ b/examples/02-SBR+/SBR_Time_Plot.py
@@ -35,7 +35,7 @@
project_file = downloads.download_sbr_time()
-hfss = Hfss(projectname=project_file, specified_version=aedt_version, non_graphical=non_graphical, new_desktop_session=True)
+hfss = Hfss(project=project_file, version=aedt_version, non_graphical=non_graphical, new_desktop=True)
hfss.analyze()
diff --git a/examples/03-Maxwell/Maxwell2D_DCConduction.py b/examples/03-Maxwell/Maxwell2D_DCConduction.py
index 2b9828647ae..7a693c8f97f 100644
--- a/examples/03-Maxwell/Maxwell2D_DCConduction.py
+++ b/examples/03-Maxwell/Maxwell2D_DCConduction.py
@@ -26,12 +26,12 @@
# ``Maxwell2d`` class named ``m2d``.
m2d = pyaedt.Maxwell2d(
- specified_version=aedt_version,
- new_desktop_session=True,
+ version=aedt_version,
+ new_desktop=True,
close_on_exit=True,
solution_type="DCConduction",
- projectname="M2D_DC_Conduction",
- designname="Ansys_resistor"
+ project="M2D_DC_Conduction",
+ design="Ansys_resistor"
)
##########################################################
diff --git a/examples/03-Maxwell/Maxwell2D_Electrostatic.py b/examples/03-Maxwell/Maxwell2D_Electrostatic.py
index 3f044ffd9bc..f9866f34186 100644
--- a/examples/03-Maxwell/Maxwell2D_Electrostatic.py
+++ b/examples/03-Maxwell/Maxwell2D_Electrostatic.py
@@ -66,11 +66,11 @@
# ~~~~~~~~~~~~~~~~~
# Launch Maxwell 2D and save the project.
-M2D = pyaedt.Maxwell2d(projectname=project_name,
- specified_version=aedt_version,
- designname=design_name,
+M2D = pyaedt.Maxwell2d(project=project_name,
+ version=aedt_version,
+ design=design_name,
solution_type=solver,
- new_desktop_session=True,
+ new_desktop=True,
non_graphical=non_graphical
)
diff --git a/examples/03-Maxwell/Maxwell2D_PMSynchronousMotor.py b/examples/03-Maxwell/Maxwell2D_PMSynchronousMotor.py
index 4435be7cc96..4d0d80e04b9 100644
--- a/examples/03-Maxwell/Maxwell2D_PMSynchronousMotor.py
+++ b/examples/03-Maxwell/Maxwell2D_PMSynchronousMotor.py
@@ -123,11 +123,11 @@
# ~~~~~~~~~~~~~~~~~
# Launch Maxwell 2D and save the project.
-M2D = pyaedt.Maxwell2d(projectname=project_name,
- specified_version=aedt_version,
- designname=design_name,
+M2D = pyaedt.Maxwell2d(project=project_name,
+ version=aedt_version,
+ design=design_name,
solution_type=solver,
- new_desktop_session=True,
+ new_desktop=True,
non_graphical=non_graphical
)
diff --git a/examples/03-Maxwell/Maxwell2D_Transformer_LL.py b/examples/03-Maxwell/Maxwell2D_Transformer_LL.py
index af134dc8802..7137bcee552 100644
--- a/examples/03-Maxwell/Maxwell2D_Transformer_LL.py
+++ b/examples/03-Maxwell/Maxwell2D_Transformer_LL.py
@@ -30,10 +30,10 @@
solver = "MagnetostaticXY"
desktop_version = "2024.1"
-m2d = Maxwell2d(specified_version=desktop_version,
- new_desktop_session=False,
- designname=design_name,
- projectname=project_name,
+m2d = Maxwell2d(version=desktop_version,
+ new_desktop=False,
+ design=design_name,
+ project=project_name,
solution_type=solver,
non_graphical=non_graphical)
@@ -86,12 +86,12 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Define design variables from the created dictionaries.
-m2d.variable_manager.set_variable(variable_name="Dimensions")
+m2d.variable_manager.set_variable(name="Dimensions")
for k, v in dimensions.items():
m2d[k] = v
-m2d.variable_manager.set_variable(variable_name="Windings")
+m2d.variable_manager.set_variable(name="Windings")
for k, v in specifications.items():
m2d[k] = v
diff --git a/examples/03-Maxwell/Maxwell2D_Transient.py b/examples/03-Maxwell/Maxwell2D_Transient.py
index d92c6f87247..f9b14ceff37 100644
--- a/examples/03-Maxwell/Maxwell2D_Transient.py
+++ b/examples/03-Maxwell/Maxwell2D_Transient.py
@@ -54,8 +54,8 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Insert a Maxwell 2D design and save the project.
-maxwell_2d = pyaedt.Maxwell2d(solution_type="TransientXY", specified_version=aedt_version, non_graphical=non_graphical,
- new_desktop_session=True, projectname=pyaedt.generate_unique_project_name())
+maxwell_2d = pyaedt.Maxwell2d(solution_type="TransientXY", version=aedt_version, non_graphical=non_graphical,
+ new_desktop=True, project=pyaedt.generate_unique_project_name())
###############################################################################
# Create rectangle and duplicate it
diff --git a/examples/03-Maxwell/Maxwell3DTeam7.py b/examples/03-Maxwell/Maxwell3DTeam7.py
index 436ca8f3382..68fccd5ca7e 100644
--- a/examples/03-Maxwell/Maxwell3DTeam7.py
+++ b/examples/03-Maxwell/Maxwell3DTeam7.py
@@ -50,12 +50,12 @@
solver = "EddyCurrent"
m3d = Maxwell3d(
- projectname=project_name,
- designname=design_name,
+ project=project_name,
+ design=design_name,
solution_type=solver,
- specified_version=aedt_version,
+ version=aedt_version,
non_graphical=non_graphical,
- new_desktop_session=True
+ new_desktop=True
)
m3d.modeler.model_units = "mm"
diff --git a/examples/03-Maxwell/Maxwell3D_Choke.py b/examples/03-Maxwell/Maxwell3D_Choke.py
index e6f59c608a0..8b19f350943 100644
--- a/examples/03-Maxwell/Maxwell3D_Choke.py
+++ b/examples/03-Maxwell/Maxwell3D_Choke.py
@@ -40,11 +40,11 @@
# ~~~~~~~~~~~~~~~~
# Launch Maxwell 3D 2023 R2 in graphical mode.
-m3d = pyaedt.Maxwell3d(projectname=pyaedt.generate_unique_project_name(),
+m3d = pyaedt.Maxwell3d(project=pyaedt.generate_unique_project_name(),
solution_type="EddyCurrent",
- specified_version=aedt_version,
+ version=aedt_version,
non_graphical=non_graphical,
- new_desktop_session=True
+ new_desktop=True
)
###############################################################################
diff --git a/examples/03-Maxwell/Maxwell3D_Segmentation.py b/examples/03-Maxwell/Maxwell3D_Segmentation.py
index 49956cd9f90..fa38433ff52 100644
--- a/examples/03-Maxwell/Maxwell3D_Segmentation.py
+++ b/examples/03-Maxwell/Maxwell3D_Segmentation.py
@@ -48,9 +48,9 @@
# ~~~~~~~~~~~~~~~~~
# Launch Maxwell 3D.
-m3d = Maxwell3d(projectname=aedt_file,
- specified_version=aedt_version,
- new_desktop_session=True,
+m3d = Maxwell3d(project=aedt_file,
+ version=aedt_version,
+ new_desktop=True,
non_graphical=non_graphical)
##################################################################################
diff --git a/examples/03-Maxwell/Maxwell3D_Team3_bath_plate.py b/examples/03-Maxwell/Maxwell3D_Team3_bath_plate.py
index 67cc322a43d..1b1d485e9cc 100644
--- a/examples/03-Maxwell/Maxwell3D_Team3_bath_plate.py
+++ b/examples/03-Maxwell/Maxwell3D_Team3_bath_plate.py
@@ -43,17 +43,17 @@
# the solver, and the version. The following code also creates an instance of the
# ``Maxwell3d`` class named ``M3D``.
-project_name = "COMPUMAG"
+project_name = os.path.join(temp_dir.name, "COMPUMAG.aedt")
design_name = "TEAM 3 Bath Plate"
solver = "EddyCurrent"
m3d = pyaedt.Maxwell3d(
- projectname=project_name,
- designname=design_name,
+ project=project_name,
+ design=design_name,
solution_type=solver,
- specified_version=aedt_version,
+ version=aedt_version,
non_graphical=non_graphical,
- new_desktop_session=True,
+ new_desktop=True,
)
m3d.modeler.model_units = "mm"
@@ -235,5 +235,6 @@
# ~~~~~~~~~~~~
# Release AEDT from the script engine, leaving both AEDT and the project open.
-m3d.release_desktop(False, False)
+m3d.release_desktop()
+
temp_dir.cleanup()
diff --git a/examples/03-Maxwell/Maxwell_Control_Program.py b/examples/03-Maxwell/Maxwell_Control_Program.py
index 035f1f8db69..cace045c035 100644
--- a/examples/03-Maxwell/Maxwell_Control_Program.py
+++ b/examples/03-Maxwell/Maxwell_Control_Program.py
@@ -13,7 +13,7 @@
# Perform required imports.
from pyaedt import downloads
-from pyaedt import generate_unique_folder_name
+from pyaedt.generic.general_methods import generate_unique_folder_name
from pyaedt import Maxwell2d
##########################################################
@@ -44,9 +44,9 @@
# ~~~~~~~~~~~~~~~~~
# Launch Maxwell 2D.
-m2d = Maxwell2d(projectname=aedt_file,
- specified_version=aedt_version,
- new_desktop_session=True,
+m2d = Maxwell2d(project=aedt_file,
+ version=aedt_version,
+ new_desktop=True,
non_graphical=non_graphical)
##################################################################################
diff --git a/examples/03-Maxwell/Maxwell_Magnet.py b/examples/03-Maxwell/Maxwell_Magnet.py
index 41882c8bb3f..1dc2fdd1fe9 100644
--- a/examples/03-Maxwell/Maxwell_Magnet.py
+++ b/examples/03-Maxwell/Maxwell_Magnet.py
@@ -41,9 +41,9 @@
# ~~~~~~~~~~~
# Launch AEDT in graphical mode.
-m3d = Maxwell3d(projectname=generate_unique_project_name(),
- specified_version=aedt_version,
- new_desktop_session=True,
+m3d = Maxwell3d(project=generate_unique_project_name(),
+ version=aedt_version,
+ new_desktop=True,
non_graphical=non_graphical)
###############################################################################
diff --git a/examples/03-Maxwell/Maxwell_Transformer_Coreloss.py b/examples/03-Maxwell/Maxwell_Transformer_Coreloss.py
index bc975659219..768f4c33275 100644
--- a/examples/03-Maxwell/Maxwell_Transformer_Coreloss.py
+++ b/examples/03-Maxwell/Maxwell_Transformer_Coreloss.py
@@ -10,7 +10,7 @@
# Perform required imports.
from pyaedt import downloads
-from pyaedt import generate_unique_folder_name
+from pyaedt.generic.general_methods import generate_unique_folder_name
from pyaedt import Maxwell3d
from pyaedt.generic.constants import unit_converter
from pyaedt.generic.general_methods import read_csv_pandas
@@ -60,10 +60,10 @@
# ~~~~~~~~~~~
# Launch AEDT in graphical mode.
-m3d = Maxwell3d(projectname=aedt_file,
- designname="02_3D eddycurrent_CmXY_for_thermal",
- specified_version=aedt_version,
- new_desktop_session=True,
+m3d = Maxwell3d(project=aedt_file,
+ design="02_3D eddycurrent_CmXY_for_thermal",
+ version=aedt_version,
+ new_desktop=True,
non_graphical=False)
###############################################################################
diff --git a/examples/04-Icepak/Icepak_3DComponents_Example.py b/examples/04-Icepak/Icepak_3DComponents_Example.py
index 7a9bec5cdf0..fecf8aec461 100644
--- a/examples/04-Icepak/Icepak_3DComponents_Example.py
+++ b/examples/04-Icepak/Icepak_3DComponents_Example.py
@@ -38,11 +38,11 @@
# ~~~~~~~~~~~~~~~
# Open a new project in non-graphical mode.
-ipk = Icepak(projectname=os.path.join(temp_folder, "Heatsink.aedt"),
- specified_version=aedt_version,
+ipk = Icepak(project=os.path.join(temp_folder, "Heatsink.aedt"),
+ version=aedt_version,
non_graphical=non_graphical,
close_on_exit=True,
- new_desktop_session=True)
+ new_desktop=True)
# Remove air region created by default because it is not needed as the heatsink will be exported as a 3DComponent.
@@ -88,30 +88,20 @@
component_name="Heatsink",
auxiliary_dict=True
)
-ipk.close_project(save_project=False)
+ipk.close_project(save=False)
###############################################################################
# Create QFP
# ~~~~~~~~~~
# Download and open a project containing a QPF.
-ipk = Icepak(projectname=qfp_temp_name)
+ipk = Icepak(project=qfp_temp_name)
ipk.plot(show=False, output_file=os.path.join(temp_folder, "QFP2.jpg"))
# Create dataset for power dissipation.
x_datalist = [45, 53, 60, 70]
y_datalist = [0.5, 3, 6, 9]
-ipk.create_dataset(
- "PowerDissipationDataset",
- x_datalist,
- y_datalist,
- zlist=None,
- vlist=None,
- is_project_dataset=False,
- xunit="cel",
- yunit="W",
- zunit="",
- vunit="",
-)
+ipk.create_dataset("PowerDissipationDataset", x_datalist, y_datalist, z=None, v=None, is_project_dataset=False,
+ x_unit="cel", y_unit="W", v_unit="")
# Assign source power condition to the die.
ipk.create_source_power(
@@ -147,8 +137,8 @@
# Create electronic package
# ~~~~~~~~~~~~~~~~~~~~~~~~~
# Download and open a project containing the electronic package.
-ipk = Icepak(projectname=package_temp_name,
- specified_version=aedt_version,
+ipk = Icepak(project=package_temp_name,
+ version=aedt_version,
non_graphical=non_graphical)
ipk.plot(show=False, output_file=os.path.join(temp_folder, "electronic_package_missing_obj.jpg"))
diff --git a/examples/04-Icepak/Icepak_CSV_Import.py b/examples/04-Icepak/Icepak_CSV_Import.py
index d4d0dd11980..9fe505d335f 100644
--- a/examples/04-Icepak/Icepak_CSV_Import.py
+++ b/examples/04-Icepak/Icepak_CSV_Import.py
@@ -39,9 +39,9 @@
temp_folder = pyaedt.generate_unique_folder_name()
-ipk = pyaedt.Icepak(projectname=os.path.join(temp_folder, "Icepak_CSV_Import.aedt"),
- specified_version=aedt_version,
- new_desktop_session=True,
+ipk = pyaedt.Icepak(project=os.path.join(temp_folder, "Icepak_CSV_Import.aedt"),
+ version=aedt_version,
+ new_desktop=True,
non_graphical=non_graphical
)
diff --git a/examples/04-Icepak/Icepak_ECAD_Import.py b/examples/04-Icepak/Icepak_ECAD_Import.py
index 0fb554991e3..2e4caa2dcde 100644
--- a/examples/04-Icepak/Icepak_ECAD_Import.py
+++ b/examples/04-Icepak/Icepak_ECAD_Import.py
@@ -43,9 +43,9 @@
temp_folder = pyaedt.generate_unique_folder_name()
-ipk = pyaedt.Icepak(projectname=os.path.join(temp_folder, "Icepak_ECAD_Import.aedt"),
- specified_version=aedt_version,
- new_desktop_session=True,
+ipk = pyaedt.Icepak(project=os.path.join(temp_folder, "Icepak_ECAD_Import.aedt"),
+ version=aedt_version,
+ new_desktop=True,
non_graphical=non_graphical
)
@@ -94,7 +94,7 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ipk.modeler.fit_all() # scales to fit all objects in AEDT
-ipk.save_project() # saves the project
+ipk.save_project() # saves the project
###############################################################################
# Add an HFSS 3D Layout design with the layout information of the PCB
@@ -106,7 +106,7 @@
#edb_full_path = os.path.join(os.getcwd(), Layout_name+'.aedb\edb.def') # path to the EDB file
hfss3dLO.import_edb(def_path) # importing the EDB file
-hfss3dLO.save_project() # save the new project so files are stored in the path
+hfss3dLO.save_project() # save the new project so files are stored in the path
ipk.delete_design(name='PCB_temp', fallback_design=None) # deleting the dummy layout from the original project
diff --git a/examples/04-Icepak/Icepak_Example.py b/examples/04-Icepak/Icepak_Example.py
index 1d728543ab9..ec0415c16e3 100644
--- a/examples/04-Icepak/Icepak_Example.py
+++ b/examples/04-Icepak/Icepak_Example.py
@@ -35,9 +35,9 @@
temp_folder = pyaedt.generate_unique_folder_name()
project_temp_name = pyaedt.downloads.download_icepak(temp_folder)
-ipk = pyaedt.Icepak(projectname=project_temp_name,
- specified_version=aedt_version,
- new_desktop_session=True,
+ipk = pyaedt.Icepak(project=project_temp_name,
+ version=aedt_version,
+ new_desktop=True,
non_graphical=non_graphical
)
diff --git a/examples/04-Icepak/Sherlock_Example.py b/examples/04-Icepak/Sherlock_Example.py
index cfeeade0a1a..ddd4b250a26 100644
--- a/examples/04-Icepak/Sherlock_Example.py
+++ b/examples/04-Icepak/Sherlock_Example.py
@@ -52,7 +52,7 @@
# ~~~~~~~~~~~
# Launch AEDT 2023 R2 in graphical mode.
-d = pyaedt.launch_desktop(specified_version=aedt_version, non_graphical=non_graphical, new_desktop_session=True)
+d = pyaedt.launch_desktop(version=aedt_version, non_graphical=non_graphical, new_desktop=True)
start = time.time()
material_list = os.path.join(input_dir, material_name)
@@ -106,7 +106,7 @@
# ~~~~~~~~~~~~~
# Save the CAD file and refresh the properties from the parsing of the AEDT file.
-ipk.save_project(refresh_obj_ids_after_save=True)
+ipk.save_project(refresh_ids=True)
###############################################################################
# Plot model
diff --git a/examples/05-Q3D/Q2D_Armoured_Cable.py b/examples/05-Q3D/Q2D_Armoured_Cable.py
index 00d431a755b..6a933a6ff47 100644
--- a/examples/05-Q3D/Q2D_Armoured_Cable.py
+++ b/examples/05-Q3D/Q2D_Armoured_Cable.py
@@ -90,7 +90,7 @@
setup_name = "MySetupAuto"
sweep_name = "sweep1"
tb_design_name = 'CableSystem'
-q2d = pyaedt.Q2d(projectname=project_name, designname=q2d_design_name, specified_version=aedt_version)
+q2d = pyaedt.Q2d(project=project_name, design=q2d_design_name, version=aedt_version)
##########################################################
# Define variables from dictionaries
@@ -238,7 +238,7 @@
# Add a Simplorer/Twin Builder design and the Q3D dynamic component
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-tb = pyaedt.TwinBuilder(designname=tb_design_name)
+tb = pyaedt.TwinBuilder(design=tb_design_name)
##########################################################
# Add a Q3D dynamic component
diff --git a/examples/05-Q3D/Q2D_Example_CPWG.py b/examples/05-Q3D/Q2D_Example_CPWG.py
index 5afd3abcb71..ce244f1d304 100644
--- a/examples/05-Q3D/Q2D_Example_CPWG.py
+++ b/examples/05-Q3D/Q2D_Example_CPWG.py
@@ -33,11 +33,11 @@
# Launch AEDT 2023 R2 in graphical mode and launch 2D Extractor. This example
# uses SI units.
-q = pyaedt.Q2d(specified_version=aedt_version,
+q = pyaedt.Q2d(version=aedt_version,
non_graphical=non_graphical,
- new_desktop_session=True,
- projectname=pyaedt.generate_unique_name("pyaedt_q2d_example"),
- designname="coplanar_waveguide")
+ new_desktop=True,
+ project=pyaedt.generate_unique_name("pyaedt_q2d_example"),
+ design="coplanar_waveguide")
###############################################################################
# Define variables
diff --git a/examples/05-Q3D/Q2D_Example_Stripline.py b/examples/05-Q3D/Q2D_Example_Stripline.py
index d76b2f7a974..9b5abf112a4 100644
--- a/examples/05-Q3D/Q2D_Example_Stripline.py
+++ b/examples/05-Q3D/Q2D_Example_Stripline.py
@@ -34,11 +34,11 @@
# Launch AEDT 2023 R2 in graphical mode and launch 2D Extractor. This example
# uses SI units.
-q = pyaedt.Q2d(projectname=project_path,
- designname="differential_stripline",
- specified_version=aedt_version,
+q = pyaedt.Q2d(project=project_path,
+ design="differential_stripline",
+ version=aedt_version,
non_graphical=non_graphical,
- new_desktop_session=True
+ new_desktop=True
)
###############################################################################
diff --git a/examples/05-Q3D/Q3D_DC_IR.py b/examples/05-Q3D/Q3D_DC_IR.py
index e0ccdcd97c7..88775d31728 100644
--- a/examples/05-Q3D/Q3D_DC_IR.py
+++ b/examples/05-Q3D/Q3D_DC_IR.py
@@ -93,7 +93,7 @@
edb.save_edb_as(output_edb)
edb.close_edb()
-h3d = pyaedt.Hfss3dLayout(output_edb, specified_version=aedt_version, non_graphical=False, new_desktop_session=True)
+h3d = pyaedt.Hfss3dLayout(output_edb, version=aedt_version, non_graphical=False, new_desktop=True)
###############################################################################
# Export to Q3D
diff --git a/examples/05-Q3D/Q3D_Example.py b/examples/05-Q3D/Q3D_Example.py
index cf3a870abcb..14b4fc13f4b 100644
--- a/examples/05-Q3D/Q3D_Example.py
+++ b/examples/05-Q3D/Q3D_Example.py
@@ -44,10 +44,10 @@
# Launch AEDT 2023 R2 in graphical mode and launch Q3D Extractor.
# This example uses SI units.
-q = pyaedt.Q3d(projectname=pyaedt.generate_unique_project_name(),
- specified_version=aedt_version,
+q = pyaedt.Q3d(project=pyaedt.generate_unique_project_name(),
+ version=aedt_version,
non_graphical=non_graphical,
- new_desktop_session=True)
+ new_desktop=True)
###############################################################################
# Create primitives
diff --git a/examples/05-Q3D/Q3D_from_EDB.py b/examples/05-Q3D/Q3D_from_EDB.py
index 8124187ba76..2b5cbc53f9c 100644
--- a/examples/05-Q3D/Q3D_from_EDB.py
+++ b/examples/05-Q3D/Q3D_from_EDB.py
@@ -78,7 +78,7 @@
edb.save_edb()
edb.close_edb()
-h3d = pyaedt.Hfss3dLayout(output_edb, specified_version=aedt_version, non_graphical=True, new_desktop_session=True)
+h3d = pyaedt.Hfss3dLayout(output_edb, version=aedt_version, non_graphical=True, new_desktop=True)
###############################################################################
# Export to Q3D
diff --git a/examples/06-Multiphysics/Hfss_Icepak_Coupling.py b/examples/06-Multiphysics/Hfss_Icepak_Coupling.py
index 272bcb130d3..0e9e22ace4e 100644
--- a/examples/06-Multiphysics/Hfss_Icepak_Coupling.py
+++ b/examples/06-Multiphysics/Hfss_Icepak_Coupling.py
@@ -48,10 +48,10 @@
# Launch AEDT and initialize HFSS. If there is an active HFSS design, the ``aedtapp``
# object is linked to it. Otherwise, a new design is created.
-aedtapp = pyaedt.Hfss(projectname=project_file,
- specified_version=aedt_version,
+aedtapp = pyaedt.Hfss(project=project_file,
+ version=aedt_version,
non_graphical=non_graphical,
- new_desktop_session=NewThread
+ new_desktop=NewThread
)
###############################################################################
diff --git a/examples/06-Multiphysics/Hfss_Mechanical.py b/examples/06-Multiphysics/Hfss_Mechanical.py
index 5972750c9d9..e2f4912ea52 100644
--- a/examples/06-Multiphysics/Hfss_Mechanical.py
+++ b/examples/06-Multiphysics/Hfss_Mechanical.py
@@ -40,8 +40,8 @@
# ~~~~~~~~~~
# Start HFSS and initialize the PyAEDT object.
-hfss = pyaedt.Hfss(projectname=project_temp_name, specified_version=aedt_version, non_graphical=non_graphical,
- new_desktop_session=True)
+hfss = pyaedt.Hfss(project=project_temp_name, version=aedt_version, non_graphical=non_graphical,
+ new_desktop=True)
pin_names = hfss.excitations
hfss.change_material_override(True)
diff --git a/examples/06-Multiphysics/MRI.py b/examples/06-Multiphysics/MRI.py
index 75f5c496eaa..be712f8794f 100644
--- a/examples/06-Multiphysics/MRI.py
+++ b/examples/06-Multiphysics/MRI.py
@@ -47,8 +47,8 @@
# Material properties defined in this project already contain #electrical and thermal properties.
project_path = downloads.download_file(directory="mri")
-hfss = Hfss(os.path.join(project_path, "background_SAR.aedt"), specified_version=aedt_version, non_graphical=non_graphical,
- new_desktop_session=True)
+hfss = Hfss(os.path.join(project_path, "background_SAR.aedt"), version=aedt_version, non_graphical=non_graphical,
+ new_desktop=True)
###############################################################################
# Insert 3D component
@@ -152,7 +152,7 @@
# Initialize a new Mechanical Transient Thermal analysis.
# Mechanical Transient Thermal is available in AEDT from 2023 R2 as a Beta feature.
-mech = Mechanical(solution_type="Transient Thermal", specified_version=aedt_version)
+mech = Mechanical(solution_type="Transient Thermal", version=aedt_version)
###############################################################################
# Copy geometries
@@ -220,7 +220,7 @@
# ~~~~~~~~~~~~~~~~~~
# Initialize a new Icepak Transient Thermal analysis.
-ipk = Icepak(solution_type="Transient", specified_version=aedt_version)
+ipk = Icepak(solution_type="Transient", version=aedt_version)
ipk.design_solutions.problem_type = "TemperatureOnly"
###############################################################################
diff --git a/examples/06-Multiphysics/Maxwell3D_Icepak_2Way_Coupling.py b/examples/06-Multiphysics/Maxwell3D_Icepak_2Way_Coupling.py
index aea6e29d8ba..1a6eb9a69e9 100644
--- a/examples/06-Multiphysics/Maxwell3D_Icepak_2Way_Coupling.py
+++ b/examples/06-Multiphysics/Maxwell3D_Icepak_2Way_Coupling.py
@@ -41,10 +41,10 @@
icepak_design_name = "2 Icepak"
m3d = pyaedt.Maxwell3d(
- projectname=project_name,
- designname=maxwell_design_name,
+ project=project_name,
+ design=maxwell_design_name,
solution_type="EddyCurrent",
- specified_version=aedt_version,
+ version=aedt_version,
non_graphical=non_graphical,
)
@@ -175,8 +175,8 @@
# ~~~~~~~~~~~~~
# Insert Icepak design, copy solid objects from Maxwell, and modify region dimensions.
-ipk = pyaedt.Icepak(designname=icepak_design_name)
-ipk.copy_solid_bodies_from(m3d, pec=False)
+ipk = pyaedt.Icepak(design=icepak_design_name)
+ipk.copy_solid_bodies_from(m3d, no_pec=False)
# Set domain dimensions suitable for natural convection using the diameter of the coil
ipk.modeler["Region"].delete()
diff --git a/examples/07-Circuit/Circuit_AMI.py b/examples/07-Circuit/Circuit_AMI.py
index f90e8e5b0b3..df422dafdce 100644
--- a/examples/07-Circuit/Circuit_AMI.py
+++ b/examples/07-Circuit/Circuit_AMI.py
@@ -47,8 +47,8 @@
# and starts the specified version in the specified mode.
pyaedt.settings.enable_pandas_output = True
-cir = pyaedt.Circuit(projectname=os.path.join(project_path), non_graphical=non_graphical,
- specified_version=aedt_version, new_desktop_session=NewThread)
+cir = pyaedt.Circuit(project=os.path.join(project_path), non_graphical=non_graphical,
+ version=aedt_version, new_desktop=NewThread)
###############################################################################
# Solve AMI setup
diff --git a/examples/07-Circuit/Circuit_Example.py b/examples/07-Circuit/Circuit_Example.py
index fff442bf276..fa0e686bf66 100644
--- a/examples/07-Circuit/Circuit_Example.py
+++ b/examples/07-Circuit/Circuit_Example.py
@@ -38,7 +38,7 @@
# starts the specified version in the specified mode.
desktop = pyaedt.launch_desktop(aedt_version, non_graphical, new_thread)
-aedt_app = pyaedt.Circuit(projectname=pyaedt.generate_unique_project_name())
+aedt_app = pyaedt.Circuit(project=pyaedt.generate_unique_project_name())
aedt_app.modeler.schematic.schematic_units = "mil"
###############################################################################
# Create circuit setup
diff --git a/examples/07-Circuit/Circuit_Siwave_Multizones.py b/examples/07-Circuit/Circuit_Siwave_Multizones.py
index 28a61516a3b..9b91153b6ab 100644
--- a/examples/07-Circuit/Circuit_Siwave_Multizones.py
+++ b/examples/07-Circuit/Circuit_Siwave_Multizones.py
@@ -69,7 +69,7 @@
# ~~~~~~~
# Create circuit design, import all sub-project as EM model and connect all corresponding pins in circuit.
-circuit = Circuit(specified_version=aedt_version, projectname=circuit_project_file)
+circuit = Circuit(version=aedt_version, project=circuit_project_file)
circuit.connect_circuit_models_from_multi_zone_cutout(project_connections=project_connexions,
edb_zones_dict=edb_zones, ports=defined_ports,
model_inc=70)
diff --git a/examples/07-Circuit/Circuit_Subcircuit_Example.py b/examples/07-Circuit/Circuit_Subcircuit_Example.py
index a5f05b47fc6..359508e4f41 100644
--- a/examples/07-Circuit/Circuit_Subcircuit_Example.py
+++ b/examples/07-Circuit/Circuit_Subcircuit_Example.py
@@ -32,10 +32,10 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~
# Launch AEDT 2023 R2 in graphical mode with Circuit.
-circuit = pyaedt.Circuit(projectname=pyaedt.generate_unique_project_name(),
- specified_version=aedt_version,
+circuit = pyaedt.Circuit(project=pyaedt.generate_unique_project_name(),
+ version=aedt_version,
non_graphical=non_graphical,
- new_desktop_session=True
+ new_desktop=True
)
circuit.modeler.schematic_units = "mil"
@@ -56,9 +56,9 @@
# the parameter values in the following code example. Connect them in series
# and then use the ``pop_up`` # method to get back to the parent design.
-circuit.variable_manager.set_variable(variable_name="R_val", expression="35ohm")
-circuit.variable_manager.set_variable(variable_name="L_val", expression="1e-7H")
-circuit.variable_manager.set_variable(variable_name="C_val", expression="5e-10F")
+circuit.variable_manager.set_variable(name="R_val", expression="35ohm")
+circuit.variable_manager.set_variable(name="L_val", expression="1e-7H")
+circuit.variable_manager.set_variable(name="C_val", expression="5e-10F")
p1 = circuit.modeler.schematic.create_interface_port(name="In")
r1 = circuit.modeler.schematic.create_resistor(value="R_val")
l1 = circuit.modeler.schematic.create_inductor(value="L_val")
diff --git a/examples/07-Circuit/Circuit_Transient.py b/examples/07-Circuit/Circuit_Transient.py
index e63fdb6655d..25972732565 100644
--- a/examples/07-Circuit/Circuit_Transient.py
+++ b/examples/07-Circuit/Circuit_Transient.py
@@ -35,9 +35,9 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~
# Launch AEDT 2023 R2 in graphical mode with Circuit.
-cir = pyaedt.Circuit(projectname=pyaedt.generate_unique_project_name(),
- specified_version=aedt_version,
- new_desktop_session=True,
+cir = pyaedt.Circuit(project=pyaedt.generate_unique_project_name(),
+ version=aedt_version,
+ new_desktop=True,
non_graphical=non_graphical
)
diff --git a/examples/07-Circuit/Create_Netlist.py b/examples/07-Circuit/Create_Netlist.py
index e284bcbf17a..c2f999fe746 100644
--- a/examples/07-Circuit/Create_Netlist.py
+++ b/examples/07-Circuit/Create_Netlist.py
@@ -44,7 +44,7 @@
# and starts it on the specified version in the specified graphical mode.
desktop = pyaedt.launch_desktop(aedt_version, non_graphical, NewThread)
-aedtapp = pyaedt.Circuit(projectname=project_name)
+aedtapp = pyaedt.Circuit(project=project_name)
###############################################################################
# Define variable
diff --git a/examples/07-Circuit/Reports.py b/examples/07-Circuit/Reports.py
index baf0118c3e7..14f4db69c87 100644
--- a/examples/07-Circuit/Reports.py
+++ b/examples/07-Circuit/Reports.py
@@ -41,10 +41,10 @@
# Launch AEDT with Circuit. The :class:`pyaedt.Desktop` class initializes AEDT
# and starts the specified version in the specified mode.
-cir = pyaedt.Circuit(projectname=os.path.join(project_path, 'CISPR25_Radiated_Emissions_Example23R1.aedtz'),
+cir = pyaedt.Circuit(project=os.path.join(project_path, 'CISPR25_Radiated_Emissions_Example23R1.aedtz'),
non_graphical=non_graphical,
- specified_version=aedt_version,
- new_desktop_session=True
+ version=aedt_version,
+ new_desktop=True
)
cir.analyze()
diff --git a/examples/07-Circuit/Virtual_Compliance.py b/examples/07-Circuit/Virtual_Compliance.py
index 721e06437a2..05fbe880dd8 100644
--- a/examples/07-Circuit/Virtual_Compliance.py
+++ b/examples/07-Circuit/Virtual_Compliance.py
@@ -45,7 +45,7 @@
# ~~~~~~~~~~~
# Launch AEDT.
-d = pyaedt.Desktop(aedt_version, new_desktop_session=new_thread, non_graphical=non_graphical)
+d = pyaedt.Desktop(aedt_version, new_desktop=new_thread, non_graphical=non_graphical)
###############################################################################
# Open and solve layout
@@ -54,7 +54,7 @@
# Before solving, this code ensures that the model is solved from DC to 70GHz and that
# causality and passivity are enforced.
-h3d = pyaedt.Hfss3dLayout(os.path.join(projectdir, "PCIE_GEN5_only_layout.aedtz"), specified_version=241)
+h3d = pyaedt.Hfss3dLayout(os.path.join(projectdir, "PCIE_GEN5_only_layout.aedtz"), version=241)
h3d.remove_all_unused_definitions()
h3d.edit_cosim_options(simulate_missing_solution=False)
h3d.setups[0].sweeps[0].props["EnforcePassivity"] = True
@@ -62,7 +62,7 @@
h3d.setups[0].sweeps[0].props["EnforceCausality"] = True
h3d.setups[0].sweeps[0].update()
h3d.analyze()
-h3d = pyaedt.Hfss3dLayout(specified_version=241)
+h3d = pyaedt.Hfss3dLayout(version=241)
touchstone_path = h3d.export_touchstone()
###############################################################################
@@ -71,7 +71,7 @@
# Use the LNA setup to retrieve Touchstone files
# and generate frequency domain reports.
-cir = pyaedt.Circuit(projectname=h3d.project_name, designname="Touchstone")
+cir = pyaedt.Circuit(project=h3d.project_name, design="Touchstone")
status, diff_pairs, comm_pairs = cir.create_lna_schematic_from_snp(input_file=touchstone_path, start_frequency=0,
stop_frequency=70, auto_assign_diff_pairs=True,
separation=".", pattern=["component", "pin", "net"],
diff --git a/examples/07-EMIT/ComputeInterferenceType.py b/examples/07-EMIT/ComputeInterferenceType.py
index fc368b36cc0..00572e3268c 100644
--- a/examples/07-EMIT/ComputeInterferenceType.py
+++ b/examples/07-EMIT/ComputeInterferenceType.py
@@ -60,10 +60,10 @@ def install(package):
non_graphical = False
new_thread = True
-desktop = pyaedt.launch_desktop(aedt_version, non_graphical=non_graphical, new_desktop_session=new_thread)
+desktop = pyaedt.launch_desktop(aedt_version, non_graphical=non_graphical, new_desktop=new_thread)
path_to_desktop_project = pyaedt.downloads.download_file("emit", "interference.aedtz")
-emitapp = Emit(non_graphical=False, new_desktop_session=False, projectname=path_to_desktop_project)
+emitapp = Emit(non_graphical=False, new_desktop=False, project=path_to_desktop_project)
# Get all the radios in the project
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/examples/07-TwinBuilder/01-RC_Circuit_Example.py b/examples/07-TwinBuilder/01-RC_Circuit_Example.py
index 0deec81cc46..940f6e50080 100644
--- a/examples/07-TwinBuilder/01-RC_Circuit_Example.py
+++ b/examples/07-TwinBuilder/01-RC_Circuit_Example.py
@@ -39,10 +39,10 @@
# Launch Twin Builder using an implicit declaration and add a new design with
# a default setup.
-tb = pyaedt.TwinBuilder(projectname=pyaedt.generate_unique_project_name(),
- specified_version=aedt_version,
+tb = pyaedt.TwinBuilder(project=pyaedt.generate_unique_project_name(),
+ version=aedt_version,
non_graphical=non_graphical,
- new_desktop_session=new_thread
+ new_desktop=new_thread
)
tb.modeler.schematic_units = "mil"
diff --git a/examples/07-TwinBuilder/02-Wiring_A_Rectifier.py b/examples/07-TwinBuilder/02-Wiring_A_Rectifier.py
index c9192f669e2..ba977468e41 100644
--- a/examples/07-TwinBuilder/02-Wiring_A_Rectifier.py
+++ b/examples/07-TwinBuilder/02-Wiring_A_Rectifier.py
@@ -41,10 +41,10 @@
# Launch Twin Builder using an implicit declaration and add a new design with
# a default setup.
-tb = pyaedt.TwinBuilder(projectname=pyaedt.generate_unique_project_name(),
- specified_version=aedt_version,
+tb = pyaedt.TwinBuilder(project=pyaedt.generate_unique_project_name(),
+ version=aedt_version,
non_graphical=non_graphical,
- new_desktop_session=new_thread
+ new_desktop=new_thread
)
###############################################################################
diff --git a/examples/07-TwinBuilder/03-Dynamic_ROM_Creation_And_Visualization.py b/examples/07-TwinBuilder/03-Dynamic_ROM_Creation_And_Visualization.py
index 78bdef0d291..e891c1b811c 100644
--- a/examples/07-TwinBuilder/03-Dynamic_ROM_Creation_And_Visualization.py
+++ b/examples/07-TwinBuilder/03-Dynamic_ROM_Creation_And_Visualization.py
@@ -19,9 +19,9 @@
import matplotlib.pyplot as plt
from pyaedt import TwinBuilder
from pyaedt import generate_unique_project_name
-from pyaedt import generate_unique_folder_name
+from pyaedt.generic.general_methods import generate_unique_folder_name
from pyaedt import downloads
-from pyaedt import settings
+from pyaedt.generic.settings import settings
##########################################################
# Set AEDT version
@@ -73,10 +73,10 @@
# Launch Twin Builder using an implicit declaration and add a new design with
# a default setup for building the dynamic ROM component.
-tb = TwinBuilder(projectname=generate_unique_project_name(),
- specified_version=aedt_version,
+tb = TwinBuilder(project=generate_unique_project_name(),
+ version=aedt_version,
non_graphical=non_graphical,
- new_desktop_session=new_thread)
+ new_desktop=new_thread)
# Switch the current desktop configuration and the schematic environment to "Twin Builder".
# The Dynamic ROM feature is only available with a twin builder license.
diff --git a/examples/07-TwinBuilder/04-Static_ROM_Creation_And_Visualization.py b/examples/07-TwinBuilder/04-Static_ROM_Creation_And_Visualization.py
index 1583c42fdd4..df40afe2985 100644
--- a/examples/07-TwinBuilder/04-Static_ROM_Creation_And_Visualization.py
+++ b/examples/07-TwinBuilder/04-Static_ROM_Creation_And_Visualization.py
@@ -20,9 +20,9 @@
import matplotlib.pyplot as plt
from pyaedt import TwinBuilder
from pyaedt import generate_unique_project_name
-from pyaedt import generate_unique_folder_name
+from pyaedt.generic.general_methods import generate_unique_folder_name
from pyaedt import downloads
-from pyaedt import settings
+from pyaedt.generic.settings import settings
##########################################################
# Set AEDT version
@@ -77,8 +77,8 @@
# Launch Twin Builder using an implicit declaration and add a new design with
# a default setup for building the static ROM component.
-tb = TwinBuilder(projectname=generate_unique_project_name(), specified_version=aedt_version,
- non_graphical=non_graphical, new_desktop_session=new_thread)
+tb = TwinBuilder(project=generate_unique_project_name(), version=aedt_version,
+ non_graphical=non_graphical, new_desktop=new_thread)
# Switch the current desktop configuration and the schematic environment to "Twin Builder".
# The Static ROM feature is only available with a twin builder license.
diff --git a/pyaedt/__init__.py b/pyaedt/__init__.py
index 34f82cf8fb1..813506620dc 100644
--- a/pyaedt/__init__.py
+++ b/pyaedt/__init__.py
@@ -1,4 +1,27 @@
# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import os
import sys
import warnings
@@ -44,33 +67,17 @@ def custom_show_warning(message, category, filename, lineno, file=None, line=Non
version = __version__
#
-
-import pyaedt.downloads as downloads
+if not ("IronPython" in sys.version or ".NETFramework" in sys.version): # pragma: no cover
+ import pyaedt.downloads as downloads
+from pyaedt.edb import Edb # nosec
+from pyaedt.edb import Siwave # nosec
from pyaedt.generic import constants
import pyaedt.generic.DataHandlers as data_handler
-import pyaedt.generic.general_methods as general_methods
-from pyaedt.generic.general_methods import _retry_ntimes
-from pyaedt.generic.general_methods import generate_unique_folder_name
-from pyaedt.generic.general_methods import generate_unique_name
-from pyaedt.generic.general_methods import generate_unique_project_name
-from pyaedt.generic.general_methods import inside_desktop
-from pyaedt.generic.general_methods import is_ironpython
-from pyaedt.generic.general_methods import is_linux
-from pyaedt.generic.general_methods import is_windows
-from pyaedt.generic.general_methods import online_help
-from pyaedt.generic.general_methods import pyaedt_function_handler
-from pyaedt.generic.general_methods import settings
-
-try:
- from pyaedt.generic.design_types import Hfss3dLayout
-except Exception:
- from pyaedt.generic.design_types import Hfss3dLayout
-
from pyaedt.generic.design_types import Circuit
from pyaedt.generic.design_types import Desktop
-from pyaedt.generic.design_types import Edb
from pyaedt.generic.design_types import Emit
from pyaedt.generic.design_types import Hfss
+from pyaedt.generic.design_types import Hfss3dLayout
from pyaedt.generic.design_types import Icepak
from pyaedt.generic.design_types import Maxwell2d
from pyaedt.generic.design_types import Maxwell3d
@@ -80,10 +87,21 @@ def custom_show_warning(message, category, filename, lineno, file=None, line=Non
from pyaedt.generic.design_types import Q3d
from pyaedt.generic.design_types import Rmxprt
from pyaedt.generic.design_types import Simplorer
-from pyaedt.generic.design_types import Siwave
from pyaedt.generic.design_types import TwinBuilder
from pyaedt.generic.design_types import get_pyaedt_app
from pyaedt.generic.design_types import launch_desktop
+import pyaedt.generic.general_methods as general_methods
+from pyaedt.generic.general_methods import _retry_ntimes
+from pyaedt.generic.general_methods import generate_unique_folder_name
+from pyaedt.generic.general_methods import generate_unique_name
+from pyaedt.generic.general_methods import generate_unique_project_name
+from pyaedt.generic.general_methods import inside_desktop
+from pyaedt.generic.general_methods import is_ironpython
+from pyaedt.generic.general_methods import is_linux
+from pyaedt.generic.general_methods import is_windows
+from pyaedt.generic.general_methods import online_help
+from pyaedt.generic.general_methods import pyaedt_function_handler
+from pyaedt.generic.general_methods import settings
from pyaedt.misc import current_student_version
from pyaedt.misc import current_version
from pyaedt.misc import installed_versions
diff --git a/pyaedt/aedt_logger.py b/pyaedt/aedt_logger.py
index 060afeabda5..fce4e646541 100644
--- a/pyaedt/aedt_logger.py
+++ b/pyaedt/aedt_logger.py
@@ -1,4 +1,27 @@
# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import logging
from logging.handlers import RotatingFileHandler
import os
diff --git a/pyaedt/application/AEDT_File_Management.py b/pyaedt/application/AEDT_File_Management.py
index 6d641ba45a4..bd64a1aeed0 100644
--- a/pyaedt/application/AEDT_File_Management.py
+++ b/pyaedt/application/AEDT_File_Management.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import csv
import os
import re
diff --git a/pyaedt/application/Analysis.py b/pyaedt/application/Analysis.py
index abd7571957d..83001a3c655 100644
--- a/pyaedt/application/Analysis.py
+++ b/pyaedt/application/Analysis.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
"""
This module contains the ``analysis`` class.
@@ -14,9 +38,6 @@
import tempfile
import time
-from pyaedt import is_ironpython
-from pyaedt import is_linux
-from pyaedt import is_windows
from pyaedt.application.Design import Design
from pyaedt.application.JobManager import update_hpc_option
from pyaedt.application.Variables import Variable
@@ -29,6 +50,9 @@
from pyaedt.generic.constants import VIEW
from pyaedt.generic.general_methods import filter_tuple
from pyaedt.generic.general_methods import generate_unique_name
+from pyaedt.generic.general_methods import is_ironpython
+from pyaedt.generic.general_methods import is_linux
+from pyaedt.generic.general_methods import is_windows
from pyaedt.generic.general_methods import open_file
from pyaedt.generic.general_methods import pyaedt_function_handler
from pyaedt.generic.settings import settings
@@ -40,6 +64,7 @@
from pyaedt.modules.SolveSetup import Setup
from pyaedt.modules.SolveSetup import SetupHFSS
from pyaedt.modules.SolveSetup import SetupHFSSAuto
+from pyaedt.modules.SolveSetup import SetupIcepak
from pyaedt.modules.SolveSetup import SetupMaxwell
from pyaedt.modules.SolveSetup import SetupQ3D
from pyaedt.modules.SolveSetup import SetupSBR
@@ -77,7 +102,7 @@ class Analysis(Design, object):
Version of AEDT to use.
NG : bool
Whether to run AEDT in the non-graphical mode.
- new_desktop_session : bool, optional
+ new_desktop : bool, optional
Whether to launch an instance of AEDT in a new thread, even if
another instance of the ``specified_version`` is active on the
machine.
@@ -86,12 +111,15 @@ class Analysis(Design, object):
student_version : bool
Whether to enable the student version of AEDT.
aedt_process_id : int, optional
- Only used when ``new_desktop_session = False``, specifies by process ID which instance
+ Only used when ``new_desktop = False``, specifies by process ID which instance
of Electronics Desktop to point PyAEDT at.
ic_mode : bool, optional
Whether to set the design to IC mode. The default is ``None``, which means to retain the
existing setting. This parameter applies only to HFSS 3D Layout.
-
+ remove_lock : bool, optional
+ Whether to remove lock to project before opening it or not.
+ The default is ``False``, which means to not unlock
+ the existing project if needed and raise an exception.
"""
def __init__(
@@ -103,13 +131,14 @@ def __init__(
setup_name,
specified_version,
non_graphical,
- new_desktop_session,
+ new_desktop,
close_on_exit,
student_version,
machine="",
port=0,
aedt_process_id=None,
ic_mode=None,
+ remove_lock=False,
):
Design.__init__(
self,
@@ -119,13 +148,14 @@ def __init__(
solution_type,
specified_version,
non_graphical,
- new_desktop_session,
+ new_desktop,
close_on_exit,
student_version,
machine,
port,
aedt_process_id,
ic_mode,
+ remove_lock,
)
self._excitation_objects = {}
self._setup = None
@@ -509,7 +539,7 @@ def get_traces_for_plot(
first_element_filter=None,
second_element_filter=None,
category="dB(S",
- differential_pairs=[],
+ differential_pairs=None,
):
# type: (bool, bool, str, str, str, list) -> list
"""Retrieve a list of traces of specified designs ready to use in plot reports.
@@ -528,9 +558,9 @@ def get_traces_for_plot(
This parameter accepts ``*`` and ``?`` as special characters. The default is ``None``.
category : str, optional
Plot category name as in the report (including operator).
- The default is ``"dB(S"``, which is the plot category name for capacitance.
+ The default is ``"dB(S)"``, which is the plot category name for capacitance.
differential_pairs : list, optional
- Differential pairs defined. The default is ``[]``.
+ Differential pairs defined. The default is ``None`` in which case an empty list is set.
Returns
-------
@@ -547,6 +577,7 @@ def get_traces_for_plot(
... first_element_filter="*_U1_data?",
... second_element_filter="*_U0_*", category="dB(S")
"""
+ differential_pairs = [] if differential_pairs is None else differential_pairs
if not first_element_filter:
first_element_filter = "*"
if not second_element_filter:
@@ -1296,6 +1327,8 @@ def _create_setup(self, name="MySetupAuto", setup_type=None, props=None):
setup = SetupMaxwell(self, setup_type, name)
elif setup_type == 14:
setup = SetupQ3D(self, setup_type, name)
+ elif setup_type in [11, 36]:
+ setup = SetupIcepak(self, setup_type, name)
else:
setup = SetupHFSS(self, setup_type, name)
@@ -1922,7 +1955,7 @@ def solve_in_batch(
Number of tasks to use in the simulation.
Set ``num_tasks`` to ``-1`` to apply auto settings and distributed mode.
setup : str
- Name of the setup, which can be an optimetric setup or a simple setup.
+ Name of the setup, which can be an optimetrics setup or a simple setup.
The default is ``None``, in which case all setups are solved.
revert_to_initial_mesh : bool, optional
Whether to revert to the initial mesh before solving. The default is ``False``.
diff --git a/pyaedt/application/Analysis3D.py b/pyaedt/application/Analysis3D.py
index dc19a77bc33..435badc9708 100644
--- a/pyaedt/application/Analysis3D.py
+++ b/pyaedt/application/Analysis3D.py
@@ -1,7 +1,30 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import csv
import ntpath
import os
-import warnings
from pyaedt.application.Analysis import Analysis
from pyaedt.generic.configurations import Configurations
@@ -39,13 +62,13 @@ class FieldAnalysis3D(Analysis, object):
Name of the setup to use as the nominal. The default is
``None``, in which case the active setup is used or
nothing is used.
- specified_version : str, int, float, optional
+ version : str, int, float, optional
Version of AEDT to use. The default is ``None``, in which case
the active version or latest installed version is used.
non_graphical : bool, optional
Whether to run AEDT in non-graphical mode. The default
is ``False``, in which case AEDT is launched in the graphical mode.
- new_desktop_session : bool, optional
+ new_desktop : bool, optional
Whether to launch an instance of AEDT in a new thread, even if
another instance of the ``specified_version`` is active on the
machine. The default is ``False``.
@@ -55,8 +78,12 @@ class FieldAnalysis3D(Analysis, object):
Whether to enable the student version of AEDT. The default
is ``False``.
aedt_process_id : int, optional
- Only used when ``new_desktop_session = False``, specifies by process ID which instance
+ Only used when ``new_desktop = False``, specifies by process ID which instance
of Electronics Desktop to point PyAEDT at.
+ remove_lock : bool, optional
+ Whether to remove lock to project before opening it or not.
+ The default is ``False``, which means to not unlock
+ the existing project if needed and raise an exception.
"""
def __init__(
@@ -66,14 +93,15 @@ def __init__(
designname,
solution_type,
setup_name=None,
- specified_version=None,
+ version=None,
non_graphical=False,
- new_desktop_session=False,
+ new_desktop=False,
close_on_exit=False,
student_version=False,
machine="",
port=0,
aedt_process_id=None,
+ remove_lock=False,
):
Analysis.__init__(
self,
@@ -82,14 +110,15 @@ def __init__(
designname,
solution_type,
setup_name,
- specified_version,
+ version,
non_graphical,
- new_desktop_session,
+ new_desktop,
close_on_exit,
student_version,
machine,
port,
aedt_process_id,
+ remove_lock=remove_lock,
)
self._post = None
self._modeler = None
@@ -422,8 +451,8 @@ def get_property_value(self, assignment, property_name, property_type=None):
return val
return None
- @pyaedt_function_handler(object_list="assignment", no_vacuum="vacuum", no_pec="pec")
- def copy_solid_bodies_from(self, design, assignment=None, vacuum=True, pec=True, include_sheets=False):
+ @pyaedt_function_handler(object_list="assignment")
+ def copy_solid_bodies_from(self, design, assignment=None, no_vacuum=True, no_pec=True, include_sheets=False):
"""Copy a list of objects and user defined models from one design to the active design.
If user defined models are selected, the project will be saved automatically.
@@ -433,10 +462,10 @@ def copy_solid_bodies_from(self, design, assignment=None, vacuum=True, pec=True,
Starting application object. For example, ``hfss1= HFSS3DLayout``.
assignment : list, optional
List of objects and user defined components to copy. The default is ``None``.
- vacuum : bool, optional
+ no_vacuum : bool, optional
Whether to include vacuum objects for the copied objects.
The default is ``True``.
- pec :
+ no_pec :
Whether to include pec objects for the copied objects. The
default is ``True``.
include_sheets :
@@ -487,9 +516,9 @@ def copy_solid_bodies_from(self, design, assignment=None, vacuum=True, pec=True,
include_object = True
for key, val in material_properties.items():
if val.name == body:
- if vacuum and val.material_name.lower() == "vacuum":
+ if no_vacuum and val.material_name.lower() == "vacuum":
include_object = False
- if pec and val.material_name == "pec":
+ if no_pec and val.material_name == "pec":
include_object = False
if include_object:
selection_list.append(body)
@@ -504,7 +533,99 @@ def copy_solid_bodies_from(self, design, assignment=None, vacuum=True, pec=True,
self.modeler.refresh_all_ids()
return True
- @pyaedt_function_handler(object_list="assignment_to_export", removed_objects="assignment_to_remove")
+ @pyaedt_function_handler(filename="input_file")
+ def import_3d_cad(
+ self,
+ input_file,
+ healing=False,
+ refresh_all_ids=True,
+ import_materials=False,
+ create_lightweigth_part=False,
+ group_by_assembly=False,
+ create_group=True,
+ separate_disjoints_lumped_object=False,
+ import_free_surfaces=False,
+ point_coicidence_tolerance=1e-6,
+ heal_stl=True,
+ reduce_stl=False,
+ reduce_percentage=0,
+ reduce_error=0,
+ merge_planar_faces=True,
+ ):
+ """Import a CAD model.
+
+ Parameters
+ ----------
+ input_file : str
+ Full path and name of the CAD file.
+ healing : bool, optional
+ Whether to perform healing. The default is ``False``.
+ refresh_all_ids : bool, optional
+ Whether to refresh all IDs after the CAD file is loaded. The
+ default is ``True``. Refreshing IDs can take a lot of time in
+ a big project.
+ import_materials : bool optional
+ Whether to import material names from the file if present. The
+ default is ``False``.
+ create_lightweigth_part : bool ,optional
+ Whether to import a lightweight part. The default is ``True``.
+ group_by_assembly : bool, optional
+ Whether to import by subassembly. The default is ``False``, in which
+ case the import is by individual parts.
+ create_group : bool, optional
+ Whether to create a group of imported objects. The default is ``True``.
+ separate_disjoints_lumped_object : bool, optional
+ Whether to automatically separate disjoint parts. The default is ``False``.
+ import_free_surfaces : bool, optional
+ Whether to import free surfaces parts. The default is ``False``.
+ point_coicidence_tolerance : float, optional
+ Tolerance on the point. The default is ``1e-6``.
+ heal_stl : bool, optional
+ Whether to heal the STL file on import. The default is ``True``.
+ reduce_stl : bool, optional
+ Whether to reduce the STL file on import. The default is ``True``.
+ reduce_percentage : int, optional
+ Percentage to reduce the STL file by if ``reduce_stl=True``. The default is ``0``.
+ reduce_error : int, optional
+ Error percentage during STL reduction operation. The default is ``0``.
+ merge_planar_faces : bool, optional
+ Whether to merge planar faces during import. The default is ``True``.
+
+ Returns
+ -------
+ bool
+ ``True`` when successful, ``False`` when failed.
+
+ References
+ ----------
+
+ >>> oEditor.Import
+ """
+ return self.modeler.import_3d_cad(
+ input_file=input_file,
+ healing=healing,
+ refresh_all_ids=refresh_all_ids,
+ import_materials=import_materials,
+ create_lightweigth_part=create_lightweigth_part,
+ group_by_assembly=group_by_assembly,
+ create_group=create_group,
+ separate_disjoints_lumped_object=separate_disjoints_lumped_object,
+ import_free_surfaces=import_free_surfaces,
+ point_coicidence_tolerance=point_coicidence_tolerance,
+ heal_stl=heal_stl,
+ reduce_stl=reduce_stl,
+ reduce_percentage=reduce_percentage,
+ reduce_error=reduce_error,
+ merge_planar_faces=merge_planar_faces,
+ )
+
+ @pyaedt_function_handler(
+ object_list="assignment_to_export",
+ removed_objects="assignment_to_remove",
+ fileName="file_name",
+ filePath="file_path",
+ fileFormat="file_format",
+ )
def export_3d_model(
self,
file_name="",
@@ -514,7 +635,6 @@ def export_3d_model(
assignment_to_remove=None,
major_version=-1,
minor_version=-1,
- **kwargs # fmt: skip
):
"""Export the 3D model.
@@ -545,83 +665,15 @@ def export_3d_model(
>>> oEditor.Export
"""
- if "fileName" in kwargs:
- warnings.warn(
- "`fileName` is deprecated. Use `file_name` instead.",
- DeprecationWarning,
- )
-
- file_name = kwargs["fileName"]
- if "filePath" in kwargs:
- warnings.warn(
- "`filePath` is deprecated. Use `file_path` instead.",
- DeprecationWarning,
- )
-
- file_path = kwargs["filePath"]
- if "fileFormat" in kwargs:
- warnings.warn(
- "`fileFormat` is deprecated. Use `file_format` instead.",
- DeprecationWarning,
- )
-
- file_format = kwargs["fileFormat"]
- if not file_name:
- file_name = self.project_name + "_" + self.design_name
- if not file_path:
- file_path = self.working_directory
- if assignment_to_export is None:
- assignment_to_export = []
- if assignment_to_remove is None:
- assignment_to_remove = []
-
- sub_regions = []
- if self.settings.aedt_version > "2023.2":
- sub_regions = [
- o for o in self.modeler.non_model_objects if self.modeler[o].history().command == "CreateSubRegion"
- ]
-
- if not assignment_to_export:
- allObjects = self.modeler.object_names
- if assignment_to_remove:
- for rem in assignment_to_remove:
- allObjects.remove(rem)
- else:
- if "Region" in allObjects:
- allObjects.remove("Region")
- for o in sub_regions:
- allObjects.remove(o)
- else:
- allObjects = assignment_to_export[:]
-
- self.logger.debug("Exporting {} objects".format(len(allObjects)))
-
- # actual version supported by AEDT is 29.0
- if major_version == -1:
- if file_format in [".sm3", ".sat", ".sab"]:
- major_version = 29
- if minor_version == -1:
- if file_format in [".sm3", ".sat", ".sab"]:
- minor_version = 0
- stringa = ",".join(allObjects)
- arg = [
- "NAME:ExportParameters",
- "AllowRegionDependentPartSelectionForPMLCreation:=",
- True,
- "AllowRegionSelectionForPMLCreation:=",
- True,
- "Selections:=",
- stringa,
- "File Name:=",
- os.path.join(file_path, file_name + file_format).replace("\\", "/"),
- "Major Version:=",
- major_version,
- "Minor Version:=",
- minor_version,
- ]
-
- self.modeler.oeditor.Export(arg)
- return True
+ return self.modeler.export_3d_model(
+ file_name=file_name,
+ file_path=file_path,
+ file_format=file_format,
+ assignment_to_export=assignment_to_export,
+ assignment_to_remove=assignment_to_remove,
+ major_version=major_version,
+ minor_version=minor_version,
+ )
@pyaedt_function_handler()
def get_all_sources(self):
@@ -1073,7 +1125,7 @@ def flatten_3d_components(self, components=None, purge_history=True, password=No
self.modeler.set_working_coordinate_system(target_cs)
comp.delete()
obj_set = set(self.modeler.objects.values())
- self.copy_solid_bodies_from(app, vacuum=False, pec=False, include_sheets=True)
+ self.copy_solid_bodies_from(app, no_vacuum=False, no_pec=False, include_sheets=True)
self.modeler.refresh_all_ids()
self.modeler.set_working_coordinate_system(oldcs)
if self.design_type == "Icepak":
diff --git a/pyaedt/application/Analysis3DLayout.py b/pyaedt/application/Analysis3DLayout.py
index 7e720234103..fee24cda10e 100644
--- a/pyaedt/application/Analysis3DLayout.py
+++ b/pyaedt/application/Analysis3DLayout.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import os
from pyaedt.application.Analysis import Analysis
@@ -35,13 +59,13 @@ class FieldAnalysis3DLayout(Analysis):
Name of the setup to use as the nominal. The default is
``None``, in which case the active setup is used or
nothing is used.
- specified_version : str, int, float, optional
+ version : str, int, float, optional
Version of AEDT to use. The default is ``None``, in which case
the active version or latest installed version is used.
- NG : bool, optional
+ non_graphical : bool, optional
Whether to run AEDT in the non-graphical mode. The default
is ``False``, in which case AEDT is launched in the graphical mode.
- new_desktop_session : bool, optional
+ new_desktop : bool, optional
Whether to launch an instance of AEDT in a new thread, even if
another instance of the ``specified_version`` is active on the
machine. The default is ``False``.
@@ -52,10 +76,14 @@ class FieldAnalysis3DLayout(Analysis):
is ``False``.
aedt_process_id : int, optional
Specifies by process ID the instance of AEDT to point PyAEDT at.
- This parameter is only used when ``new_desktop_session=False``.
+ This parameter is only used when ``new_desktop=False``.
ic_mode : bool, optional
Whether to set the design to IC mode. The default is ``None``, which means to retain the
existing setting.
+ remove_lock : bool, optional
+ Whether to remove lock to project before opening it or not.
+ The default is ``False``, which means to not unlock
+ the existing project if needed and raise an exception.
"""
@@ -66,15 +94,16 @@ def __init__(
designname,
solution_type,
setup_name=None,
- specified_version=None,
+ version=None,
non_graphical=False,
- new_desktop_session=False,
+ new_desktop=False,
close_on_exit=False,
student_version=False,
machine="",
port=0,
aedt_process_id=None,
ic_mode=None,
+ remove_lock=False,
):
Analysis.__init__(
self,
@@ -83,15 +112,16 @@ def __init__(
designname,
solution_type,
setup_name,
- specified_version,
+ version,
non_graphical,
- new_desktop_session,
+ new_desktop,
close_on_exit,
student_version,
machine,
port,
aedt_process_id,
ic_mode,
+ remove_lock=remove_lock,
)
self._modeler = None
self._mesh = None
diff --git a/pyaedt/application/AnalysisMaxwellCircuit.py b/pyaedt/application/AnalysisMaxwellCircuit.py
index 3e53372604a..8f34e2e9977 100644
--- a/pyaedt/application/AnalysisMaxwellCircuit.py
+++ b/pyaedt/application/AnalysisMaxwellCircuit.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
from pyaedt.application.Analysis import Analysis
from pyaedt.generic.settings import settings
@@ -19,14 +43,14 @@ class AnalysisMaxwellCircuit(Analysis):
Name of the design to select. The default is ``None``, in
which case an attempt is made to get an active design. If no
designs are present, an empty design is created.
- specified_version : str, int, float, optional
+ version : str, int, float, optional
Version of AEDT to use. The default is ``None``. If ``None``,
the active setup is used or the latest installed version is
used.
NG : bool, optional
Whether to launch AEDT in the non-graphical mode. The default
is ``False``, in which case AEDT is launched in the graphical mode.
- new_desktop_session : bool, optional
+ new_desktop : bool, optional
Whether to launch an instance of AEDT in a new thread, even if
another instance of the ``specified_version`` is active on the
machine. The default is ``False``.
@@ -35,9 +59,12 @@ class AnalysisMaxwellCircuit(Analysis):
student_version : bool, optional
Whether to open the AEDT student version. The default is ``False``.
aedt_process_id : int, optional
- Only used when ``new_desktop_session = False``, specifies by process ID which instance
+ Only used when ``new_desktop = False``, specifies by process ID which instance
of Electronics Desktop to point PyAEDT at.
-
+ remove_lock : bool, optional
+ Whether to remove lock to project before opening it or not.
+ The default is ``False``, which means to not unlock
+ the existing project if needed and raise an exception.
"""
def __init__(
@@ -45,14 +72,15 @@ def __init__(
application,
projectname,
designname,
- specified_version=None,
+ version=None,
non_graphical=False,
- new_desktop_session=False,
+ new_desktop=False,
close_on_exit=False,
student_version=False,
machine="",
port=0,
aedt_process_id=None,
+ remove_lock=False,
):
Analysis.__init__(
self,
@@ -61,14 +89,15 @@ def __init__(
designname,
None,
None,
- specified_version,
+ version,
non_graphical,
- new_desktop_session,
+ new_desktop,
close_on_exit,
student_version,
machine,
port,
aedt_process_id,
+ remove_lock=remove_lock,
)
self._modeler = None
if not settings.lazy_load:
diff --git a/pyaedt/application/AnalysisNexxim.py b/pyaedt/application/AnalysisNexxim.py
index 30a3307ff53..4ae54d9e5a9 100644
--- a/pyaedt/application/AnalysisNexxim.py
+++ b/pyaedt/application/AnalysisNexxim.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
from pyaedt.application.Analysis import Analysis
from pyaedt.generic.general_methods import pyaedt_function_handler
from pyaedt.generic.settings import settings
@@ -35,14 +59,15 @@ def __init__(
designname,
solution_type,
setup_name=None,
- specified_version=None,
+ version=None,
non_graphical=False,
- new_desktop_session=False,
+ new_desktop=False,
close_on_exit=False,
student_version=False,
machine="",
port=0,
aedt_process_id=None,
+ remove_lock=False,
):
Analysis.__init__(
self,
@@ -51,14 +76,15 @@ def __init__(
designname,
solution_type,
setup_name,
- specified_version,
+ version,
non_graphical,
- new_desktop_session,
+ new_desktop,
close_on_exit,
student_version,
machine,
port,
aedt_process_id,
+ remove_lock=remove_lock,
)
self._modeler = None
@@ -123,7 +149,7 @@ def push_down(self, component):
out_name = component
try:
self.desktop_class.active_design(self.oproject, out_name, self.design_type)
- self.__init__(projectname=self.project_name, designname=out_name)
+ self.__init__(project=self.project_name, design=out_name)
except Exception: # pragma: no cover
return False
return True
@@ -140,7 +166,7 @@ def pop_up(self):
try:
parent_name = self.odesign.GetName().split(";")[1].split("/")[0]
self.desktop_class.active_design(self.oproject, parent_name, self.design_type)
- self.__init__(projectname=self.project_name, designname=parent_name)
+ self.__init__(project=self.project_name, design=parent_name)
except Exception:
return False
return True
diff --git a/pyaedt/application/AnalysisRMxprt.py b/pyaedt/application/AnalysisRMxprt.py
index a63acd5bc83..4989ecc2ef7 100644
--- a/pyaedt/application/AnalysisRMxprt.py
+++ b/pyaedt/application/AnalysisRMxprt.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
from pyaedt.application.Analysis import Analysis
from pyaedt.generic.general_methods import pyaedt_function_handler
from pyaedt.generic.settings import settings
@@ -24,14 +48,15 @@ def __init__(
designname,
solution_type,
setup_name=None,
- specified_version=None,
+ version=None,
non_graphical=False,
- new_desktop_session=False,
+ new_desktop=False,
close_on_exit=False,
student_version=False,
machine="",
port=0,
aedt_process_id=None,
+ remove_lock=False,
):
Analysis.__init__(
self,
@@ -40,14 +65,15 @@ def __init__(
designname,
solution_type,
setup_name,
- specified_version,
+ version,
non_graphical,
- new_desktop_session,
+ new_desktop,
close_on_exit,
student_version,
machine,
port,
aedt_process_id,
+ remove_lock=remove_lock,
)
self._modeler = None
self._post = None
diff --git a/pyaedt/application/AnalysisTwinBuilder.py b/pyaedt/application/AnalysisTwinBuilder.py
index 85d9dc246a0..1acabd68878 100644
--- a/pyaedt/application/AnalysisTwinBuilder.py
+++ b/pyaedt/application/AnalysisTwinBuilder.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
from pyaedt.application.Analysis import Analysis
from pyaedt.generic.general_methods import pyaedt_function_handler
from pyaedt.generic.settings import settings
@@ -46,14 +70,15 @@ def __init__(
designname,
solution_type,
setup_name=None,
- specified_version=None,
+ version=None,
non_graphical=False,
- new_desktop_session=False,
+ new_desktop=False,
close_on_exit=False,
student_version=False,
machine="",
port=0,
aedt_process_id=None,
+ remove_lock=False,
):
Analysis.__init__(
self,
@@ -62,14 +87,15 @@ def __init__(
designname,
solution_type,
setup_name,
- specified_version,
+ version,
non_graphical,
- new_desktop_session,
+ new_desktop,
close_on_exit,
student_version,
machine,
port,
aedt_process_id,
+ remove_lock=remove_lock,
)
self._modeler = None
self._post = None
diff --git a/pyaedt/application/Design.py b/pyaedt/application/Design.py
index 6f88d4a0131..536f70c5080 100644
--- a/pyaedt/application/Design.py
+++ b/pyaedt/application/Design.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
"""
This module contains these classes: ``Design``.
@@ -51,6 +75,7 @@
from pyaedt.generic.general_methods import read_csv
from pyaedt.generic.general_methods import read_tab
from pyaedt.generic.general_methods import read_xlsx
+from pyaedt.generic.general_methods import remove_project_lock
from pyaedt.generic.general_methods import settings
from pyaedt.generic.general_methods import write_csv
from pyaedt.modules.Boundary import BoundaryObject
@@ -89,13 +114,13 @@ class Design(AedtObjects):
solution_type : str, optional
Solution type to apply to the design. The default is
``None``, in which case the default type is applied.
- specified_version : str, int, float, optional
+ version : str, int, float, optional
Version of AEDT to use. The default is ``None``, in which case
the active version or latest installed version is used.
non_graphical : bool, optional
Whether to run AEDT in non-graphical mode. The default
is ``False``, in which case AEDT launches in graphical mode.
- new_desktop_session : bool, optional
+ new_desktop : bool, optional
Whether to launch an instance of AEDT in a new thread, even if
another instance of the ``specified_version`` is active on the
machine. The default is ``False``.
@@ -105,12 +130,15 @@ class Design(AedtObjects):
Whether to enable the student version of AEDT. The default
is ``False``.
aedt_process_id : int, optional
- Only used when ``new_desktop_session = False``, specifies by process ID which instance
+ Only used when ``new_desktop = False``, specifies by process ID which instance
of Electronics Desktop to point PyAEDT at.
ic_mode : bool, optional
Whether to set the design to IC mode or not. The default is ``None``, which means to retain
the existing setting. Applicable only to ``Hfss3dLayout``.
-
+ remove_lock : bool, optional
+ Whether to remove lock to project before opening it or not.
+ The default is ``False``, which means to not unlock
+ the existing project if needed and raise an exception.
"""
@property
@@ -178,12 +206,12 @@ def info(self):
def _init_design(self, project_name, design_name, solution_type=None):
# calls the method from the application class
self._init_from_design(
- projectname=project_name,
- designname=design_name,
+ project=project_name,
+ design=design_name,
solution_type=solution_type,
- specified_version=settings.aedt_version,
+ version=settings.aedt_version,
non_graphical=self._desktop_class.non_graphical,
- new_desktop_session=False,
+ new_desktop=False,
close_on_exit=self.close_on_exit,
student_version=self.student_version,
machine=self._desktop_class.machine,
@@ -196,17 +224,19 @@ def __init__(
project_name=None,
design_name=None,
solution_type=None,
- specified_version=None,
+ version=None,
non_graphical=False,
- new_desktop_session=False,
+ new_desktop=False,
close_on_exit=False,
student_version=False,
machine="",
port=0,
aedt_process_id=None,
ic_mode=None,
+ remove_lock=False,
):
-
+ self._design_name = None
+ self._project_name = None
self.__t = None
if (
not is_ironpython
@@ -230,9 +260,9 @@ def __init__(
self.close_on_exit = close_on_exit
self._desktop_class = None
self._desktop_class = _init_desktop_from_design(
- specified_version,
+ version,
non_graphical,
- new_desktop_session,
+ new_desktop,
close_on_exit,
student_version,
machine,
@@ -263,14 +293,13 @@ def __init__(
self.design_solutions = DesignSolution(None, design_type, self._aedt_version)
self.design_solutions._solution_type = solution_type
self._temp_solution_type = solution_type
+ self._remove_lock = remove_lock
self.oproject = project_name
self.odesign = design_name
self._logger.oproject = self.oproject
self._logger.odesign = self.odesign
AedtObjects.__init__(self, self._desktop_class, self.oproject, self.odesign, is_inherithed=True)
self.logger.info("Aedt Objects correctly read")
- # if t:
- # t.join()
if not self.__t and not settings.lazy_load and not is_ironpython and os.path.exists(self.project_file):
self.__t = threading.Thread(target=load_aedt_thread, args=(self.project_file,), daemon=True)
self.__t.start()
@@ -611,11 +640,11 @@ def design_name(self):
if not self.odesign:
return None
- name = _retry_ntimes(5, self.odesign.GetName)
- if ";" in name:
- return name.split(";")[1]
+ self._design_name = _retry_ntimes(5, self.odesign.GetName)
+ if ";" in self._design_name:
+ return self._design_name.split(";")[1]
else:
- return name
+ return self._design_name
@design_name.setter
def design_name(self, new_name):
@@ -638,6 +667,7 @@ def design_name(self, new_name):
timeout -= timestep
if timeout < 0:
raise RuntimeError("Timeout reached while checking design renaming.")
+ self._design_name = new_name
@property
def design_list(self):
@@ -694,7 +724,8 @@ def project_name(self):
"""
if self.oproject:
try:
- return self.oproject.GetName()
+ self._project_name = self.oproject.GetName()
+ return self._project_name
except Exception:
return None
else:
@@ -1063,6 +1094,10 @@ def odesign(self):
>>> oProject.SetActiveDesign
>>> oProject.InsertDesign
"""
+ if settings.use_multi_desktop: # pragma: no cover
+ self._desktop_class.grpc_plugin.recreate_application(True)
+ if self._design_name:
+ self._odesign = self.oproject.SetActiveDesign(self._design_name)
return self._odesign
@odesign.setter
@@ -1090,6 +1125,7 @@ def odesign(self, des_name):
self.solution_type == "HFSS3DLayout" or self.solution_type == "HFSS 3D Layout Design"
):
self.set_oo_property_value(self.odesign, "Design Settings", "Design Mode/IC", self._ic_mode)
+ self.desktop_class.active_design(self.oproject, des_name)
@property
def oproject(self):
@@ -1106,6 +1142,8 @@ def oproject(self):
>>> oDesktop.SetActiveProject
>>> oDesktop.NewProject
"""
+ if settings.use_multi_desktop: # pragma: no cover
+ self._desktop_class.grpc_plugin.recreate_application(True)
return self._oproject
@oproject.setter
@@ -1147,7 +1185,11 @@ def oproject(self, proj_name=None):
self.logger.info("Project %s set to active.", pname)
elif os.path.exists(project):
if is_project_locked(project):
- raise RuntimeError("Project is locked. Close or remove the lock before proceeding.")
+ if self._remove_lock: # pragma: no cover
+ self.logger.warning("Project is locked. Removing it and opening.")
+ remove_project_lock(project)
+ else: # pragma: no cover
+ raise RuntimeError("Project is locked. Close or remove the lock before proceeding.")
self.logger.info("aedt project found. Loading it.")
self._oproject = self.odesktop.OpenProject(project)
self._add_handler()
@@ -1172,7 +1214,11 @@ def oproject(self, proj_name=None):
self.logger.info("Project %s set to active.", pname)
else:
if is_project_locked(proj_name):
- raise RuntimeError("Project is locked. Close or remove the lock before proceeding.")
+ if self._remove_lock: # pragma: no cover
+ self.logger.warning("Project is locked. Removing it and opening.")
+ remove_project_lock(proj_name)
+ else: # pragma: no cover
+ raise RuntimeError("Project is locked. Close or remove the lock before proceeding.")
self._oproject = self.odesktop.OpenProject(proj_name)
if not is_windows and settings.aedt_version:
time.sleep(1)
@@ -1245,6 +1291,47 @@ def remove_all_unused_definitions(self):
self.oproject.RemoveAllUnusedDefinitions()
return True
+ @pyaedt_function_handler()
+ def get_profile(self, name=None):
+ """Get profile information.
+
+ Parameters
+ ----------
+ name : str
+ Setup name. The default is ``None``, in which case all available setups are returned.
+
+ Returns
+ -------
+ dict of :class:`pyaedt.modeler.cad.elements3d.BinaryTree` when successful,
+ ``False`` when failed.
+ """
+ from pyaedt.modeler.cad.elements3d import BinaryTreeNode
+
+ if not name:
+ name = self.setup_names
+ if not isinstance(name, list):
+ name = [name]
+
+ profile_setups_obj = self.get_oo_object(self.odesign, "results/profile")
+
+ profile_objs = {}
+ if profile_setups_obj:
+ profile_setup_names = self.get_oo_name(self.odesign, "results/profile")
+ for n in name:
+ for profile_setup_name in profile_setup_names:
+ if n in profile_setup_name:
+ profile_setup_obj = self.get_oo_object(profile_setups_obj, profile_setup_name)
+ if profile_setup_obj and self.get_oo_name(profile_setup_obj):
+ try:
+ profile_tree = BinaryTreeNode("profile", profile_setup_obj)
+ profile_objs[profile_setup_name] = profile_tree
+ except Exception: # pragma: no cover
+ self.logger.error("{} profile could not be obtained.".format(profile_setup_name))
+ return profile_objs
+ else: # pragma: no cover
+ self.logger.error("Profile can not be obtained.")
+ return False
+
@pyaedt_function_handler()
def get_oo_name(self, aedt_object, object_name=None):
"""Return the object-oriented AEDT property names.
@@ -1361,17 +1448,17 @@ def set_oo_property_value(self, aedt_object, object_name, prop_name, value):
except Exception:
return False
- @pyaedt_function_handler()
- def export_profile(self, setup_name, variation_string="", file_path=None):
+ @pyaedt_function_handler(setup_name="setup", variation_string="variation", file_path="output_file")
+ def export_profile(self, setup, variation="", output_file=None):
"""Export a solution profile to a PROF file.
Parameters
----------
- setup_name : str
+ setup : str
Setup name. For example, ``'Setup1'``.
- variation_string : str
+ variation : str
Variation string with values. For example, ``'radius=3mm'``.
- file_path : str, optional
+ output_file : str, optional
Full path to the PROF file. The default is ``None``, in which case
the working directory is used.
@@ -1387,55 +1474,54 @@ def export_profile(self, setup_name, variation_string="", file_path=None):
>>> oDesign.ExportProfile
"""
- if not file_path:
- file_path = os.path.join(self.working_directory, generate_unique_name("Profile") + ".prof")
- if not variation_string:
+ if not output_file:
+ output_file = os.path.join(self.working_directory, generate_unique_name("Profile") + ".prof")
+ if not variation:
val_str = []
for el, val in self.available_variations.nominal_w_values_dict.items():
val_str.append("{}={}".format(el, val))
if self.design_type == "HFSS 3D Layout Design":
- variation_string = " ".join(val_str)
+ variation = " ".join(val_str)
else:
- variation_string = ",".join(val_str)
+ variation = ",".join(val_str)
if self.design_type == "2D Extractor":
- for setup in self.setups:
- if setup.name == setup_name:
- if "CGDataBlock" in setup.props:
- file_path = os.path.splitext(file_path)[0] + "CG" + os.path.splitext(file_path)[1]
- self.odesign.ExportProfile(setup_name, variation_string, "CG", file_path, True)
- self.logger.info("Exported Profile to file {}".format(file_path))
- if "RLDataBlock" in setup.props:
- file_path = os.path.splitext(file_path)[0] + "RL" + os.path.splitext(file_path)[1]
- self.odesign.ExportProfile(setup_name, variation_string, "RL", file_path, True)
- self.logger.info("Exported Profile to file {}".format(file_path))
+ for s in self.setups:
+ if s.name == setup:
+ if "CGDataBlock" in s.props:
+ output_file = os.path.splitext(output_file)[0] + "CG" + os.path.splitext(output_file)[1]
+ self.odesign.ExportProfile(setup, variation, "CG", output_file, True)
+ self.logger.info("Exported Profile to file {}".format(output_file))
+ if "RLDataBlock" in s.props:
+ output_file = os.path.splitext(output_file)[0] + "RL" + os.path.splitext(output_file)[1]
+ self.odesign.ExportProfile(setup, variation, "RL", output_file, True)
+ self.logger.info("Exported Profile to file {}".format(output_file))
break
elif self.design_type == "Q3D Extractor":
- for setup in self.setups:
- if setup.name == setup_name:
- if "Cap" in setup.props:
- file_path = os.path.splitext(file_path)[0] + "CG" + os.path.splitext(file_path)[1]
- self.odesign.ExportProfile(setup_name, variation_string, "CG", file_path, True)
- self.logger.info("Exported Profile to file {}".format(file_path))
- if "AC" in setup.props:
- file_path = os.path.splitext(file_path)[0] + "ACRL" + os.path.splitext(file_path)[1]
- self.odesign.ExportProfile(setup_name, variation_string, "AC RL", file_path, True)
- self.logger.info("Exported Profile to file {}".format(file_path))
- if "DC" in setup.props:
- file_path = os.path.splitext(file_path)[0] + "DC" + os.path.splitext(file_path)[1]
- self.odesign.ExportProfile(setup_name, variation_string, "DC RL", file_path, True)
- self.logger.info("Exported Profile to file {}".format(file_path))
-
+ for s in self.setups:
+ if s.name == setup:
+ if "Cap" in s.props:
+ output_file = os.path.splitext(output_file)[0] + "CG" + os.path.splitext(output_file)[1]
+ self.odesign.ExportProfile(setup, variation, "CG", output_file, True)
+ self.logger.info("Exported Profile to file {}".format(output_file))
+ if "AC" in s.props:
+ output_file = os.path.splitext(output_file)[0] + "ACRL" + os.path.splitext(output_file)[1]
+ self.odesign.ExportProfile(setup, variation, "AC RL", output_file, True)
+ self.logger.info("Exported Profile to file {}".format(output_file))
+ if "DC" in s.props:
+ output_file = os.path.splitext(output_file)[0] + "DC" + os.path.splitext(output_file)[1]
+ self.odesign.ExportProfile(setup, variation, "DC RL", output_file, True)
+ self.logger.info("Exported Profile to file {}".format(output_file))
break
else:
try:
- self.odesign.ExportProfile(setup_name, variation_string, file_path)
+ self.odesign.ExportProfile(setup, variation, output_file)
except Exception:
- self.odesign.ExportProfile(setup_name, variation_string, file_path, True)
- self.logger.info("Exported Profile to file {}".format(file_path))
- return file_path
+ self.odesign.ExportProfile(setup, variation, output_file, True)
+ self.logger.info("Exported Profile to file {}".format(output_file))
+ return output_file
- @pyaedt_function_handler()
- def add_info_message(self, message_text, message_type=None):
+ @pyaedt_function_handler(message_text="text", message_type="level")
+ def add_info_message(self, text, level=None):
"""Add a type 0 "Info" message to either the global, active project, or active design
level of the message manager tree.
@@ -1443,9 +1529,9 @@ def add_info_message(self, message_text, message_type=None):
Parameters
----------
- message_text : str
+ text : str
Text to display as the info message.
- message_type : str, optional
+ level : str, optional
Level to add the "Info" message to. Options are ``"Global"``,
``"Project"``, and ``"Design"``. The default is ``None``,
in which case the "Info" message gets added to the ``"Design"``
@@ -1469,16 +1555,16 @@ def add_info_message(self, message_text, message_type=None):
"`add_info_message` is deprecated. Use `logger.design_logger.info` instead.",
DeprecationWarning,
)
- if message_type.lower() == "project":
- self.logger.project_logger.info(message_text)
- elif message_type.lower() == "design":
- self.logger.design_logger.info(message_text)
+ if level.lower() == "project":
+ self.logger.project_logger.info(text)
+ elif level.lower() == "design":
+ self.logger.design_logger.info(text)
else:
- self.logger.info(message_text)
+ self.logger.info(text)
return True
- @pyaedt_function_handler()
- def add_warning_message(self, message_text, message_type=None):
+ @pyaedt_function_handler(message_text="text", message_type="level")
+ def add_warning_message(self, text, level=None):
"""Add a type 0 "Warning" message to either the global, active project, or active design
level of the message manager tree.
@@ -1486,9 +1572,9 @@ def add_warning_message(self, message_text, message_type=None):
Parameters
----------
- message_text : str
+ text : str
Text to display as the "Warning" message.
- message_type : str, optional
+ level : str, optional
Level to add the "Warning" message to. Options are ``"Global"``,
``"Project"``, and ``"Design"``. The default is ``None``,
in which case the "Warning" message gets added to the ``"Design"``
@@ -1513,16 +1599,16 @@ def add_warning_message(self, message_text, message_type=None):
DeprecationWarning,
)
- if message_type.lower() == "project":
- self.logger.project_logger.warning(message_text)
- elif message_type.lower() == "design":
- self.logger.design_logger.warning(message_text)
+ if level.lower() == "project":
+ self.logger.project_logger.warning(text)
+ elif level.lower() == "design":
+ self.logger.design_logger.warning(text)
else:
- self.logger.warning(message_text)
+ self.logger.warning(text)
return True
- @pyaedt_function_handler()
- def add_error_message(self, message_text, message_type=None):
+ @pyaedt_function_handler(message_text="text", message_type="level")
+ def add_error_message(self, text, level=None):
"""Add a type 0 "Error" message to either the global, active project, or active design
level of the message mmanager tree.
@@ -1530,9 +1616,9 @@ def add_error_message(self, message_text, message_type=None):
Parameters
----------
- message_text : str
+ text : str
Text to display as the "Error" message.
- message_type : str, optional
+ level : str, optional
Level to add the "Error" message to. Options are ``"Global"``,
``"Project"``, and ``"Design"``. The default is ``None``,
in which case the "Error" message gets added to the ``"Design"``
@@ -1557,12 +1643,12 @@ def add_error_message(self, message_text, message_type=None):
DeprecationWarning,
)
- if message_type.lower() == "project":
- self.logger.project_logger.error(message_text)
- elif message_type.lower() == "design":
- self.logger.design_logger.error(message_text)
+ if level.lower() == "project":
+ self.logger.project_logger.error(text)
+ elif level.lower() == "design":
+ self.logger.design_logger.error(text)
else:
- self.logger.error(message_text)
+ self.logger.error(text)
return True
@property
@@ -1633,15 +1719,15 @@ def set_license_type(self, license_type="Pool"):
except Exception:
return False
- @pyaedt_function_handler()
- def set_registry_key(self, key_full_name, key_value):
+ @pyaedt_function_handler(key_full_name="name", key_value="value")
+ def set_registry_key(self, name, value):
"""Change a specific registry key to a new value.
Parameters
----------
- key_full_name : str
+ name : str
Full name of the AEDT registry key.
- key_value : str, int
+ value : str, int
Value for the AEDT registry key.
Returns
-------
@@ -1654,33 +1740,33 @@ def set_registry_key(self, key_full_name, key_value):
>>> oDesktop.SetRegistryString
>>> oDesktop.SetRegistryInt
"""
- if isinstance(key_value, str):
+ if isinstance(value, str):
try:
- self.odesktop.SetRegistryString(key_full_name, key_value)
- self.logger.info("Key %s correctly changed.", key_full_name)
+ self.odesktop.SetRegistryString(name, value)
+ self.logger.info("Key %s correctly changed.", name)
return True
except Exception:
- self.logger.warning("Error setting up Key %s.", key_full_name)
+ self.logger.warning("Error setting up Key %s.", name)
return False
- elif isinstance(key_value, int):
+ elif isinstance(value, int):
try:
- self.odesktop.SetRegistryInt(key_full_name, key_value)
- self.logger.info("Key %s correctly changed.", key_full_name)
+ self.odesktop.SetRegistryInt(name, value)
+ self.logger.info("Key %s correctly changed.", name)
return True
except Exception:
- self.logger.warning("Error setting up Key %s.", key_full_name)
+ self.logger.warning("Error setting up Key %s.", name)
return False
else:
self.logger.warning("Key value must be an integer or string.")
return False
- @pyaedt_function_handler()
- def get_registry_key_string(self, key_full_name):
+ @pyaedt_function_handler(key_full_name="name")
+ def get_registry_key_string(self, name):
"""Get the value for the AEDT registry key if one exists.
Parameters
----------
- key_full_name : str
+ name : str
Full name of the AEDT registry key.
Returns
@@ -1693,15 +1779,15 @@ def get_registry_key_string(self, key_full_name):
>>> oDesktop.GetRegistryString
"""
- return self.odesktop.GetRegistryString(key_full_name)
+ return self.odesktop.GetRegistryString(name)
- @pyaedt_function_handler()
- def get_registry_key_int(self, key_full_name):
+ @pyaedt_function_handler(key_full_name="name")
+ def get_registry_key_int(self, name):
"""Get the value for the AEDT registry key if one exists.
Parameters
----------
- key_full_name : str
+ name : str
Full name of the AEDT registry key.
Returns
@@ -1714,15 +1800,15 @@ def get_registry_key_int(self, key_full_name):
>>> oDesktop.GetRegistryInt
"""
- return self.odesktop.GetRegistryInt(key_full_name)
+ return self.odesktop.GetRegistryInt(name)
- @pyaedt_function_handler()
- def check_beta_option_enabled(self, beta_option_name):
+ @pyaedt_function_handler(beta_option_name="beta_option")
+ def check_beta_option_enabled(self, beta_option):
"""Check if a beta option is enabled.
Parameters
----------
- beta_option_name : str
+ beta_option : str
Name of the beta option to check. For example, ``'SF43060_HFSS_PI'``.
Returns
@@ -1739,7 +1825,7 @@ def check_beta_option_enabled(self, beta_option_name):
i = 0
while limit > 0:
a = self.get_registry_key_string("Desktop/Settings/ProjectOptions/EnabledBetaOptions/Item{}".format(i))
- if a and a == beta_option_name:
+ if a and a == beta_option:
return True
elif a:
i += 1
@@ -1904,19 +1990,19 @@ def _optimetrics_variable_args(
arg3 = [tab, ["NAME:PropServers", propserver], ["NAME:ChangedProps", ["NAME:" + variable_name, arg2]]]
arg.append(arg3)
- @pyaedt_function_handler()
+ @pyaedt_function_handler(variable_name="name", min_val="minimum", max_val="maximum")
def activate_variable_statistical(
- self, variable_name, min_val=None, max_val=None, tolerance=None, probability=None, mean=None
+ self, name, minimum=None, maximum=None, tolerance=None, probability=None, mean=None
):
"""Activate statitistical analysis for a variable and optionally set up ranges.
Parameters
----------
- variable_name : str
+ name : str
Name of the variable.
- min_val : optional
+ minimum : optional
Minimum value for the variable. The default is ``None``.
- max_val : optional
+ maximum : optional
Maximum value for the variable. The default is ``None``.
tolerance : optional
Tolerance value for the variable. The default is ``None``.
@@ -1936,26 +2022,24 @@ def activate_variable_statistical(
>>> oDesign.ChangeProperty
"""
arg = ["NAME:AllTabs"]
- self._optimetrics_variable_args(
- arg, "Statistical", variable_name, min_val, max_val, tolerance, probability, mean
- )
- if "$" in variable_name:
+ self._optimetrics_variable_args(arg, "Statistical", name, minimum, maximum, tolerance, probability, mean)
+ if "$" in name:
self.oproject.ChangeProperty(arg)
else:
self.odesign.ChangeProperty(arg)
return True
- @pyaedt_function_handler()
- def activate_variable_optimization(self, variable_name, min_val=None, max_val=None):
+ @pyaedt_function_handler(variable_name="name", min_val="minimum", max_val="maximum")
+ def activate_variable_optimization(self, name, minimum=None, maximum=None):
"""Activate optimization analysis for a variable and optionally set up ranges.
Parameters
----------
- variable_name : str
+ name : str
Name of the variable.
- min_val : optional
+ minimum : optional
Minimum value for the variable. The default is ``None``.
- max_val : optional
+ maximum : optional
Maximum value for the variable. The default is ``None``.
Returns
@@ -1969,24 +2053,24 @@ def activate_variable_optimization(self, variable_name, min_val=None, max_val=No
>>> oDesign.ChangeProperty
"""
arg = ["NAME:AllTabs"]
- self._optimetrics_variable_args(arg, "Optimization", variable_name, min_val, max_val)
- if variable_name.startswith("$"):
+ self._optimetrics_variable_args(arg, "Optimization", name, minimum, maximum)
+ if name.startswith("$"):
self.oproject.ChangeProperty(arg)
else:
self.odesign.ChangeProperty(arg)
return True
- @pyaedt_function_handler()
- def activate_variable_sensitivity(self, variable_name, min_val=None, max_val=None):
+ @pyaedt_function_handler(variable_name="name", min_val="minimum", max_val="maximum")
+ def activate_variable_sensitivity(self, name, minimum=None, maximum=None):
"""Activate sensitivity analysis for a variable and optionally set up ranges.
Parameters
----------
- variable_name : str
+ name : str
Name of the variable.
- min_val : optional
+ minimum : optional
Minimum value for the variable. The default is ``None``.
- max_val : optional
+ maximum : optional
Maximum value for the variable. The default is ``None``.
Returns
@@ -2000,24 +2084,24 @@ def activate_variable_sensitivity(self, variable_name, min_val=None, max_val=Non
>>> oDesign.ChangeProperty
"""
arg = ["NAME:AllTabs"]
- self._optimetrics_variable_args(arg, "Sensitivity", variable_name, min_val, max_val)
- if "$" in variable_name:
+ self._optimetrics_variable_args(arg, "Sensitivity", name, minimum, maximum)
+ if "$" in name:
self.oproject.ChangeProperty(arg)
else:
self.odesign.ChangeProperty(arg)
return True
- @pyaedt_function_handler()
- def activate_variable_tuning(self, variable_name, min_val=None, max_val=None):
+ @pyaedt_function_handler(variable_name="name", min_val="minimum", max_val="maximum")
+ def activate_variable_tuning(self, name, minimum=None, maximum=None):
"""Activate tuning analysis for a variable and optionally set up ranges.
Parameters
----------
- variable_name : str
+ name : str
Name of the variable.
- min_val : optional
+ minimum : optional
Minimum value for the variable. The default is ``None``.
- max_val : optional
+ maximum : optional
Maximum value for the variable. The default is ``None``.
Returns
@@ -2031,20 +2115,20 @@ def activate_variable_tuning(self, variable_name, min_val=None, max_val=None):
>>> oDesign.ChangeProperty
"""
arg = ["NAME:AllTabs"]
- self._optimetrics_variable_args(arg, "Tuning", variable_name, min_val, max_val)
- if "$" in variable_name:
+ self._optimetrics_variable_args(arg, "Tuning", name, minimum, maximum)
+ if "$" in name:
self.oproject.ChangeProperty(arg)
else:
self.odesign.ChangeProperty(arg)
return True
- @pyaedt_function_handler()
- def deactivate_variable_statistical(self, variable_name):
+ @pyaedt_function_handler(variable_name="name")
+ def deactivate_variable_statistical(self, name):
"""Deactivate the statistical analysis for a variable.
Parameters
----------
- variable_name : str
+ name : str
Name of the variable.
Returns
@@ -2058,20 +2142,20 @@ def deactivate_variable_statistical(self, variable_name):
>>> oDesign.ChangeProperty
"""
arg = ["NAME:AllTabs"]
- self._optimetrics_variable_args(arg, "Statistical", variable_name, enable=False)
- if "$" in variable_name:
+ self._optimetrics_variable_args(arg, "Statistical", name, enable=False)
+ if "$" in name:
self.oproject.ChangeProperty(arg)
else:
self.odesign.ChangeProperty(arg)
return True
- @pyaedt_function_handler()
- def deactivate_variable_optimization(self, variable_name):
+ @pyaedt_function_handler(variable_name="name")
+ def deactivate_variable_optimization(self, name):
"""Deactivate the optimization analysis for a variable.
Parameters
----------
- variable_name : str
+ name : str
Name of the variable.
Returns
@@ -2085,20 +2169,20 @@ def deactivate_variable_optimization(self, variable_name):
>>> oDesign.ChangeProperty
"""
arg = ["NAME:AllTabs"]
- self._optimetrics_variable_args(arg, "Optimization", variable_name, enable=False)
- if "$" in variable_name:
+ self._optimetrics_variable_args(arg, "Optimization", name, enable=False)
+ if "$" in name:
self.oproject.ChangeProperty(arg)
else:
self.odesign.ChangeProperty(arg)
return True
- @pyaedt_function_handler()
- def deactivate_variable_sensitivity(self, variable_name):
+ @pyaedt_function_handler(variable_name="name")
+ def deactivate_variable_sensitivity(self, name):
"""Deactivate the sensitivity analysis for a variable.
Parameters
----------
- variable_name : str
+ name : str
Name of the variable.
Returns
@@ -2112,20 +2196,20 @@ def deactivate_variable_sensitivity(self, variable_name):
>>> oDesign.ChangeProperty
"""
arg = ["NAME:AllTabs"]
- self._optimetrics_variable_args(arg, "Sensitivity", variable_name, enable=False)
- if "$" in variable_name:
+ self._optimetrics_variable_args(arg, "Sensitivity", name, enable=False)
+ if "$" in name:
self.oproject.ChangeProperty(arg)
else:
self.odesign.ChangeProperty(arg)
return True
- @pyaedt_function_handler()
- def deactivate_variable_tuning(self, variable_name):
+ @pyaedt_function_handler(variable_name="name")
+ def deactivate_variable_tuning(self, name):
"""Deactivate the tuning analysis for a variable.
Parameters
----------
- variable_name : str
+ name : str
Name of the variable.
Returns
@@ -2139,20 +2223,20 @@ def deactivate_variable_tuning(self, variable_name):
>>> oDesign.ChangeProperty
"""
arg = ["NAME:AllTabs"]
- self._optimetrics_variable_args(arg, "Tuning", variable_name, enable=False)
- if "$" in variable_name:
+ self._optimetrics_variable_args(arg, "Tuning", name, enable=False)
+ if "$" in name:
self.oproject.ChangeProperty(arg)
else:
self.odesign.ChangeProperty(arg)
return True
- @pyaedt_function_handler
- def hidden_variable(self, variable_name, value=True):
+ @pyaedt_function_handler(variable_name="name")
+ def hidden_variable(self, name, value=True):
"""Set the variable to a hidden or unhidden variable.
Parameters
----------
- variable_name : str or list
+ name : str or list
One or more variable names.
value : bool, optional
Whether to hide the variable. The default is ``True``, in which case the variable
@@ -2173,16 +2257,14 @@ def hidden_variable(self, variable_name, value=True):
>>> from pyaedt import Hfss
>>> hfss = Hfss()
>>> hfss["my_hidden_leaf"] = "15mm"
- >>> hfss.hidden_variable("my_hidden_leaf", True)
-
+ >>> hfss.hidden_variable("my_hidden_leaf",True)
"""
-
- if not isinstance(variable_name, list):
- self.variable_manager[variable_name].hidden = value
+ if not isinstance(name, list):
+ self.variable_manager[name].hidden = value
else:
design_variables = ["NAME:ChangedProps"]
project_variables = ["NAME:ChangedProps"]
- for name in variable_name:
+ for name in name:
if name in self.variable_manager.design_variable_names:
design_variables.append(["NAME:" + name, "Hidden:=", value])
elif name in self.variable_manager.project_variable_names:
@@ -2202,13 +2284,13 @@ def hidden_variable(self, variable_name, value=True):
self.oproject.ChangeProperty(command)
return True
- @pyaedt_function_handler
- def read_only_variable(self, variable_name, value=True):
+ @pyaedt_function_handler(variable_name="name")
+ def read_only_variable(self, name, value=True):
"""Set the variable to a read-only or not read-only variable.
Parameters
----------
- variable_name : str
+ name : str
Name of the variable.
value : bool, optional
Whether the variable is read-only. The default is ``True``, in which case
@@ -2230,9 +2312,8 @@ def read_only_variable(self, variable_name, value=True):
>>> hfss = Hfss()
>>> hfss["my_read_only_variable"] = "15mm"
>>> hfss.make_read_only_variable("my_read_only_variable")
-
"""
- self.variable_manager[variable_name].read_only = value
+ self.variable_manager[name].read_only = value
return True
@pyaedt_function_handler()
@@ -2468,8 +2549,8 @@ def release_desktop(self, close_projects=True, close_desktop=True):
gc.collect()
return True
- @pyaedt_function_handler()
- def generate_temp_project_directory(self, subdir_name):
+ @pyaedt_function_handler(subdir_name="name")
+ def generate_temp_project_directory(self, name):
"""Generate a unique directory string to save a project to.
This method creates a directory for storage of a project in the ``temp`` directory
@@ -2479,7 +2560,7 @@ def generate_temp_project_directory(self, subdir_name):
Parameters
----------
- subdir_name : str
+ name : str
Base name of the subdirectory to create in the ``temp`` directory.
Returns
@@ -2495,10 +2576,10 @@ def generate_temp_project_directory(self, subdir_name):
"""
base_path = self.temp_directory
- if not isinstance(subdir_name, str):
+ if not isinstance(name, str):
self.logger.error("Input argument 'subdir' must be a string")
return False
- dir_name = generate_unique_name(subdir_name)
+ dir_name = generate_unique_name(name)
project_dir = os.path.join(base_path, dir_name)
try:
if not os.path.exists(project_dir):
@@ -2507,19 +2588,24 @@ def generate_temp_project_directory(self, subdir_name):
except OSError:
return False
- @pyaedt_function_handler()
- def load_project(self, project_file, design_name=None, close_active_proj=False, save_active_project=False):
+ @pyaedt_function_handler(
+ project_file="file_name",
+ design_name="design",
+ close_active_proj="close_active",
+ save_active_project="set_active",
+ )
+ def load_project(self, file_name, design=None, close_active=False, set_active=False):
"""Open an AEDT project based on a project and optional design.
Parameters
----------
- project_file : str
- Full path and name for the project.
- design_name : str, optional
+ file_name : str
+ Full path of the project to load.
+ design : str, optional
Design name. The default is ``None``.
- close_active_proj : bool, optional
+ close_active : bool, optional
Whether to close the active project. The default is ``False``.
- save_active_project : bool, optional
+ set_active : bool, optional
Whether to save the active project. The default is ``False``.
Returns
@@ -2532,12 +2618,12 @@ def load_project(self, project_file, design_name=None, close_active_proj=False,
>>> oDesktop.OpenProject
"""
- proj = self.odesktop.OpenProject(project_file)
- if close_active_proj and self.oproject:
+ proj = self.odesktop.OpenProject(file_name)
+ if close_active and self.oproject:
self._close_edb()
- self.close_project(self.project_name, save_project=save_active_project)
+ self.close_project(self.project_name, save=set_active)
if proj:
- self._init_design(project_name=proj.GetName(), design_name=design_name)
+ self._init_design(project_name=proj.GetName(), design_name=design)
return True
else:
return False
@@ -2548,22 +2634,24 @@ def _close_edb(self):
if self.modeler and self.modeler._edb:
self.modeler._edb.close_edb()
- @pyaedt_function_handler()
- def create_dataset1d_design(self, dsname, xlist, ylist, xunit="", yunit=""):
+ @pyaedt_function_handler(dsname="name", xlist="x", ylist="y", xunit="x_unit", yunit="y_unit")
+ def create_dataset1d_design(self, name, x, y, x_unit="", y_unit="", sort=True):
"""Create a design dataset.
Parameters
----------
- dsname : str
+ name : str
Name of the dataset (without a prefix for a project dataset).
- xlist : list
+ x : list
List of X-axis values for the dataset.
- ylist : list
+ y : list
List of Y-axis values for the dataset.
- xunit : str, optional
+ x_unit : str, optional
Units for the X axis. The default is ``""``.
- yunit : str, optional
+ y_unit : str, optional
Units for the Y axis. The default is ``""``.
+ sort : bool, optional
+ Sort dataset. The default is ``True``.
Returns
-------
@@ -2575,24 +2663,26 @@ def create_dataset1d_design(self, dsname, xlist, ylist, xunit="", yunit=""):
>>> oProject.AddDataset
>>> oDesign.AddDataset
"""
- return self.create_dataset(dsname, xlist, ylist, is_project_dataset=False, xunit=xunit, yunit=yunit)
+ return self.create_dataset(name, x, y, is_project_dataset=False, x_unit=x_unit, y_unit=y_unit, sort=sort)
- @pyaedt_function_handler()
- def create_dataset1d_project(self, dsname, xlist, ylist, xunit="", yunit=""):
+ @pyaedt_function_handler(dsname="name", xlist="x", ylist="y", xunit="x_unit", yunit="y_unit")
+ def create_dataset1d_project(self, name, x, y, x_unit="", y_unit="", sort=True):
"""Create a project dataset.
Parameters
----------
- dsname : str
+ name : str
Name of dataset (without a prefix for a project dataset).
- xlist : list
+ x : list
List of X-axis values for the dataset.
- ylist : list
+ y : list
List of Y-axis values for the dataset.
- xunit : str, optional
+ x_unit : str, optional
Units for the X axis. The default is ``""``.
- yunit : str, optional
+ y_unit : str, optional
Units for the Y axis. The default is ``""``.
+ sort : bool, optional
+ Sort dataset. The default is ``True``.
Returns
-------
@@ -2605,46 +2695,48 @@ def create_dataset1d_project(self, dsname, xlist, ylist, xunit="", yunit=""):
>>> oProject.AddDataset
>>> oDesign.AddDataset
"""
- return self.create_dataset(dsname, xlist, ylist, is_project_dataset=True, xunit=xunit, yunit=yunit)
-
- @pyaedt_function_handler()
+ return self.create_dataset(name, x, y, is_project_dataset=True, x_unit=x_unit, y_unit=y_unit, sort=sort)
+
+ @pyaedt_function_handler(
+ dsname="name",
+ xlist="x",
+ ylist="y",
+ zlist="z",
+ vlist="v",
+ xunit="x_unit",
+ yunit="y_unit",
+ zunit="z_unit",
+ vunit="v_unit",
+ )
def create_dataset3d(
- self,
- dsname,
- xlist,
- ylist,
- zlist=None,
- vlist=None,
- xunit="",
- yunit="",
- zunit="",
- vunit="",
- is_project_dataset=True,
+ self, name, x, y, z=None, v=None, x_unit="", y_unit="", z_unit="", v_unit="", is_project_dataset=True, sort=True
):
"""Create a 3D dataset.
Parameters
----------
- dsname : str
+ name : str
Name of the dataset (without a prefix for a project dataset).
- xlist : list
+ x : list
List of X-axis values for the dataset.
- ylist : list
+ y : list
List of Y-axis values for the dataset.
- zylist : list, optional
+ z : list, optional
List of Z-axis values for a 3D dataset only. The default is ``None``.
- vylist : list, optional
+ v : list, optional
List of V-axis values for a 3D dataset only. The default is ``None``.
- xunit : str, optional
+ x_unit : str, optional
Units for the X axis. The default is ``""``.
- yunit : str, optional
+ y_unit : str, optional
Units for the Y axis. The default is ``""``.
- zunit : str, optional
+ z_unit : str, optional
Units for the Z axis for a 3D dataset only. The default is ``""``.
- vunit : str, optional
+ v_unit : str, optional
Units for the V axis for a 3D dataset only. The default is ``""``.
is_project_dataset : bool, optional
Whether it is a project data set. The default is ``True``.
+ sort : bool, optional
+ Sort dataset. The default is ``True``.
Returns
-------
@@ -2656,37 +2748,40 @@ def create_dataset3d(
>>> oDesign.AddDataset
"""
- if dsname[0] == "$":
- dsname = dsname[1:]
+ if name[0] == "$":
+ name = name[1:]
is_project_dataset = True
if self.design_type != "Maxwell 3D" and self.design_type != "Icepak":
is_project_dataset = True
return self.create_dataset(
- dsname=dsname,
- xlist=xlist,
- ylist=ylist,
- zlist=zlist,
- vlist=vlist,
- xunit=xunit,
- yunit=yunit,
- zunit=zunit,
- vunit=vunit,
+ name=name,
+ x=x,
+ y=y,
+ z=z,
+ v=v,
is_project_dataset=is_project_dataset,
+ x_unit=x_unit,
+ y_unit=y_unit,
+ z_unit=z_unit,
+ v_unit=v_unit,
+ sort=sort,
)
- @pyaedt_function_handler()
- def import_dataset1d(self, filename, dsname=None, is_project_dataset=True):
+ @pyaedt_function_handler(filename="input_file", dsname="name")
+ def import_dataset1d(self, input_file, name=None, is_project_dataset=True, sort=True):
"""Import a 1D dataset.
Parameters
----------
- filename : str
+ input_file : str
Full path and name for the TAB file.
- dsname : str, optional
+ name : str, optional
Name of the dataset. The default is the file name.
is_project_dataset : bool, optional
Whether it is a project data set. The default is ``True``.
+ sort : bool, optional
+ Sort dataset. The default is ``True``.
Returns
-------
@@ -2698,7 +2793,7 @@ def import_dataset1d(self, filename, dsname=None, is_project_dataset=True):
>>> oProject.AddDataset
>>> oDesign.AddDataset
"""
- with open_file(filename, "r") as f:
+ with open_file(input_file, "r") as f:
lines = f.read().splitlines()
header = lines[0]
points = lines[1:]
@@ -2718,31 +2813,33 @@ def import_dataset1d(self, filename, dsname=None, is_project_dataset=True):
xlist.append(float(item.split()[0]))
ylist.append(float(item.split()[1]))
- if not dsname:
- dsname = os.path.basename(os.path.splitext(filename)[0])
+ if not name:
+ name = os.path.basename(os.path.splitext(input_file)[0])
- if dsname[0] == "$":
- dsname = dsname[1:]
+ if name[0] == "$":
+ name = name[1:]
is_project_dataset = True
return self.create_dataset(
- dsname, xlist, ylist, is_project_dataset=is_project_dataset, xunit=units[0], yunit=units[1]
+ name, xlist, ylist, is_project_dataset=is_project_dataset, x_unit=units[0], y_unit=units[1], sort=sort
)
- @pyaedt_function_handler()
- def import_dataset3d(self, filename, dsname=None, encoding="utf-8-sig", is_project_dataset=True):
+ @pyaedt_function_handler(filename="input_file", dsname="name")
+ def import_dataset3d(self, input_file, name=None, encoding="utf-8-sig", is_project_dataset=True, sort=True):
"""Import a 3D dataset.
Parameters
----------
- filename : str
+ input_file : str
Full path and name for the tab/csv/xlsx file.
- dsname : str, optional
+ name : str, optional
Name of the dataset. The default is the file name.
encoding : str, optional
File encoding to be provided for csv.
is_project_dataset : bool, optional
Whether it is a project data set. The default is ``True``.
+ sort : bool, optional
+ Sort dataset. The default is ``True``.
Returns
-------
@@ -2753,8 +2850,8 @@ def import_dataset3d(self, filename, dsname=None, encoding="utf-8-sig", is_proje
>>> oProject.AddDataset
"""
- index_of_dot = filename.rfind(".")
- file_extension = filename[index_of_dot + 1 :]
+ index_of_dot = input_file.rfind(".")
+ file_extension = input_file[index_of_dot + 1 :]
xlist = []
ylist = []
zlist = []
@@ -2762,7 +2859,7 @@ def import_dataset3d(self, filename, dsname=None, encoding="utf-8-sig", is_proje
if file_extension == "xlsx":
self.logger.warning("You need pandas and openpyxl library installed for reading excel files")
- lines = read_xlsx(filename)
+ lines = read_xlsx(input_file)
if list(lines):
header = str([lines.columns[i] for i in range(len(lines.columns))])
xlist = list((lines.iloc[:, 0]).array)
@@ -2774,7 +2871,7 @@ def import_dataset3d(self, filename, dsname=None, encoding="utf-8-sig", is_proje
return False
elif file_extension == "csv":
- lines = read_csv(filename, encoding)
+ lines = read_csv(input_file, encoding)
header = " ".join(lines[0])
for row in lines[1:]:
xlist.append(float(row[0]))
@@ -2783,7 +2880,7 @@ def import_dataset3d(self, filename, dsname=None, encoding="utf-8-sig", is_proje
vlist.append(float(row[3]))
elif file_extension == "tab":
- lines = read_tab(filename)
+ lines = read_tab(input_file)
header = lines[0]
for item in lines[1:]:
xlist.append(float(item.split()[0]))
@@ -2800,66 +2897,69 @@ def import_dataset3d(self, filename, dsname=None, encoding="utf-8-sig", is_proje
units[cont] = result.group(1)
cont += 1
- if not dsname:
- dsname = os.path.basename(os.path.splitext(filename)[0])
+ if not name:
+ name = os.path.basename(os.path.splitext(input_file)[0])
- if dsname[0] == "$":
- dsname = dsname[1:]
+ if name[0] == "$":
+ name = name[1:]
is_project_dataset = True
if self.design_type != "Maxwell 3D" and self.design_type != "Icepak":
is_project_dataset = True
return self.create_dataset(
- dsname,
+ name,
xlist,
ylist,
zlist,
vlist,
is_project_dataset=is_project_dataset,
- xunit=units[0],
- yunit=units[1],
- zunit=units[2],
- vunit=units[3],
+ x_unit=units[0],
+ y_unit=units[1],
+ z_unit=units[2],
+ v_unit=units[3],
+ sort=sort,
)
- @pyaedt_function_handler()
+ @pyaedt_function_handler(
+ dsname="name",
+ xlist="x",
+ ylist="y",
+ zlist="z",
+ vlist="v",
+ xunit="x_unit",
+ yunit="y_unit",
+ zunit="z_unit",
+ vunit="v_unit",
+ )
def create_dataset(
- self,
- dsname,
- xlist,
- ylist,
- zlist=None,
- vlist=None,
- is_project_dataset=True,
- xunit="",
- yunit="",
- zunit="",
- vunit="",
+ self, name, x, y, z=None, v=None, is_project_dataset=True, x_unit="", y_unit="", z_unit="", v_unit="", sort=True
):
"""Create a dataset.
Parameters
----------
- dsname : str
+ name : str
Name of the dataset (without a prefix for a project dataset).
- xlist : list
+ x : list
List of X-axis values for the dataset.
- ylist : list
+ y : list
List of Y-axis values for the dataset.
- zlist : list, optional
+ z : list, optional
List of Z-axis values for a 3D dataset only. The default is ``None``.
- vlist : list, optional
+ v : list, optional
List of V-axis values for a 3D dataset only. The default is ``None``.
is_project_dataset : bool, optional
Whether it is a project data set. The default is ``True``.
- xunit : str, optional
+ x_unit : str, optional
Units for the X axis. The default is ``""``.
- yunit : str, optional
+ y_unit : str, optional
Units for the Y axis. The default is ``""``.
- zunit : str, optional
+ z_unit : str, optional
Units for the Z axis for a 3D dataset only. The default is ``""``.
- vunit : str, optional
+ v_unit : str, optional
Units for the V axis for a 3D dataset only. The default is ``""``.
+ sort : bool, optional
+ Sort dataset. The default is ``True``.
Returns
-------
@@ -2872,19 +2972,19 @@ def create_dataset(
>>> oProject.AddDataset
>>> oDesign.AddDataset
"""
- if not self.dataset_exists(dsname, is_project_dataset):
+ if not self.dataset_exists(name, is_project_dataset):
if is_project_dataset:
- dsname = "$" + dsname
- ds = DataSet(self, dsname, xlist, ylist, zlist, vlist, xunit, yunit, zunit, vunit)
+ name = "$" + name
+ ds = DataSet(self, name, x, y, z, v, x_unit, y_unit, z_unit, v_unit, sort)
else:
- self.logger.warning("Dataset %s already exists", dsname)
+ self.logger.warning("Dataset %s already exists", name)
return False
ds.create()
if is_project_dataset:
- self.project_datasets[dsname] = ds
+ self.project_datasets[name] = ds
else:
- self.design_datasets[dsname] = ds
- self.logger.info("Dataset %s created successfully.", dsname)
+ self.design_datasets[name] = ds
+ self.logger.info("Dataset %s created successfully.", name)
return ds
@pyaedt_function_handler()
@@ -3065,8 +3165,8 @@ def clean_proj_folder(self, directory=None, name=None):
self.logger.info("Project Directory cleaned")
return True
- @pyaedt_function_handler()
- def copy_project(self, path, dest):
+ @pyaedt_function_handler(path="destination", dest="name")
+ def copy_project(self, destination, name):
"""Copy the project to another destination.
.. note::
@@ -3074,9 +3174,9 @@ def copy_project(self, path, dest):
Parameters
----------
- path : str
+ destination : str
Path to save a copy of the project to.
- dest :
+ name :
Name to give the project in the new destination.
Returns
@@ -3091,16 +3191,16 @@ def copy_project(self, path, dest):
"""
self.logger.info("Copy AEDT Project ")
self.oproject.Save()
- self.oproject.SaveAs(os.path.join(path, dest + ".aedt"), True)
+ self.oproject.SaveAs(os.path.join(destination, name + ".aedt"), True)
return True
- @pyaedt_function_handler()
- def create_new_project(self, proj_name):
+ @pyaedt_function_handler(proj_name="name")
+ def create_new_project(self, name):
"""Create a project within AEDT.
Parameters
----------
- proj_name :
+ name :
Name of the project.
Returns
@@ -3114,14 +3214,14 @@ def create_new_project(self, proj_name):
>>> oDesktop.NewProject
"""
self.logger.info("Creating new Project ")
- prj = self.odesktop.NewProject(proj_name)
+ prj = self.odesktop.NewProject(name)
prj_name = prj.GetName()
self.oproject = prj_name
self.odesign = None
return True
- @pyaedt_function_handler()
- def close_project(self, name=None, save_project=True):
+ @pyaedt_function_handler(save_project="save")
+ def close_project(self, name=None, save=True):
"""Close an AEDT project.
Parameters
@@ -3129,7 +3229,7 @@ def close_project(self, name=None, save_project=True):
name : str, optional
Name of the project. The default is ``None``, in which case the
active project is closed.
- save_project : bool, optional
+ save : bool, optional
Whether to save the project before closing it. The default is
``True``.
@@ -3155,7 +3255,7 @@ def close_project(self, name=None, save_project=True):
oproj = self.desktop_class.active_project(name)
proj_path = oproj.GetPath()
proj_file = os.path.join(proj_path, name + ".aedt")
- if save_project:
+ if save:
oproj.Save()
if name == legacy_name:
self._global_logger.remove_file_logger(name)
@@ -3231,13 +3331,13 @@ def delete_design(self, name=None, fallback_design=None):
self._odesign = None
return True
- @pyaedt_function_handler()
- def delete_separator(self, separator_name):
+ @pyaedt_function_handler(separator_name="name")
+ def delete_separator(self, name):
"""Delete a separator from either the active project or a design.
Parameters
----------
- separator_name : str
+ name : str
Name of the separator.
Returns
@@ -3251,15 +3351,15 @@ def delete_separator(self, separator_name):
>>> oProject.ChangeProperty
>>> oDesign.ChangeProperty
"""
- return self._variable_manager.delete_separator(separator_name)
+ return self._variable_manager.delete_separator(name)
- @pyaedt_function_handler()
- def delete_variable(self, sVarName):
+ @pyaedt_function_handler(sVarName="name")
+ def delete_variable(self, name):
"""Delete a variable.
Parameters
----------
- sVarName :
+ name :
Name of the variable.
References
@@ -3268,7 +3368,7 @@ def delete_variable(self, sVarName):
>>> oProject.ChangeProperty
>>> oDesign.ChangeProperty
"""
- return self.variable_manager.delete_variable(sVarName)
+ return self.variable_manager.delete_variable(name)
@pyaedt_function_handler()
def delete_unused_variables(self):
@@ -3281,15 +3381,15 @@ def delete_unused_variables(self):
"""
return self.variable_manager.delete_unused_variables()
- @pyaedt_function_handler()
- def insert_design(self, design_name=None, solution_type=None):
+ @pyaedt_function_handler(design_name="name")
+ def insert_design(self, name=None, solution_type=None):
"""Add a design of a specified type.
The default design type is taken from the derived application class.
Parameters
----------
- design_name : str, optional
+ name : str, optional
Name of the design. The default is ``None``, in which case the
default design name is ``Design<_index>``. If the
given or default design name is in use, then an underscore and
@@ -3312,7 +3412,7 @@ def insert_design(self, design_name=None, solution_type=None):
self._close_edb()
self._init_design(
project_name=self.project_name if self.project_name else generate_unique_name("Project"),
- design_name=design_name,
+ design_name=name,
solution_type=solution_type if solution_type else self.solution_type,
)
@@ -3400,15 +3500,15 @@ def _generate_unique_project_name(self):
proj_name = "Project_" + uName + ".aedt"
return proj_name
- @pyaedt_function_handler()
- def rename_design(self, new_name, save_after_duplicate=True):
+ @pyaedt_function_handler(new_name="name", save_after_duplicate="save")
+ def rename_design(self, name, save=True):
"""Rename the active design.
Parameters
----------
- new_name : str
+ name : str
New name of the design.
- save_after_duplicate : bool, optional
+ save : bool, optional
Save project after the duplication is completed. If ``False``, pyaedt objects like boundaries will not be
available.
@@ -3422,22 +3522,22 @@ def rename_design(self, new_name, save_after_duplicate=True):
>>> oDesign.RenameDesignInstance
"""
- self._odesign.RenameDesignInstance(self.design_name, new_name)
- if save_after_duplicate:
+ self._odesign.RenameDesignInstance(self.design_name, name)
+ if save:
self.oproject.Save()
self._project_dictionary = None
return True
- @pyaedt_function_handler()
- def copy_design_from(self, project_fullname, design_name, save_project=True, set_active_design=True):
+ @pyaedt_function_handler(project_fullname="project", design_name="design")
+ def copy_design_from(self, project, design, save_project=True, set_active_design=True):
"""Copy a design from a project into the active project.
Parameters
----------
- project_fullname : str
+ project : str
Full path and name for the project containing the design to copy.
The active design is maintained.
- design_name : str
+ design : str
Name of the design to copy into the active design. If a design with this
name is already present in the destination project, AEDT automatically
changes the name.
@@ -3462,16 +3562,16 @@ def copy_design_from(self, project_fullname, design_name, save_project=True, set
self.save_project()
active_design = self.design_name
# open the origin project
- if os.path.exists(project_fullname):
- proj_from = self.odesktop.OpenProject(project_fullname)
+ if os.path.exists(project):
+ proj_from = self.odesktop.OpenProject(project)
proj_from_name = proj_from.GetName()
else:
return None
# check if the requested design exists in the origin project
- if design_name not in [x for i in list(proj_from.GetDesigns()) for x in (i.GetName(), i.GetName()[2:])]:
+ if design not in [x for i in list(proj_from.GetDesigns()) for x in (i.GetName(), i.GetName()[2:])]:
return None
# copy the source design
- proj_from.CopyDesign(design_name)
+ proj_from.CopyDesign(design)
# paste in the destination project and get the name
self._oproject.Paste()
new_designname = self.desktop_class.active_design(self._oproject, design_type=self.design_type).GetName()
@@ -3491,8 +3591,8 @@ def copy_design_from(self, project_fullname, design_name, save_project=True, set
# return the pasted design name
return new_designname
- @pyaedt_function_handler()
- def duplicate_design(self, label, save_after_duplicate=True):
+ @pyaedt_function_handler(label="name")
+ def duplicate_design(self, name, save_after_duplicate=True):
"""Copy a design to a new name.
The new name consists of the original
@@ -3501,7 +3601,7 @@ def duplicate_design(self, label, save_after_duplicate=True):
Parameters
----------
- label : str
+ name : str
Name of the design to copy.
save_after_duplicate : bool, optional
Save project after the duplication is completed. If ``False``, pyaedt objects like boundaries will not be
@@ -3518,15 +3618,14 @@ def duplicate_design(self, label, save_after_duplicate=True):
>>> oProject.CopyDesign
>>> oProject.Paste
"""
-
active_design = self.design_name
design_list = self.design_list
self._oproject.CopyDesign(active_design)
self._oproject.Paste()
- newname = label
+ newname = name
ind = 1
while newname in self.design_list:
- newname = label + "_" + str(ind)
+ newname = name + "_" + str(ind)
ind += 1
actual_name = [i for i in self.design_list if i not in design_list]
self.odesign = actual_name[0]
@@ -3538,13 +3637,13 @@ def duplicate_design(self, label, save_after_duplicate=True):
self._project_dictionary = None
return True
- @pyaedt_function_handler()
- def export_design_preview_to_jpg(self, filename):
+ @pyaedt_function_handler(filename="output_file")
+ def export_design_preview_to_jpg(self, output_file):
"""Export design preview image to a JPG file.
Parameters
----------
- filename : str
+ output_file : str
Full path and name for the JPG file.
Returns
@@ -3558,7 +3657,7 @@ def export_design_preview_to_jpg(self, filename):
# is self.design_name guaranteed to be there?
design_info = [design for design in design_info if design["DesignName"] == self.design_name][0]
image_data_str = design_info["Image64"]
- with open_file(filename, "wb") as f:
+ with open_file(output_file, "wb") as f:
if sys.version_info.major == 2:
bytestring = bytes(image_data_str).decode("base64")
else:
@@ -3566,17 +3665,19 @@ def export_design_preview_to_jpg(self, filename):
f.write(bytestring)
return True
- @pyaedt_function_handler()
- def export_variables_to_csv(self, filename, export_project=True, export_design=True):
+ @pyaedt_function_handler(
+ filename="output_file", export_project="export_project_variables", export_design="export_design_properties"
+ )
+ def export_variables_to_csv(self, output_file, export_project_variables=True, export_design_properties=True):
"""Export design properties, project variables, or both to a CSV file.
Parameters
----------
- filename : str
+ output_file : str
Full path and name for the CSV file.
- export_project : bool, optional
+ export_project_variables : bool, optional
Whether to export project variables. The default is ``True``.
- export_design : bool, optional
+ export_design_properties : bool, optional
Whether to export design properties. The default is ``True``.
@@ -3595,9 +3696,9 @@ def export_variables_to_csv(self, filename, export_project=True, export_design=T
"""
varnames = []
desnames = []
- if export_project:
+ if export_project_variables:
varnames = self.oproject.GetProperties("ProjectVariableTab", "ProjectVariables")
- if export_design:
+ if export_design_properties:
desnames = self.odesign.GetProperties("LocalVariableTab", "LocalVariables")
if self.design_type in ["HFSS 3D Layout Design", "Circuit Design"]:
desnames.extend(self.odesign.GetProperties("DefinitionParameterTab", "LocalVariables"))
@@ -3608,7 +3709,7 @@ def export_variables_to_csv(self, filename, export_project=True, export_design=T
for el in desnames:
value = self.odesign.GetVariableValue(el)
list_full.append([el, value])
- return write_csv(filename, list_full)
+ return write_csv(output_file, list_full)
@pyaedt_function_handler()
def read_design_data(self):
@@ -3625,17 +3726,17 @@ def read_design_data(self):
design_data = json.load(fps)
return design_data
- @pyaedt_function_handler()
- def save_project(self, project_file=None, overwrite=True, refresh_obj_ids_after_save=False):
+ @pyaedt_function_handler(project_file="file_name", refresh_obj_ids_after_save="refresh_ids")
+ def save_project(self, file_name=None, overwrite=True, refresh_ids=False):
"""Save the project and add a message.
Parameters
----------
- project_file : str, optional
+ file_name : str, optional
Full path and project name. The default is ````None``.
overwrite : bool, optional
Whether to overwrite the existing project. The default is ``True``.
- refresh_obj_ids_after_save : bool, optional
+ refresh_ids : bool, optional
Whether to refresh object IDs after saving the project.
The default is ``False``.
@@ -3650,14 +3751,14 @@ def save_project(self, project_file=None, overwrite=True, refresh_obj_ids_after_
>>> oProject.Save
>>> oProject.SaveAs
"""
- if project_file and not os.path.exists(os.path.dirname(project_file)):
- os.makedirs(os.path.dirname(project_file))
- elif project_file:
- self.oproject.SaveAs(project_file, overwrite)
+ if file_name and not os.path.exists(os.path.dirname(file_name)):
+ os.makedirs(os.path.dirname(file_name))
+ elif file_name:
+ self.oproject.SaveAs(file_name, overwrite)
self._add_handler()
else:
self.oproject.Save()
- if refresh_obj_ids_after_save:
+ if refresh_ids:
self.modeler.refresh_all_ids()
self.modeler._refresh_all_ids_from_aedt_file()
self.mesh._refresh_mesh_operations()
@@ -3665,27 +3766,28 @@ def save_project(self, project_file=None, overwrite=True, refresh_obj_ids_after_
self.logger.info(msg_text)
return True
- @pyaedt_function_handler()
+ @pyaedt_function_handler(project_file="project_path", additional_file_lists="additional_files")
def archive_project(
self,
- project_file=None,
+ project_path=None,
include_external_files=True,
include_results_file=True,
- additional_file_lists=[],
+ additional_files=None,
notes="",
):
"""Archive the AEDT project and add a message.
Parameters
----------
- project_file : str, optional
+ project_path : str, optional
Full path and project name. The default is ``None``.
include_external_files : bool, optional
Whether to include external files in the archive. The default is ``True``.
include_results_file : bool, optional
Whether to include simulation results files in the archive. The default is ``True``.
- additional_file_lists : list, optional
- List of additional files to add to the archive. The default is ``[]``.
+ additional_files : list, optional
+ List of additional files to add to the archive.
+ The default is ``None`` in which case an empty list is set.
notes : str, optional
Simulation notes to add to the archive. The default is ``""``.
@@ -3700,24 +3802,24 @@ def archive_project(
>>> oProject.Save
>>> oProject.SaveProjectArchive
"""
+ additional_files = [] if additional_files is None else additional_files
msg_text = "Saving {0} Project".format(self.project_name)
self.logger.info(msg_text)
- if not project_file:
- project_file = os.path.join(self.project_path, self.project_name + ".aedtz")
+ if not project_path:
+ project_path = os.path.join(self.project_path, self.project_name + ".aedtz")
self.oproject.Save()
self.oproject.SaveProjectArchive(
- project_file, include_external_files, include_results_file, additional_file_lists, notes
+ project_path, include_external_files, include_results_file, additional_files, notes
)
-
return True
- @pyaedt_function_handler()
- def delete_project(self, project_name):
+ @pyaedt_function_handler(project_name="name")
+ def delete_project(self, name):
"""Delete a project.
Parameters
----------
- project_name : str
+ name : str
Name of the project.
Returns
@@ -3730,9 +3832,9 @@ def delete_project(self, project_name):
>>> oDesktop.DeleteProject
"""
- if self.project_name == project_name:
+ if self.project_name == name:
raise ValueError("You cannot delete the active project.")
- self.odesktop.DeleteProject(project_name)
+ self.odesktop.DeleteProject(name)
return True
@pyaedt_function_handler()
@@ -3753,13 +3855,13 @@ def set_active_design(self, name):
self._init_design(project_name=self.project_name, design_name=name)
return True
- @pyaedt_function_handler()
- def validate_simple(self, logfile=None):
+ @pyaedt_function_handler(logfile="log_file")
+ def validate_simple(self, log_file=None):
"""Validate a design.
Parameters
----------
- logfile : str, optional
+ log_file : str, optional
Name of the log file to save validation information to.
The default is ``None``.
@@ -3773,18 +3875,18 @@ def validate_simple(self, logfile=None):
>>> oDesign.ValidateDesign
"""
- if logfile:
- return self._odesign.ValidateDesign(logfile)
+ if log_file:
+ return self._odesign.ValidateDesign(log_file)
else:
return self._odesign.ValidateDesign()
- @pyaedt_function_handler()
- def get_evaluated_value(self, variable_name, units=None):
+ @pyaedt_function_handler(variable_name="name")
+ def get_evaluated_value(self, name, units=None):
"""Retrieve the evaluated value of a design property or project variable in SI units if no unit is provided.
Parameters
----------
- variable_name : str
+ name : str
Name of the design property or project variable.
units : str, optional
Name of the unit to use for rescaling. The default is ``None``,
@@ -3812,27 +3914,27 @@ def get_evaluated_value(self, variable_name, units=None):
"""
val = None
var_obj = None
- if "$" in variable_name:
+ if "$" in name:
app = self._oproject
- var_obj = self.get_oo_object(app, "Variables/{}".format(variable_name))
+ var_obj = self.get_oo_object(app, "Variables/{}".format(name))
else:
app = self._odesign
if self.design_type in ["Circuit Design", "Twin Builder", "HFSS 3D Layout Design"]:
- if variable_name in self.get_oo_name(app, "Instance:{}".format(self._odesign.GetName())):
- var_obj = self.get_oo_object(app, "Instance:{}/{}".format(self._odesign.GetName(), variable_name))
- elif variable_name in self.get_oo_object(app, "DefinitionParameters").GetPropNames():
- val = self.get_oo_object(app, "DefinitionParameters").GetPropEvaluatedValue(variable_name)
+ if name in self.get_oo_name(app, "Instance:{}".format(self._odesign.GetName())):
+ var_obj = self.get_oo_object(app, "Instance:{}/{}".format(self._odesign.GetName(), name))
+ elif name in self.get_oo_object(app, "DefinitionParameters").GetPropNames():
+ val = self.get_oo_object(app, "DefinitionParameters").GetPropEvaluatedValue(name)
else:
- var_obj = self.get_oo_object(app, "Variables/{}".format(variable_name))
+ var_obj = self.get_oo_object(app, "Variables/{}".format(name))
if var_obj:
val = var_obj.GetPropValue("SIValue")
elif not val:
try:
variation_string = self._odesign.GetNominalVariation()
- val = self._odesign.GetVariationVariableValue(variation_string, variable_name) # pragma: no cover
+ val = self._odesign.GetVariationVariableValue(variation_string, name) # pragma: no cover
except Exception:
- val_units = app.GetVariableValue(variable_name)
+ val_units = app.GetVariableValue(name)
val, original_units = decompose_variable_value(val_units)
try:
if original_units:
@@ -3854,13 +3956,13 @@ def get_evaluated_value(self, variable_name, units=None):
except (ValueError, KeyError, TypeError, AttributeError): # pragma: no cover
return val
- @pyaedt_function_handler()
- def evaluate_expression(self, expression_string):
+ @pyaedt_function_handler(expression_string="expression")
+ def evaluate_expression(self, expression):
"""Evaluate a valid string expression and return the numerical value in SI units.
Parameters
----------
- expression_string : str
+ expression : str
A valid string expression for a design property or project variable.
For example, ``"34mm*sqrt(2)"`` or ``"$G1*p2/34"``.
@@ -3871,40 +3973,36 @@ def evaluate_expression(self, expression_string):
"""
# Set the value of an internal reserved design variable to the specified string
- if expression_string in self._variable_manager.variables:
- return self._variable_manager.variables[expression_string].value
- elif "pwl" in str(expression_string):
+ if expression in self._variable_manager.variables:
+ return self._variable_manager.variables[expression].value
+ elif "pwl" in str(expression):
for ds in self.project_datasets:
- if ds in expression_string:
- return expression_string
+ if ds in expression:
+ return expression
for ds in self.design_datasets:
- if ds in expression_string:
- return expression_string
+ if ds in expression:
+ return expression
try:
- return float(expression_string)
+ return float(expression)
except ValueError:
pass
try:
variable_name = "pyaedt_evaluator"
- if "$" in expression_string:
+ if "$" in expression:
variable_name = "$pyaedt_evaluator"
self._variable_manager.set_variable(
- variable_name,
- expression=expression_string,
- readonly=True,
- hidden=True,
- description="Internal_Evaluator",
+ variable_name, expression=expression, read_only=True, hidden=True, description="Internal_Evaluator"
)
eval_value = self._variable_manager.variables[variable_name].value
# Extract the numeric value of the expression (in SI units!)
self._variable_manager.delete_variable(variable_name)
return eval_value
except Exception:
- self.logger.warning("Invalid string expression {}".format(expression_string))
- return expression_string
+ self.logger.warning("Invalid string expression {}".format(expression))
+ return expression
- @pyaedt_function_handler()
- def design_variation(self, variation_string=None):
+ @pyaedt_function_handler(variation_string="variation")
+ def design_variation(self, variation=None):
"""Generate a string to specify a desired variation.
This method converts an input string defining a desired solution variation into a valid
@@ -3918,7 +4016,7 @@ def design_variation(self, variation_string=None):
Parameters
----------
- variation_string : str, optional
+ variation : str, optional
Variation string. For example, ``"p1=1mm"`` or ``"p2=3mm"``.
Returns
@@ -3932,12 +4030,12 @@ def design_variation(self, variation_string=None):
>>> oDesign.GetNominalVariation
"""
nominal = self._odesign.GetNominalVariation()
- if variation_string:
+ if variation:
# decompose the nominal variation into a dictionary of name[value]
nominal_dict = variation_string_to_dict(nominal)
# decompose the desired variation into a dictionary of name[value]
- var_dict = variation_string_to_dict(variation_string)
+ var_dict = variation_string_to_dict(variation)
# set the values of the desired variation in the active design
for key, value in var_dict.items():
@@ -3992,45 +4090,55 @@ def _check_design_consistency(self):
consistent = self._check_solution_consistency()
return consistent
- @pyaedt_function_handler()
- def add_from_toolkit(self, toolkit_object, draw=False, **kwargs):
+ @pyaedt_function_handler(toolkit_object="toolkit")
+ def add_from_toolkit(self, toolkit, draw=False, **kwargs):
"""Add a new toolkit to the current application.
Parameters
----------
- toolkit_object :
+ toolkit :
Application object from ``"ansys.aedt.toolkits"``.
Returns
-------
-
- Application-created object."""
- app = toolkit_object(self, **kwargs)
+ Application-created object.
+ """
+ app = toolkit(self, **kwargs)
if draw:
app.init_model()
app.model_hfss()
app.setup_hfss()
return app
- @pyaedt_function_handler()
- def check_if_project_is_loaded(self, project_path):
+ @pyaedt_function_handler(project_path="input_file")
+ def check_if_project_is_loaded(self, input_file):
"""Check if a project path is already loaded in active Desktop.
+ Parameters
+ ----------
+ input_file : str
+ Project path to check in active desktop.
+
Returns
-------
str
Project name if loaded in Desktop.
"""
for p in self.odesktop.GetProjects():
- if os.path.normpath(os.path.join(p.GetPath(), p.GetName()) + ".aedt") == os.path.normpath(project_path):
+ if os.path.normpath(os.path.join(p.GetPath(), p.GetName()) + ".aedt") == os.path.normpath(input_file):
return p.GetName()
return False
- @pyaedt_function_handler
- def set_temporary_directory(self, temp_dir_path):
+ @pyaedt_function_handler(temp_dir_path="path")
+ def set_temporary_directory(self, path):
"""Set temporary directory path.
+ Parameters
+ ----------
+ path : str
+ Temporary directory path.
+
Returns
-------
bool
@@ -4041,7 +4149,7 @@ def set_temporary_directory(self, temp_dir_path):
>>> oDesktop.SetTempDirectory()
"""
- self.odesktop.SetTempDirectory(temp_dir_path)
+ self.odesktop.SetTempDirectory(path)
return True
diff --git a/pyaedt/application/JobManager.py b/pyaedt/application/JobManager.py
index 1277424e1f5..67f2777b570 100644
--- a/pyaedt/application/JobManager.py
+++ b/pyaedt/application/JobManager.py
@@ -1,3 +1,28 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+
def get_hpc_info(filename):
"""Retrieve HPC information.
diff --git a/pyaedt/application/Variables.py b/pyaedt/application/Variables.py
index ec3e31e5432..cf147a0570c 100644
--- a/pyaedt/application/Variables.py
+++ b/pyaedt/application/Variables.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
"""
This module contains these classes: `CSVDataset`, `DataSet`, `Expression`, `Variable`, and `VariableManager`.
@@ -22,7 +46,6 @@
import types
import warnings
-from pyaedt import pyaedt_function_handler
from pyaedt.generic.constants import AEDT_UNITS
from pyaedt.generic.constants import SI_UNITS
from pyaedt.generic.constants import _resolve_unit_system
@@ -32,6 +55,7 @@
from pyaedt.generic.general_methods import is_array
from pyaedt.generic.general_methods import is_number
from pyaedt.generic.general_methods import open_file
+from pyaedt.generic.general_methods import pyaedt_function_handler
class CSVDataset:
@@ -458,13 +482,13 @@ def variables(self):
"""
return self._variable_dict([self._odesign, self._oproject])
- @pyaedt_function_handler()
- def decompose(self, variable_value):
+ @pyaedt_function_handler(variable_value="variable")
+ def decompose(self, variable):
"""Decompose a variable string to a floating with its unit.
Parameters
----------
- variable_value : str
+ variable : str
Returns
-------
@@ -483,12 +507,12 @@ def decompose(self, variable_value):
>>> print(hfss.variable_manager.decompose("v2"))
>>> (6.0, 'N')
"""
- if variable_value in self.independent_variable_names:
- val, unit = decompose_variable_value(self[variable_value].expression)
- elif variable_value in self.dependent_variable_names:
- val, unit = decompose_variable_value(self[variable_value].evaluated_value)
+ if variable in self.independent_variable_names:
+ val, unit = decompose_variable_value(self[variable].expression)
+ elif variable in self.dependent_variable_names:
+ val, unit = decompose_variable_value(self[variable].evaluated_value)
else:
- val, unit = decompose_variable_value(variable_value)
+ val, unit = decompose_variable_value(variable)
return val, unit
@property
@@ -893,10 +917,15 @@ def _variable_dict(self, object_list, dependent=True, independent=True):
vars_to_output[k] = v
return vars_to_output
- @pyaedt_function_handler()
- def get_expression(self, variable_name): # TODO: Should be renamed to "evaluate"
+ @pyaedt_function_handler(variable_name="name")
+ def get_expression(self, name): # TODO: Should be renamed to "evaluate"
"""Retrieve the variable value of a project or design variable as a string.
+ Parameters
+ ----------
+ name : str
+ Name of the expression.
+
References
----------
@@ -904,53 +933,53 @@ def get_expression(self, variable_name): # TODO: Should be renamed to "evaluate
>>> oDesign.GetVariableValue
"""
invalid_names = ["CosimDefinition", "CoSimulator", "CoSimulator/Choices", "InstanceName", "ModelName"]
- if variable_name not in invalid_names:
+ if name not in invalid_names:
try:
- return self.aedt_object(variable_name).GetVariableValue(variable_name)
+ return self.aedt_object(name).GetVariableValue(name)
except Exception:
return False
else:
return False
- @pyaedt_function_handler()
- def aedt_object(self, variable):
+ @pyaedt_function_handler(variable="name")
+ def aedt_object(self, name):
"""Retrieve an AEDT object.
Parameters
----------
- variable : str
- Name of the variable.
+ name : str
+ Name of the variable.
"""
- if variable[0] == "$":
+ if name[0] == "$":
return self._oproject
else:
return self._odesign
- @pyaedt_function_handler()
+ @pyaedt_function_handler(variable_name="name", readonly="read_only", postprocessing="is_post_processing")
def set_variable(
self,
- variable_name,
+ name,
expression=None,
- readonly=False,
+ read_only=False,
hidden=False,
description=None,
overwrite=True,
- postprocessing=False,
+ is_post_processing=False,
circuit_parameter=True,
):
"""Set the value of a design property or project variable.
Parameters
----------
- variable_name : str
+ name : str
Name of the design property or project variable
(``$var``). If this variable does not exist, a new one is
created and a value is set.
expression : str
Valid string expression within the AEDT design and project
structure. For example, ``"3*cos(34deg)"``.
- readonly : bool, optional
+ read_only : bool, optional
Whether to set the design property or project variable to
read-only. The default is ``False``.
hidden : bool, optional
@@ -963,7 +992,7 @@ def set_variable(
Whether to overwrite an existing value for the design
property or project variable. The default is ``False``, in
which case this method is ignored.
- postprocessing : bool, optional
+ is_post_processing : bool, optional
Whether to define a postprocessing variable.
The default is ``False``, in which case the variable is not used in postprocessing.
circuit_parameter : bool, optional
@@ -982,21 +1011,27 @@ def set_variable(
Examples
--------
+ >>> from pyaedt import Maxwell3d
+ >>> aedtapp = Maxwell3d(specified_version="2024.1")
+
Set the value of design property ``p1`` to ``"10mm"``,
creating the property if it does not already eixst.
- >>> aedtapp.variable_manager.set_variable("p1", expression="10mm")
+ >>> aedtapp.variable_manager.set_variable("p1",expression="10mm")
Set the value of design property ``p1`` to ``"20mm"`` only if
the property does not already exist.
- >>> aedtapp.variable_manager.set_variable("p1", expression="20mm", overwrite=False)
+ >>> aedtapp.variable_manager.set_variable("p1",expression="20mm",overwrite=False)
Set the value of design property ``p2`` to ``"10mm"``,
creating the property if it does not already exist. Also make
it read-only and hidden and add a description.
- >>> aedtapp.variable_manager.set_variable(variable_name="p2", expression="10mm", readonly=True, hidden=True,
+ >>> aedtapp.variable_manager.set_variable(name="p2",
+ ... expression="10mm",
+ ... read_only=True,
+ ... hidden=True,
... description="This is the description of this variable.")
Set the value of the project variable ``$p1`` to ``"30mm"``,
@@ -1005,23 +1040,23 @@ def set_variable(
>>> aedtapp.variable_manager.set_variable["$p1"] == "30mm"
"""
- if variable_name in self._independent_variables:
- del self._independent_variables[variable_name]
- if variable_name in self._independent_design_variables:
- del self._independent_design_variables[variable_name]
- elif variable_name in self._independent_project_variables:
- del self._independent_project_variables[variable_name]
- elif variable_name in self._dependent_variables:
- del self._dependent_variables[variable_name]
- if variable_name in self._dependent_design_variables:
- del self._dependent_design_variables[variable_name]
- elif variable_name in self._dependent_project_variables:
- del self._dependent_project_variables[variable_name]
+ if name in self._independent_variables:
+ del self._independent_variables[name]
+ if name in self._independent_design_variables:
+ del self._independent_design_variables[name]
+ elif name in self._independent_project_variables:
+ del self._independent_project_variables[name]
+ elif name in self._dependent_variables:
+ del self._dependent_variables[name]
+ if name in self._dependent_design_variables:
+ del self._dependent_design_variables[name]
+ elif name in self._dependent_project_variables:
+ del self._dependent_project_variables[name]
if not description:
description = ""
- desktop_object = self.aedt_object(variable_name)
- if variable_name.startswith("$"):
+ desktop_object = self.aedt_object(name)
+ if name.startswith("$"):
tab_name = "ProjectVariableTab"
prop_server = "ProjectVariables"
else:
@@ -1038,7 +1073,7 @@ def set_variable(
prop_server = "Instance:{}".format(desktop_object.GetName())
prop_type = "VariableProp"
- if postprocessing or "post" in variable_name.lower()[0:5]:
+ if is_post_processing or "post" in name.lower()[0:5]:
prop_type = "PostProcessingVariableProp"
if isinstance(expression, str):
# Handle string type variable (including arbitrary expression)# Handle input type variable
@@ -1056,12 +1091,12 @@ def set_variable(
prop_type = "SeparatorProp"
variable = ""
try:
- if self.delete_separator(variable_name):
+ if self.delete_separator(name):
desktop_object.Undo()
self._logger.clear_messages()
return
except Exception:
- self._logger.debug("Something went wrong when deleting '{}'.".format(variable_name))
+ self._logger.debug("Something went wrong when deleting '{}'.".format(name))
else:
raise Exception("Unhandled input type to the design property or project variable.") # pragma: no cover
@@ -1069,7 +1104,7 @@ def set_variable(
var_list = self._get_var_list_from_aedt(desktop_object)
lower_case_vars = [var_name.lower() for var_name in var_list]
- if variable_name.lower() not in lower_case_vars:
+ if name.lower() not in lower_case_vars:
try:
desktop_object.ChangeProperty(
[
@@ -1080,7 +1115,7 @@ def set_variable(
[
"NAME:NewProps",
[
- "NAME:" + variable_name,
+ "NAME:" + name,
"PropType:=",
prop_type,
"UserDef:=",
@@ -1090,7 +1125,7 @@ def set_variable(
"Description:=",
description,
"ReadOnly:=",
- readonly,
+ read_only,
"Hidden:=",
hidden,
],
@@ -1110,13 +1145,13 @@ def set_variable(
[
"NAME:ChangedProps",
[
- "NAME:" + variable_name,
+ "NAME:" + name,
"Value:=",
variable,
"Description:=",
description,
"ReadOnly:=",
- readonly,
+ read_only,
"Hidden:=",
hidden,
],
@@ -1134,13 +1169,13 @@ def set_variable(
[
"NAME:ChangedProps",
[
- "NAME:" + variable_name,
+ "NAME:" + name,
"Value:=",
variable,
"Description:=",
description,
"ReadOnly:=",
- readonly,
+ read_only,
"Hidden:=",
hidden,
],
@@ -1151,17 +1186,17 @@ def set_variable(
self._cleanup_variables()
var_list = self._get_var_list_from_aedt(desktop_object)
lower_case_vars = [var_name.lower() for var_name in var_list]
- if variable_name.lower() not in lower_case_vars:
+ if name.lower() not in lower_case_vars:
return False
return True
- @pyaedt_function_handler()
- def delete_separator(self, separator_name):
+ @pyaedt_function_handler(separator_name="name")
+ def delete_separator(self, name):
"""Delete a separator from either the active project or design.
Parameters
----------
- separator_name : str
+ name : str
Value to use for the delimiter.
Returns
@@ -1187,7 +1222,7 @@ def delete_separator(self, separator_name):
[
"NAME:{0}VariableTab".format(var_type),
["NAME:PropServers", "{0}Variables".format(var_type)],
- ["NAME:DeletedProps", separator_name],
+ ["NAME:DeletedProps", name],
],
]
)
@@ -1196,16 +1231,15 @@ def delete_separator(self, separator_name):
self._logger.debug("Failed to change desktop object property.")
return False
- @pyaedt_function_handler()
- def delete_variable(self, var_name):
+ @pyaedt_function_handler(var_name="name")
+ def delete_variable(self, name):
"""Delete a variable.
Parameters
----------
- var_name : str
+ name : str
Name of the variable.
-
Returns
-------
bool
@@ -1217,11 +1251,11 @@ def delete_variable(self, var_name):
>>> oProject.ChangeProperty
>>> oDesign.ChangeProperty
"""
- desktop_object = self.aedt_object(var_name)
+ desktop_object = self.aedt_object(name)
var_type = "Project" if desktop_object == self._oproject else "Local"
var_list = self._get_var_list_from_aedt(desktop_object)
lower_case_vars = [var_name.lower() for var_name in var_list]
- if var_name.lower() in lower_case_vars:
+ if name.lower() in lower_case_vars:
try:
desktop_object.ChangeProperty(
[
@@ -1229,7 +1263,7 @@ def delete_variable(self, var_name):
[
"NAME:{0}VariableTab".format(var_type),
["NAME:PropServers", "{0}Variables".format(var_type)],
- ["NAME:DeletedProps", var_name],
+ ["NAME:DeletedProps", name],
],
]
)
@@ -1240,40 +1274,39 @@ def delete_variable(self, var_name):
return True
return False
- @pyaedt_function_handler()
- def is_used(self, var_name):
+ @pyaedt_function_handler(var_name="name")
+ def is_used(self, name):
"""Find if a variable is used.
Parameters
----------
- var_name : str
+ name : str
Name of the variable.
Returns
-------
bool
``True`` when successful, ``False`` when failed.
-
"""
used = False
# Modeler
for obj in self._app.modeler.objects.values():
- used = self._find_used_variable_history(obj.history(), var_name)
+ used = self._find_used_variable_history(obj.history(), name)
if used:
- self._logger.warning("{} used in modeler.".format(var_name))
+ self._logger.warning("{} used in modeler.".format(name))
return used
# Material
for mat in self._app.materials.material_keys.values():
for _, v in mat._props.items():
- if isinstance(v, str) and var_name in re.findall("[$a-zA-Z0-9_]+", v):
+ if isinstance(v, str) and name in re.findall("[$a-zA-Z0-9_]+", v):
used = True
- self._logger.warning("{} used in the material: {}.".format(var_name, mat.name))
+ self._logger.warning("{} used in the material: {}.".format(name, mat.name))
return used
return used
- @pyaedt_function_handler()
- def is_used_variable(self, var_name):
+ @pyaedt_function_handler(var_name="name")
+ def is_used_variable(self, name):
"""Find if a variable is used.
.. deprecated:: 0.7.4
@@ -1281,7 +1314,7 @@ def is_used_variable(self, var_name):
Parameters
----------
- var_name : str
+ name : str
Name of the variable.
Returns
@@ -1291,7 +1324,7 @@ def is_used_variable(self, var_name):
"""
warnings.warn("`is_used_variable` is deprecated. Use `is_used` method instead.", DeprecationWarning)
- return self.is_used(var_name)
+ return self.is_used(name)
def _find_used_variable_history(self, history, var_name):
"""Find if a variable is used.
@@ -1463,11 +1496,11 @@ def _update_var(self):
return self._app.variable_manager.set_variable(
self._variable_name,
self._expression,
- readonly=self._readonly,
- postprocessing=self._postprocessing,
- circuit_parameter=self._circuit_parameter,
- description=self._description,
+ read_only=self._readonly,
hidden=self._hidden,
+ description=self._description,
+ is_post_processing=self._postprocessing,
+ circuit_parameter=self._circuit_parameter,
)
return False
@@ -2123,10 +2156,11 @@ class DataSet(object):
Units for the Z axis for a 3D dataset only. The default is ``""``.
vunit : str, optional
Units for the V axis for a 3D dataset only. The default is ``""``.
-
+ sort : bool, optional
+ Sort dataset. The default is ``True``.
"""
- def __init__(self, app, name, x, y, z=None, v=None, xunit="", yunit="", zunit="", vunit=""):
+ def __init__(self, app, name, x, y, z=None, v=None, xunit="", yunit="", zunit="", vunit="", sort=True):
self._app = app
self.name = name
self.x = x
@@ -2137,12 +2171,12 @@ def __init__(self, app, name, x, y, z=None, v=None, xunit="", yunit="", zunit=""
self.yunit = yunit
self.zunit = zunit
self.vunit = vunit
+ self.sort = sort
@pyaedt_function_handler()
def _args(self):
"""Retrieve arguments."""
- arg = []
- arg.append("Name:" + self.name)
+ arg = ["Name:" + self.name]
arg2 = ["Name:Coordinates"]
if self.z is None:
arg2.append(["NAME:DimUnits", self.xunit, self.yunit])
@@ -2150,16 +2184,25 @@ def _args(self):
arg2.append(["NAME:DimUnits", self.xunit, self.yunit, self.zunit, self.vunit])
else:
return False
+ z = {}
+ v = {}
if self.z:
- x, y, z, v = (list(t) for t in zip(*sorted(zip(self.x, self.y, self.z, self.v), key=lambda e: float(e[0]))))
+ if self.sort:
+ x, y, z, v = (
+ list(t) for t in zip(*sorted(zip(self.x, self.y, self.z, self.v), key=lambda e: float(e[0])))
+ )
+ else:
+ x, y, z, v = (list(t) for t in zip(*zip(self.x, self.y, self.z, self.v)))
else:
- x, y = (list(t) for t in zip(*sorted(zip(self.x, self.y), key=lambda e: float(e[0]))))
+ if self.sort:
+ x, y = (list(t) for t in zip(*sorted(zip(self.x, self.y), key=lambda e: float(e[0]))))
+ else:
+ x, y = (list(t) for t in zip(*(zip(self.x, self.y))))
+
ver = self._app._aedt_version
for i in range(len(x)):
if ver >= "2022.1":
- arg3 = ["NAME:Point"]
- arg3.append(float(x[i]))
- arg3.append(float(y[i]))
+ arg3 = ["NAME:Point", float(x[i]), float(y[i])]
if self.z:
arg3.append(float(z[i]))
arg3.append(float(v[i]))
diff --git a/pyaedt/application/__init__.py b/pyaedt/application/__init__.py
index e69de29bb2d..9c4476773da 100644
--- a/pyaedt/application/__init__.py
+++ b/pyaedt/application/__init__.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
diff --git a/pyaedt/application/aedt_objects.py b/pyaedt/application/aedt_objects.py
index 81fad1bd4fc..eb26dfef1bd 100644
--- a/pyaedt/application/aedt_objects.py
+++ b/pyaedt/application/aedt_objects.py
@@ -1,10 +1,34 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import sys
import time
-from pyaedt import is_linux
-from pyaedt import pyaedt_function_handler
-from pyaedt import settings
from pyaedt.generic.desktop_sessions import _desktop_sessions
+from pyaedt.generic.general_methods import is_linux
+from pyaedt.generic.general_methods import pyaedt_function_handler
+from pyaedt.generic.general_methods import settings
class AedtObjects(object):
diff --git a/pyaedt/application/analysis_hf.py b/pyaedt/application/analysis_hf.py
index 1171624b856..d361b5ef3d0 100644
--- a/pyaedt/application/analysis_hf.py
+++ b/pyaedt/application/analysis_hf.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
from pyaedt.generic.general_methods import pyaedt_function_handler
diff --git a/pyaedt/application/design_solutions.py b/pyaedt/application/design_solutions.py
index 8b0fa36aab9..af0e789d263 100644
--- a/pyaedt/application/design_solutions.py
+++ b/pyaedt/application/design_solutions.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import copy
from pyaedt.aedt_logger import pyaedt_logger as logger
diff --git a/pyaedt/circuit.py b/pyaedt/circuit.py
index 82296a387d8..3b81392a75c 100644
--- a/pyaedt/circuit.py
+++ b/pyaedt/circuit.py
@@ -1,4 +1,27 @@
# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
"""This module contains the ``Circuit`` class."""
from __future__ import absolute_import # noreorder
@@ -10,8 +33,6 @@
import shutil
import time
-from pyaedt import Hfss3dLayout
-from pyaedt import settings
from pyaedt.application.AnalysisNexxim import FieldAnalysisCircuit
from pyaedt.application.analysis_hf import ScatteringMethods
from pyaedt.generic import ibis_reader
@@ -22,6 +43,8 @@
from pyaedt.generic.general_methods import is_linux
from pyaedt.generic.general_methods import open_file
from pyaedt.generic.general_methods import pyaedt_function_handler
+from pyaedt.generic.settings import settings
+from pyaedt.hfss3dlayout import Hfss3dLayout
from pyaedt.modules.Boundary import CurrentSinSource
from pyaedt.modules.Boundary import PowerIQSource
from pyaedt.modules.Boundary import PowerSinSource
@@ -37,23 +60,23 @@ class Circuit(FieldAnalysisCircuit, ScatteringMethods):
Parameters
----------
- projectname : str, optional
+ project : str, optional
Name of the project to select or the full path to the project
or AEDTZ archive to open. The default is ``None``, in which
case an attempt is made to get an active project. If no
projects are present, an empty project is created.
- designname : str, optional
+ design : str, optional
Name of the design to select. The default is ``None``, in
which case an attempt is made to get an active design. If no
designs are present, an empty design is created.
solution_type : str, optional
Solution type to apply to the design. The default is
``None``, in which case the default type is applied.
- setup_name : str, optional
+ setup : str, optional
Name of the setup to use as the nominal. The default is
``None``, in which case the active setup is used or
nothing is used.
- specified_version : str, int, float, optional
+ version : str, int, float, optional
Version of AEDT to use. The default is ``None``, in which case
the active version or latest installed version is used.
This parameter is ignored when Script is launched within AEDT.
@@ -62,7 +85,7 @@ class Circuit(FieldAnalysisCircuit, ScatteringMethods):
Whether to run AEDT in non-graphical mode. The default
is ``False``, in which case AEDT is launched in graphical mode.
This parameter is ignored when a script is launched within AEDT.
- new_desktop_session : bool, optional
+ new_desktop : bool, optional
Whether to launch an instance of AEDT in a new thread, even if
another instance of the ``specified_version`` is active on the
machine. The default is ``False``. This parameter is ignored when
@@ -84,7 +107,11 @@ class Circuit(FieldAnalysisCircuit, ScatteringMethods):
`"ansysedt.exe -grpcsrv portnum"`.
aedt_process_id : int, optional
Process ID for the instance of AEDT to point PyAEDT at. The default is
- ``None``. This parameter is only used when ``new_desktop_session = False``.
+ ``None``. This parameter is only used when ``new_desktop = False``.
+ remove_lock : bool, optional
+ Whether to remove lock to project before opening it or not.
+ The default is ``False``, which means to not unlock
+ the existing project if needed and raise an exception.
Examples
--------
@@ -113,45 +140,54 @@ class Circuit(FieldAnalysisCircuit, ScatteringMethods):
Create an instance of Circuit using the 2023 R2 version and
open the specified project, which is ``"myfile.aedt"``.
- >>> aedtapp = Circuit(specified_version=2023.2, projectname="myfile.aedt")
+ >>> aedtapp = Circuit(version=2023.2, project="myfile.aedt")
Create an instance of Circuit using the 2023 R2 student version and open
the specified project, which is named ``"myfile.aedt"``.
- >>> hfss = Circuit(specified_version="2023.2", projectname="myfile.aedt", student_version=True)
+ >>> hfss = Circuit(version="2023.2", project="myfile.aedt", student_version=True)
"""
+ @pyaedt_function_handler(
+ designname="design",
+ projectname="project",
+ specified_version="version",
+ setup_name="setup",
+ new_desktop_session="new_desktop",
+ )
def __init__(
self,
- projectname=None,
- designname=None,
+ project=None,
+ design=None,
solution_type=None,
- setup_name=None,
- specified_version=None,
+ setup=None,
+ version=None,
non_graphical=False,
- new_desktop_session=False,
+ new_desktop=False,
close_on_exit=False,
student_version=False,
machine="",
port=0,
aedt_process_id=None,
+ remove_lock=False,
):
FieldAnalysisCircuit.__init__(
self,
"Circuit Design",
- projectname,
- designname,
+ project,
+ design,
solution_type,
- setup_name,
- specified_version,
+ setup,
+ version,
non_graphical,
- new_desktop_session,
+ new_desktop,
close_on_exit,
student_version,
machine,
port,
aedt_process_id,
+ remove_lock=remove_lock,
)
ScatteringMethods.__init__(self, self)
self.onetwork_data_explorer = self._desktop.GetTool("NdExplorer")
@@ -1620,7 +1656,7 @@ def import_edb_in_circuit(self, input_dir):
active_project = hfss.desktop_class.active_project(self.project_name)
active_project.Paste()
hfss_3d_layout_model = self.modeler.schematic.add_subcircuit_3dlayout(hfss.design_name)
- hfss.close_project(save_project=False)
+ hfss.close_project(save=False)
return hfss_3d_layout_model
@pyaedt_function_handler(touchstone="input_file")
diff --git a/pyaedt/common_rpc.py b/pyaedt/common_rpc.py
index b53a519c420..d5739c5bd3b 100644
--- a/pyaedt/common_rpc.py
+++ b/pyaedt/common_rpc.py
@@ -1,11 +1,35 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import os
import signal
import sys
import tempfile
import time
-from pyaedt import is_ironpython
from pyaedt.aedt_logger import pyaedt_logger as logger
+from pyaedt.generic.general_methods import is_ironpython
from pyaedt.generic.settings import settings
from pyaedt.misc import list_installed_ansysem
@@ -252,7 +276,7 @@ def launch_server(port=18000, ansysem_path=None, non_graphical=False, threaded=T
t.start()
-def create_session(server_name, client_port=None, launch_aedt_on_server=False, aedt_port=None, non_graphical=True):
+def create_session(server_name, client_port=None, launch_aedt_on_server=False, aedt_port=None, non_graphical=False):
"""
Connect to an existing AEDT server session and create a new client session from it.
diff --git a/pyaedt/desktop.py b/pyaedt/desktop.py
index 44191724188..df1412b993a 100644
--- a/pyaedt/desktop.py
+++ b/pyaedt/desktop.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
"""
This module contains the ``Desktop`` class.
This module is used to initialize AEDT and the message manager for managing AEDT.
@@ -22,12 +46,12 @@
import warnings
from pyaedt import __version__ as pyaedt_version
-from pyaedt import is_ironpython
-from pyaedt import is_linux
-from pyaedt import is_windows
from pyaedt.aedt_logger import AedtLogger
from pyaedt.aedt_logger import pyaedt_logger
from pyaedt.generic.general_methods import generate_unique_name
+from pyaedt.generic.general_methods import is_ironpython
+from pyaedt.generic.general_methods import is_linux
+from pyaedt.generic.general_methods import is_windows
if is_linux:
os.environ["ANS_NODEPCHECK"] = str(1)
@@ -38,7 +62,6 @@
import subprocess
from pyaedt import __version__
-from pyaedt import pyaedt_function_handler
from pyaedt.generic.desktop_sessions import _desktop_sessions
from pyaedt.generic.desktop_sessions import _edb_sessions
from pyaedt.generic.general_methods import active_sessions
@@ -48,6 +71,7 @@
from pyaedt.generic.general_methods import inside_desktop
from pyaedt.generic.general_methods import is_ironpython
from pyaedt.generic.general_methods import open_file
+from pyaedt.generic.general_methods import pyaedt_function_handler
from pyaedt.generic.settings import settings
from pyaedt.misc import current_student_version
from pyaedt.misc import current_version
@@ -390,7 +414,7 @@ class Desktop(object):
Parameters
----------
- specified_version : str, int, float, optional
+ version : str, int, float, optional
Version of AEDT to use. The default is ``None``, in which case the
active setup or latest installed version is used.
Examples of input values are ``232``, ``23.2``,``2023.2``,``"2023.2"``.
@@ -398,7 +422,7 @@ class Desktop(object):
Whether to launch AEDT in non-graphical mode. The default
is ``False``, in which case AEDT is launched in graphical mode.
This parameter is ignored when a script is launched within AEDT.
- new_desktop_session : bool, optional
+ new_desktop : bool, optional
Whether to launch an instance of AEDT in a new thread, even if
another instance of the ``specified_version`` is active on the machine.
The default is ``True``.
@@ -420,17 +444,17 @@ class Desktop(object):
later. The remote server must be up and running with the command `"ansysedt.exe -grpcsrv portnum"`.
aedt_process_id : int, optional
Process ID for the instance of AEDT to point PyAEDT at. The default is
- ``None``. This parameter is only used when ``new_desktop_session = False``.
+ ``None``. This parameter is only used when ``new_desktop = False``.
Examples
--------
Launch AEDT 2023 R1 in non-graphical mode and initialize HFSS.
>>> import pyaedt
- >>> desktop = pyaedt.Desktop(specified_version="2023.2", non_graphical=True)
+ >>> desktop = pyaedt.Desktop(version="2023.2", non_graphical=False)
PyAEDT INFO: pyaedt v...
PyAEDT INFO: Python version ...
- >>> hfss = pyaedt.Hfss(designname="HFSSDesign1")
+ >>> hfss = pyaedt.Hfss(design="HFSSDesign1")
PyAEDT INFO: Project...
PyAEDT INFO: Added design 'HFSSDesign1' of type HFSS.
@@ -439,7 +463,7 @@ class Desktop(object):
>>> desktop = Desktop(232)
PyAEDT INFO: pyaedt v...
PyAEDT INFO: Python version ...
- >>> hfss = pyaedt.Hfss(designname="HFSSDesign1")
+ >>> hfss = pyaedt.Hfss(design="HFSSDesign1")
PyAEDT INFO: No project is defined. Project...
"""
@@ -448,14 +472,20 @@ class Desktop(object):
def __new__(cls, *args, **kwargs):
# The following commented lines will be useful when we will need to search among multiple saved desktop.
- specified_version = kwargs.get("specified_version") or None if (not args or len(args) < 1) else args[0]
- new_desktop_session = kwargs.get("new_desktop_session") or False if (not args or len(args) < 3) else args[2]
+ specified_version = (
+ kwargs.get("specified_version") or kwargs.get("version") or None if (not args or len(args) < 1) else args[0]
+ )
+ new_desktop = (
+ kwargs.get("new_desktop_session") or kwargs.get("new_desktop") or False
+ if (not args or len(args) < 3)
+ else args[2]
+ )
# student_version = kwargs.get("student_version") or False if (not args or len(args)<5) else args[4]
# machine = kwargs.get("machine") or "" if (not args or len(args)<6) else args[5]
specified_version = get_string_version(specified_version)
port = kwargs.get("port") or 0 if (not args or len(args) < 7) else args[6]
aedt_process_id = kwargs.get("aedt_process_id") or None if (not args or len(args) < 8) else args[7]
- if settings.use_multi_desktop and not inside_desktop and new_desktop_session:
+ if settings.use_multi_desktop and not inside_desktop and new_desktop:
pyaedt_logger.info("Initializing new Desktop session.")
return object.__new__(cls)
elif len(_desktop_sessions.keys()) > 0:
@@ -482,20 +512,23 @@ def __new__(cls, *args, **kwargs):
pyaedt_logger.info("Initializing new Desktop session.")
return object.__new__(cls)
- @pyaedt_function_handler()
+ @pyaedt_function_handler(
+ specified_version="version",
+ new_desktop_session="new_desktop",
+ )
def __init__(
self,
- specified_version=None,
+ version=None,
non_graphical=False,
- new_desktop_session=True,
+ new_desktop=True,
close_on_exit=True,
student_version=False,
machine="",
port=0,
aedt_process_id=None,
):
- if _desktop_sessions and specified_version is None:
- specified_version = list(_desktop_sessions.values())[-1].aedt_version_id
+ if _desktop_sessions and version is None:
+ version = list(_desktop_sessions.values())[-1].aedt_version_id
if aedt_process_id: # pragma no cover
aedt_process_id = int(aedt_process_id)
if getattr(self, "_initialized", None) is not None and self._initialized:
@@ -516,20 +549,20 @@ def __init__(
self.launched_by_pyaedt = False
# Used in unit tests. The ``PYAEDT_NON_GRAPHICAL`` environment variable overrides
- # the ``non_graphical`` argument.
+ # the ``graphical`` argument.
if os.getenv("PYAEDT_NON_GRAPHICAL", None) is not None: # pragma no cover
non_graphical = os.getenv("PYAEDT_NON_GRAPHICAL", "false").lower() in ("true", "1", "t")
# Used in Examples generation to force the desktop opening
if os.getenv("PYAEDT_DOC_GENERATION", "False").lower() in ("true", "1", "t"): # pragma no cover
- new_desktop_session = True
+ new_desktop = True
# Used in toolkit scripts. The ``PYAEDT_SCRIPT_PROCESS_ID`` environment variable overrides
# the ``aedt_process_id`` argument.
if os.getenv("PYAEDT_SCRIPT_PROCESS_ID", None): # pragma no cover
aedt_process_id = int(os.getenv("PYAEDT_SCRIPT_PROCESS_ID"))
# Used in toolkit scripts. The ``PYAEDT_SCRIPT_VERSION`` environment variable overrides
- # the ``specified_version`` argument.
+ # the ``version`` argument.
if os.getenv("PYAEDT_SCRIPT_VERSION", None): # pragma no cover
- specified_version = str(os.getenv("PYAEDT_SCRIPT_VERSION"))
+ version = str(os.getenv("PYAEDT_SCRIPT_VERSION"))
self.close_on_exit = close_on_exit
self.machine = machine
@@ -557,7 +590,7 @@ def __init__(
self._logger.info("Debug logger is enabled. PyAEDT methods will be logged.")
else:
self._logger.info("Debug logger is disabled. PyAEDT methods will not be logged.")
- student_version_flag, version_key, version = self._assert_version(specified_version, student_version)
+ student_version_flag, version_key, version = self._assert_version(version, student_version)
# start the AEDT opening decision tree
# starting_mode can be one of these: "grpc", "com", "ironpython", "console_in", "console_out"
@@ -573,10 +606,10 @@ def __init__(
starting_mode = "grpc"
elif is_ironpython:
starting_mode = "ironpython"
- elif aedt_process_id and not new_desktop_session and not is_ironpython: # pragma: no cover
+ elif aedt_process_id and not new_desktop and not is_ironpython: # pragma: no cover
# connecting to an existing session has the precedence over use_grpc_api user preference
sessions = active_sessions(
- version=specified_version, student_version=student_version_flag, non_graphical=non_graphical
+ version=version, student_version=student_version_flag, non_graphical=non_graphical
)
self.logger.info(sessions)
if aedt_process_id in sessions:
@@ -588,15 +621,15 @@ def __init__(
else:
raise ValueError(
"The version specified ({}) doesn't correspond to the pid specified ({})".format(
- specified_version, aedt_process_id
+ version, aedt_process_id
)
)
elif float(version_key[0:6]) < 2022.2: # pragma no cover
starting_mode = "com"
- if non_graphical:
+ if self.non_graphical:
self._logger.disable_desktop_log()
elif float(version_key[0:6]) == 2022.2: # pragma no cover
- if non_graphical:
+ if self.non_graphical:
self._logger.disable_desktop_log()
if self.machine and self.port:
starting_mode = "grpc" # if the machine and port is specified, user wants to use gRPC
@@ -627,12 +660,12 @@ def __init__(
settings.aedt_version = version_key
if starting_mode == "ironpython": # pragma no cover
self._logger.info("Launching PyAEDT outside AEDT with IronPython.")
- self._init_ironpython(non_graphical, new_desktop_session, version)
+ self._init_ironpython(non_graphical, new_desktop, version)
elif starting_mode == "com": # pragma no cover
self._logger.info("Launching PyAEDT outside AEDT with CPython and PythonNET.")
self._init_dotnet(
non_graphical,
- new_desktop_session,
+ new_desktop,
version,
student_version_flag,
version_key,
@@ -640,7 +673,7 @@ def __init__(
)
elif starting_mode == "grpc":
self._logger.info("Launching PyAEDT outside AEDT with gRPC plugin.")
- self._init_grpc(non_graphical, new_desktop_session, version, student_version_flag, version_key)
+ self._init_grpc(non_graphical, new_desktop, version, student_version_flag, version_key)
self._set_logger_file()
settings.enable_desktop_logs = not self.non_graphical
@@ -650,7 +683,7 @@ def __init__(
self._logger.info("Python version %s", sys.version)
current_pid = int(self.odesktop.GetProcessID())
- if aedt_process_id and not new_desktop_session and aedt_process_id != current_pid: # pragma no cover
+ if aedt_process_id and not new_desktop and aedt_process_id != current_pid: # pragma no cover
raise Exception(
"AEDT started a new session instead of connecting to the session with pid: {}".format(aedt_process_id)
)
@@ -1547,6 +1580,7 @@ def release_desktop(self, close_projects=True, close_on_exit=True):
>>> desktop.release_desktop(close_projects=False, close_on_exit=False) # doctest: +SKIP
"""
+ self.grpc_plugin.recreate_application(True)
self.logger.oproject = None
self.logger.odesign = None
if os.getenv("PYAEDT_DOC_GENERATION", "False").lower() in ("true", "1", "t"): # pragma: no cover
@@ -1559,7 +1593,7 @@ def release_desktop(self, close_projects=True, close_on_exit=True):
except Exception:
self.logger.warning("Failed to close Edb object.")
- if close_projects:
+ if close_projects and "PYTEST_CURRENT_TEST" not in os.environ:
projects = self.odesktop.GetProjectList()
for project in projects:
try:
@@ -1577,7 +1611,8 @@ def release_desktop(self, close_projects=True, close_on_exit=True):
self.logger.info("Desktop has been released and closed.")
else:
self.logger.info("Desktop has been released.")
- del _desktop_sessions[self.aedt_process_id]
+ if self.aedt_process_id in _desktop_sessions:
+ del _desktop_sessions[self.aedt_process_id]
props = [a for a in dir(self) if not a.startswith("__")]
for a in props:
self.__dict__.pop(a, None)
@@ -1924,7 +1959,7 @@ def submit_ansys_cloud_job(
--------
>>> from pyaedt import Desktop
- >>> d = Desktop(specified_version="2023.1", new_desktop_session=False)
+ >>> d = Desktop(version="2023.1", new_desktop=False)
>>> d.select_scheduler("Ansys Cloud")
>>> out = d.get_available_cloud_config()
>>> job_id, job_name = d.submit_ansys_cloud_job('via_gsg.aedt',
@@ -2013,7 +2048,7 @@ def get_ansyscloud_job_info(self, job_id=None, job_name=None): # pragma: no cov
--------
>>> from pyaedt import Desktop
- >>> d = Desktop(specified_version="2023.1", new_desktop_session=False)
+ >>> d = Desktop(version="2023.1", new_desktop=False)
>>> d.select_scheduler("Ansys Cloud")
>>> out = d.get_available_cloud_config()
>>> job_id, job_name = d.submit_ansys_cloud_job('via_gsg.aedt',
@@ -2080,7 +2115,7 @@ def select_scheduler(
--------
>>> from pyaedt import Desktop
- >>> d = Desktop(specified_version="2023.1", new_desktop_session=False)
+ >>> d = Desktop(version="2023.1", new_desktop=False)
>>> d.select_scheduler("Ansys Cloud")
>>> out = d.get_available_cloud_config()
>>> job_id, job_name = d.submit_ansys_cloud_job('via_gsg.aedt',
@@ -2122,7 +2157,7 @@ def get_available_cloud_config(self, region="westeurope"): # pragma: no cover
--------
>>> from pyaedt import Desktop
- >>> d = Desktop(specified_version="2023.1", new_desktop_session=False)
+ >>> d = Desktop(version="2023.1", new_desktop=False)
>>> d.select_scheduler("Ansys Cloud")
>>> out = d.get_available_cloud_config()
>>> job_id, job_name = d.submit_ansys_cloud_job('via_gsg.aedt',
diff --git a/pyaedt/downloads.py b/pyaedt/downloads.py
index bb85da981c5..6057dc170c6 100644
--- a/pyaedt/downloads.py
+++ b/pyaedt/downloads.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
"""Download example datasets from https://github.com/ansys/example-data"""
import os
diff --git a/pyaedt/edb.py b/pyaedt/edb.py
index a3cc69fa28c..bbb9fc0d1b9 100644
--- a/pyaedt/edb.py
+++ b/pyaedt/edb.py
@@ -1,8 +1,140 @@
-from pyedb import Edb as App
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+import os
from pyaedt.generic.settings import settings
log = settings.logger
-log.warning("pyaedt.edb.Edb is Deprecated. Please use pyedb.Edb or pyaedt.Edb call instead")
-Edb = App
+
+# lazy imports
+def Edb(
+ edbpath=None,
+ cellname=None,
+ isreadonly=False,
+ edbversion=None,
+ isaedtowned=False,
+ oproject=None,
+ student_version=False,
+ use_ppe=False,
+ technology_file=None,
+):
+ """Provides the EDB application interface.
+
+ This module inherits all objects that belong to EDB.
+
+ Parameters
+ ----------
+ edbpath : str, optional
+ Full path to the ``aedb`` folder. The variable can also contain
+ the path to a layout to import. Allowed formats are BRD,
+ XML (IPC2581), GDS, and DXF. The default is ``None``.
+ For GDS import, the Ansys control file (also XML) should have the same
+ name as the GDS file. Only the file extension differs.
+ cellname : str, optional
+ Name of the cell to select. The default is ``None``.
+ isreadonly : bool, optional
+ Whether to open EBD in read-only mode when it is
+ owned by HFSS 3D Layout. The default is ``False``.
+ edbversion : str, optional
+ Version of EDB to use. The default is ``"2021.2"``.
+ isaedtowned : bool, optional
+ Whether to launch EDB from HFSS 3D Layout. The
+ default is ``False``.
+ oproject : optional
+ Reference to the AEDT project object.
+ student_version : bool, optional
+ Whether to open the AEDT student version. The default is ``False.``
+ technology_file : str, optional
+ Full path to technology file to be converted to xml before importing or xml. Supported by GDS format only.
+
+ Returns
+ -------
+ :class:`pyedb.dotnet.edb.Edb`, :class:`pyedb.grpc.edb.Edb`
+
+ Examples
+ --------
+ Create an ``Edb`` object and a new EDB cell.
+
+ >>> from pyedb import Edb
+ >>> app = Edb()
+
+ Add a new variable named "s1" to the ``Edb`` instance.
+
+ >>> app['s1'] = "0.25 mm"
+ >>> app['s1'].tofloat
+ >>> 0.00025
+ >>> app['s1'].tostring
+ >>> "0.25mm"
+
+ or add a new parameter with description:
+
+ >>> app['s2'] = ["20um", "Spacing between traces"]
+ >>> app['s2'].value
+ >>> 1.9999999999999998e-05
+ >>> app['s2'].description
+ >>> 'Spacing between traces'
+
+
+ Create an ``Edb`` object and open the specified project.
+
+ >>> app = Edb("myfile.aedb")
+
+ Create an ``Edb`` object from GDS and control files.
+ The XML control file resides in the same directory as the GDS file: (myfile.xml).
+
+ >>> app = Edb("/path/to/file/myfile.gds")
+
+ """
+
+ # Use EDB legacy (default choice)
+ if bool(os.getenv("PYEDB_USE_DOTNET", "1")):
+ from pyedb.dotnet.edb import Edb as app
+
+ return app(
+ edbpath=edbpath,
+ cellname=cellname,
+ isreadonly=isreadonly,
+ edbversion=edbversion,
+ isaedtowned=isaedtowned,
+ oproject=oproject,
+ student_version=student_version,
+ use_ppe=use_ppe,
+ technology_file=technology_file,
+ )
+ # TODO: Use EDB gRPC
+ else:
+ raise Exception("not implemented yet.")
+
+
+def Siwave(
+ specified_version=None,
+):
+ """Siwave Class."""
+ from pyedb.siwave import Siwave as app
+
+ return app(
+ specified_version=specified_version,
+ )
diff --git a/pyaedt/emit.py b/pyaedt/emit.py
index f67e403be6e..a9c1accb876 100644
--- a/pyaedt/emit.py
+++ b/pyaedt/emit.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
from __future__ import absolute_import
import warnings
@@ -17,19 +41,19 @@ class Emit(Design, object):
Parameters
----------
- projectname : str, optional
+ project : str, optional
Name of the project to select or the full path to the project
or AEDTZ archive to open. The default is ``None``, in which case
an attempt is made to get an active project. If no projects are
present, an empty project is created.
- designname : str, optional
+ design : str, optional
Name of the design to select. The default is ``None``, in which case
an attempt is made to get an active design. If no designs are
present, an empty design is created.
solution_type : str, optional
Solution type to apply to the design. The default is ``None``, in which
case the default type is applied.
- specified_version : str, int, float, optional
+ version : str, int, float, optional
Version of AEDT to use. The default is ``None``, in which case
the active setup is used or the latest installed version is
used.
@@ -38,7 +62,7 @@ class Emit(Design, object):
Whether to launch AEDT in non-graphical mode. The default
is ``False``, in which case AEDT is launched in graphical mode.
This parameter is ignored when a script is launched within AEDT.
- new_desktop_session : bool, optional
+ new_desktop : bool, optional
Whether to launch an instance of AEDT in a new thread, even if
another instance of the ``specified_version`` is active on the
machine. The default is ``False``.
@@ -58,7 +82,11 @@ class Emit(Design, object):
If the machine is `"localhost"`, the server starts if it is not present.
aedt_process_id : int, optional
Process ID for the instance of AEDT to point PyAEDT at. The default is
- ``None``. This parameter is only used when ``new_desktop_session = False``.
+ ``None``. This parameter is only used when ``new_desktop = False``.
+ remove_lock : bool, optional
+ Whether to remove lock to project before opening it or not.
+ The default is ``False``, which means to not unlock
+ the existing project if needed and raise an exception.
Examples
--------
@@ -69,7 +97,7 @@ class Emit(Design, object):
Typically, it is desirable to specify a project name, design name, and other parameters.
- >>> aedtapp = Emit(projectname, designame, specified_version=232)
+ >>> aedtapp = Emit(projectname, designame, version=232)
Once an ``Emit`` instance is initialized, you can edit the schematic:
@@ -99,19 +127,27 @@ class Emit(Design, object):
>>> print("Worst-case sensitivity for Rx '{}' is {}dB.".format(domain.rx_radio_name, val))
"""
+ @pyaedt_function_handler(
+ designname="design",
+ projectname="project",
+ specified_version="version",
+ setup_name="setup",
+ new_desktop_session="new_desktop",
+ )
def __init__(
self,
- projectname=None,
- designname=None,
+ project=None,
+ design=None,
solution_type=None,
- specified_version=None,
+ version=None,
non_graphical=False,
- new_desktop_session=True,
+ new_desktop=True,
close_on_exit=True,
student_version=False,
machine="",
port=0,
aedt_process_id=None,
+ remove_lock=False,
):
self.__emit_api_enabled = False
self.results = None
@@ -123,17 +159,18 @@ def __init__(
Design.__init__(
self,
"EMIT",
- projectname,
- designname,
+ project,
+ design,
solution_type,
- specified_version,
+ version,
non_graphical,
- new_desktop_session,
+ new_desktop,
close_on_exit,
student_version,
machine=machine,
port=port,
aedt_process_id=aedt_process_id,
+ remove_lock=remove_lock,
)
self._modeler = ModelerEmit(self)
self._couplings = CouplingsEmit(self)
diff --git a/pyaedt/emit_core/Couplings.py b/pyaedt/emit_core/Couplings.py
index 918ad5f8874..2eee0ec58e4 100644
--- a/pyaedt/emit_core/Couplings.py
+++ b/pyaedt/emit_core/Couplings.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
"""
This module contains these classes: `CouplingsEmit`.
This module provides for interacting with EMIT Analysis and Results windows.
diff --git a/pyaedt/emit_core/__init__.py b/pyaedt/emit_core/__init__.py
index 1a7b6de9744..c30f1f602b6 100644
--- a/pyaedt/emit_core/__init__.py
+++ b/pyaedt/emit_core/__init__.py
@@ -1,4 +1,27 @@
-import imp
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
from importlib import import_module
import os
import sys
@@ -10,6 +33,13 @@
from pyaedt.emit_core.emit_constants import TxRxMode
from pyaedt.emit_core.emit_constants import UnitType
+# TODO: Remove once IronPython compatibility is removed
+if sys.version_info < (3, 12):
+ import imp
+else: # pragma: no cover
+ from importlib.util import find_spec
+
+
EMIT_API_PYTHON = None
@@ -69,8 +99,17 @@ def _set_api(aedt_version):
if override_path_key in os.environ:
path = os.environ.get(override_path_key)
sys.path.insert(0, path)
- module_path = imp.find_module("EmitApiPython")[1]
- logger.info("Importing EmitApiPython from: {}".format(module_path))
+ # TODO: Remove once IronPython compatibility is removed
+ if sys.version_info < (3, 12):
+ module_path = imp.find_module("EmitApiPython")[1]
+ logger.info("Importing EmitApiPython from: {}".format(module_path))
+ else: # pragma: no cover
+ spec = find_spec("EmitApiPython")
+ if spec is None:
+ logger.warning("Module {} not found".format("EmitApiPython"))
+ else:
+ module_path = spec.origin
+ logger.info("Importing EmitApiPython from: {}".format(module_path))
global EMIT_API_PYTHON
EMIT_API_PYTHON = import_module("EmitApiPython")
logger.info("Loaded {}".format(EMIT_API_PYTHON.EmitApi().get_version(True)))
diff --git a/pyaedt/emit_core/emit_constants.py b/pyaedt/emit_core/emit_constants.py
index 90364082825..9c09566b676 100644
--- a/pyaedt/emit_core/emit_constants.py
+++ b/pyaedt/emit_core/emit_constants.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
"""
Enums from the ``EmitApiPython`` module are defined as ``None`` until this module initializes.
This allows IDE auto-complete to find them and ``emit_constants`` to import before the
diff --git a/pyaedt/emit_core/results/__init__.py b/pyaedt/emit_core/results/__init__.py
index 8b137891791..9c4476773da 100644
--- a/pyaedt/emit_core/results/__init__.py
+++ b/pyaedt/emit_core/results/__init__.py
@@ -1 +1,23 @@
-
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
diff --git a/pyaedt/emit_core/results/results.py b/pyaedt/emit_core/results/results.py
index 5cc9d46b2f2..19b634523bf 100644
--- a/pyaedt/emit_core/results/results.py
+++ b/pyaedt/emit_core/results/results.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import warnings
from pyaedt import emit_core
diff --git a/pyaedt/emit_core/results/revision.py b/pyaedt/emit_core/results/revision.py
index 86973012ac4..ce94aceb32d 100644
--- a/pyaedt/emit_core/results/revision.py
+++ b/pyaedt/emit_core/results/revision.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import warnings
from pyaedt.emit_core.emit_constants import EmiCategoryFilter
diff --git a/pyaedt/generic/DataHandlers.py b/pyaedt/generic/DataHandlers.py
index 5312aa61439..19db10aac28 100644
--- a/pyaedt/generic/DataHandlers.py
+++ b/pyaedt/generic/DataHandlers.py
@@ -1,4 +1,27 @@
# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
from collections import OrderedDict
from decimal import Decimal
import math
@@ -596,7 +619,7 @@ def from_rkm_to_aedt(code):
setup = os.getenv('setup')
with Desktop() as d:
- maxwell_2d = Maxwell2d(designname=design_name, name=setup)
+ maxwell_2d = Maxwell2d(design=design_name, name=setup)
maxwell_2d.setup_ctrlprog(keep_modifications=True )
d.logger.info("Successfully updated project definitions")
maxwell_2d.save_project()
diff --git a/pyaedt/generic/LoadAEDTFile.py b/pyaedt/generic/LoadAEDTFile.py
index b679456cb04..785f3307ada 100644
--- a/pyaedt/generic/LoadAEDTFile.py
+++ b/pyaedt/generic/LoadAEDTFile.py
@@ -1,4 +1,27 @@
# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import os.path
import re
diff --git a/pyaedt/generic/__init__.py b/pyaedt/generic/__init__.py
index e69de29bb2d..9c4476773da 100644
--- a/pyaedt/generic/__init__.py
+++ b/pyaedt/generic/__init__.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
diff --git a/pyaedt/generic/clr_module.py b/pyaedt/generic/clr_module.py
index 7564603c433..c331515755b 100644
--- a/pyaedt/generic/clr_module.py
+++ b/pyaedt/generic/clr_module.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import os
import pkgutil
import sys
diff --git a/pyaedt/generic/com_parameters.py b/pyaedt/generic/com_parameters.py
index e69de29bb2d..9c4476773da 100644
--- a/pyaedt/generic/com_parameters.py
+++ b/pyaedt/generic/com_parameters.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
diff --git a/pyaedt/generic/compliance.py b/pyaedt/generic/compliance.py
index 9f24c0012b1..27c702c74f5 100644
--- a/pyaedt/generic/compliance.py
+++ b/pyaedt/generic/compliance.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import os.path
from pathlib import Path
import time
diff --git a/pyaedt/generic/configurations.py b/pyaedt/generic/configurations.py
index 55349386ca4..351d0aa67cd 100644
--- a/pyaedt/generic/configurations.py
+++ b/pyaedt/generic/configurations.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
from collections import OrderedDict
import copy
from datetime import datetime
@@ -6,16 +30,14 @@
import tempfile
import pyaedt
-from pyaedt import Icepak
from pyaedt import __version__
-from pyaedt import generate_unique_folder_name
-from pyaedt import get_pyaedt_app
-from pyaedt import is_ironpython
from pyaedt.application.Variables import decompose_variable_value
from pyaedt.generic.DataHandlers import _arg2dict
from pyaedt.generic.LoadAEDTFile import load_keyword_in_aedt_file
from pyaedt.generic.general_methods import GrpcApiError
+from pyaedt.generic.general_methods import generate_unique_folder_name
from pyaedt.generic.general_methods import generate_unique_name
+from pyaedt.generic.general_methods import is_ironpython
from pyaedt.generic.general_methods import open_file
from pyaedt.generic.general_methods import pyaedt_function_handler
from pyaedt.generic.general_methods import read_configuration_file
@@ -1094,7 +1116,7 @@ def import_config(self, config_file, *args):
self.results.import_variables = True
try:
for k, v in dict_in["general"]["postprocessing_variables"].items():
- self._app.variable_manager.set_variable(k, v, postprocessing=True)
+ self._app.variable_manager.set_variable(k, v, is_post_processing=True)
except KeyError:
self.results.import_postprocessing_variables = False
else:
@@ -1118,9 +1140,7 @@ def import_config(self, config_file, *args):
if numcol > 2:
zunit = val["Coordinates"]["DimUnits"][2]
zval = new_list[2]
- if not self._app.create_dataset(
- el[1:], xunit=xunit, yunit=yunit, zunit=zunit, xlist=xval, ylist=yval, zlist=zval
- ):
+ if not self._app.create_dataset(el[1:], x=xval, y=yval, z=zval, x_unit=xunit, y_unit=yunit):
self.results.import_material_datasets = False
if self.options.import_materials and dict_in.get("materials", None):
@@ -1865,6 +1885,8 @@ def import_config(self, config_file, *args):
@pyaedt_function_handler
def _get_duplicate_names(self):
# Copy project to get dictionary
+ from pyaedt.icepak import Icepak
+
directory = os.path.join(
self._app.toolkit_directory,
self._app.design_name,
@@ -1872,7 +1894,7 @@ def _get_duplicate_names(self):
)
os.makedirs(directory)
tempproj_name = os.path.join(directory, "temp_proj.aedt")
- tempproj = Icepak(tempproj_name, specified_version=self._app._aedt_version)
+ tempproj = Icepak(tempproj_name, version=self._app._aedt_version)
empty_design = tempproj.design_list[0]
self._app.modeler.refresh()
self._app.modeler.delete(
@@ -2090,6 +2112,8 @@ def apply_operations_to_native_components(obj, operation_dict, native_dict): #
]["DefnLink"]["Project"] not in [self._app.project_file or "This Project*"]:
prj = list(set(self._app.project_list) - prj_list)[0]
design = nc_dict["NativeComponentDefinitionProvider"]["DefnLink"]["Design"]
+ from pyaedt.generic.design_types import get_pyaedt_app
+
app = get_pyaedt_app(prj, design)
app.oproject.Close()
user_defined_component = UserDefinedComponent(
diff --git a/pyaedt/generic/constants.py b/pyaedt/generic/constants.py
index 854916e1640..33bcb86eda6 100644
--- a/pyaedt/generic/constants.py
+++ b/pyaedt/generic/constants.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import math
import warnings
diff --git a/pyaedt/generic/design_types.py b/pyaedt/generic/design_types.py
index d63284d4b15..e54feb076b8 100644
--- a/pyaedt/generic/design_types.py
+++ b/pyaedt/generic/design_types.py
@@ -1,1557 +1,58 @@
-import re
-import sys
-import time
-
-from pyaedt import is_linux
-from pyaedt.generic.settings import settings
-
-
-# lazy imports
-def Circuit(
- projectname=None,
- designname=None,
- solution_type=None,
- setup_name=None,
- specified_version=None,
- non_graphical=False,
- new_desktop_session=False,
- close_on_exit=False,
- student_version=False,
- machine="",
- port=0,
- aedt_process_id=None,
-):
- """Circuit Class.
-
- Parameters
- ----------
- projectname : str, optional
- Name of the project to select or the full path to the project
- or AEDTZ archive to open. The default is ``None``, in which
- case an attempt is made to get an active project. If no
- projects are present, an empty project is created.
- designname : str, optional
- Name of the design to select. The default is ``None``, in
- which case an attempt is made to get an active design. If no
- designs are present, an empty design is created.
- solution_type : str, optional
- Solution type to apply to the design. The default is
- ``None``, in which case the default type is applied.
- setup_name : str, optional
- Name of the setup to use as the nominal. The default is
- ``None``, in which case the active setup is used or
- nothing is used.
- specified_version : str, int, float, optional
- Version of AEDT to use. The default is ``None``, in which case
- the active version or latest installed version is used.
- This parameter is ignored when Script is launched within AEDT.
- Examples of input values are ``232``, ``23.2``,``2023.2``,``"2023.2"``.
- non_graphical : bool, optional
- Whether to run AEDT in non-graphical mode. The default
- is ``False``, in which case AEDT is launched in graphical mode.
- This parameter is ignored when a script is launched within AEDT.
- new_desktop_session : bool, optional
- Whether to launch an instance of AEDT in a new thread, even if
- another instance of the ``specified_version`` is active on the
- machine. The default is ``False``. This parameter is ignored when
- a script is launched within AEDT.
- close_on_exit : bool, optional
- Whether to release AEDT on exit. The default is ``False``.
- student_version : bool, optional
- Whether to open the AEDT student version. The default is ``False``.
- This parameter is ignored when Script is launched within AEDT.
- machine : str, optional
- Machine name to which connect the oDesktop Session. Works only in 2022 R2
- or later. The remote server must be up and running with the command
- `"ansysedt.exe -grpcsrv portnum"`. If a machine is `"localhost"`, the
- server also starts if not present.
- port : int, optional
- Port number on which to start the oDesktop communication on an already existing server.
- This parameter is ignored when creating a new server. It works only in 2022 R2 or
- later. The remote server must be up and running with the command
- `"ansysedt.exe -grpcsrv portnum"`.
- aedt_process_id : int, optional
- Process ID for the instance of AEDT to point PyAEDT at. The default is
- ``None``. This parameter is only used when ``new_desktop_session = False``.
-
- Returns
- -------
- :class:`pyaedt.circuit.Circuit`
-
- Examples
- --------
- Create an instance of Circuit and connect to an existing HFSS
- design or create a new HFSS design if one does not exist.
-
- >>> from pyaedt import Circuit
- >>> aedtapp = Circuit()
-
- Create an instance of Circuit and link to a project named
- ``"projectname"``. If this project does not exist, create one with
- this name.
-
- >>> aedtapp = Circuit(projectname)
-
- Create an instance of Circuit and link to a design named
- ``"designname"`` in a project named ``"projectname"``.
-
- >>> aedtapp = Circuit(projectname,designame)
-
- Create an instance of Circuit and open the specified project,
- which is ``"myfie.aedt"``.
-
- >>> aedtapp = Circuit("myfile.aedt")
-
- Create an instance of Circuit using the 2023 R2 version and
- open the specified project, which is ``"myfile.aedt"``.
-
- >>> aedtapp = Circuit(specified_version=2023.2, projectname="myfile.aedt")
-
- Create an instance of Circuit using the 2023 R2 student version and open
- the specified project, which is named ``"myfile.aedt"``.
-
- >>> hfss = Circuit(specified_version="2023.2", projectname="myfile.aedt", student_version=True)
-
- """
- from pyaedt.circuit import Circuit as app
-
- return app(
- projectname=projectname,
- designname=designname,
- solution_type=solution_type,
- setup_name=setup_name,
- specified_version=specified_version,
- non_graphical=non_graphical,
- new_desktop_session=new_desktop_session,
- close_on_exit=close_on_exit,
- student_version=student_version,
- machine=machine,
- port=port,
- aedt_process_id=aedt_process_id,
- )
-
-
-def Hfss(
- projectname=None,
- designname=None,
- solution_type=None,
- setup_name=None,
- specified_version=None,
- non_graphical=False,
- new_desktop_session=False,
- close_on_exit=False,
- student_version=False,
- machine="",
- port=0,
- aedt_process_id=None,
-):
- """Return an instance of the Hfss Class.
-
- Parameters
- ----------
- projectname : str, optional
- Name of the project to select or the full path to the project
- or AEDTZ archive to open. The default is ``None``, in which
- case an attempt is made to get an active project. If no
- projects are present, an empty project is created.
- designname : str, optional
- Name of the design to select. The default is ``None``, in
- which case an attempt is made to get an active design. If no
- designs are present, an empty design is created.
- solution_type : str, optional
- Solution type to apply to the design. The default is
- ``None``, in which case the default type is applied.
- setup_name : str, optional
- Name of the setup to use as the nominal. The default is
- ``None``, in which case the active setup is used or
- nothing is used.
- specified_version : str, int, float, optional
- Version of AEDT to use. The default is ``None``, in which case
- the active version or latest installed version is used.
- This parameter is ignored when a script is launched within AEDT.
- Examples of input values are ``232``, ``23.2``,``2023.2``,``"2023.2"``.
- non_graphical : bool, optional
- Whether to run AEDT in non-graphical mode. The default
- is ``False``, in which case AEDT is launched in graphical mode.
- This parameter is ignored when a script is launched within AEDT.
- new_desktop_session : bool, optional
- Whether to launch an instance of AEDT in a new thread, even if
- another instance of the ``specified_version`` is active on the
- machine. The default is ``False``. This parameter is ignored when
- a script is launched within AEDT.
- close_on_exit : bool, optional
- Whether to release AEDT on exit. The default is ``False``.
- student_version : bool, optional
- Whether to open the AEDT student version. The default is
- ``False``. This parameter is ignored when a script is launched
- within AEDT.
- machine : str, optional
- Machine name to connect the oDesktop session to. This parameter works only on
- 2022 R2 or later. The remote Server must be up and running with the command
- `"ansysedt.exe -grpcsrv portnum"`. If the machine is `"localhost"`, the server
- starts if it is not present.
- port : int, optional
- Port number on which to start the oDesktop communication on an already existing server.
- This parameter is ignored when creating a new server. It works only in 2022 R2 or later.
- The remote server must be up and running with the command `"ansysedt.exe -grpcsrv portnum"`.
- aedt_process_id : int, optional
- Process ID for the instance of AEDT to point PyAEDT at. The default is
- ``None``. This parameter is only used when ``new_desktop_session = False``.
-
- Returns
- -------
- :class:`pyaedt.hfss.Hfss`
-
- Examples
- --------
- Create an instance of HFSS and connect to an existing HFSS
- design or create a new HFSS design if one does not exist.
-
- >>> from pyaedt import Hfss
- >>> hfss = Hfss()
- PyAEDT INFO: No project is defined...
- PyAEDT INFO: Active design is set to...
-
-
- Create an instance of HFSS and link to a project named
- ``HfssProject``. If this project does not exist, create one with
- this name.
-
- >>> hfss = Hfss("HfssProject")
- PyAEDT INFO: Project HfssProject has been created.
- PyAEDT INFO: No design is present. Inserting a new design.
- PyAEDT INFO: Added design ...
-
-
- Create an instance of HFSS and link to a design named
- ``HfssDesign1`` in a project named ``HfssProject``.
-
- >>> hfss = Hfss("HfssProject","HfssDesign1")
- PyAEDT INFO: Added design 'HfssDesign1' of type HFSS.
-
-
- Create an instance of HFSS and open the specified project,
- which is named ``"myfile.aedt"``.
-
- >>> hfss = Hfss("myfile.aedt")
- PyAEDT INFO: Project myfile has been created.
- PyAEDT INFO: No design is present. Inserting a new design.
- PyAEDT INFO: Added design...
-
-
- Create an instance of HFSS using the 2023 R2 release and open
- the specified project, which is named ``"myfile2.aedt"``.
-
- >>> hfss = Hfss(specified_version=232, projectname="myfile2.aedt")
- PyAEDT INFO: Project myfile2 has been created.
- PyAEDT INFO: No design is present. Inserting a new design.
- PyAEDT INFO: Added design...
-
-
- Create an instance of HFSS using the 2023 R2 student version and open
- the specified project, which is named ``"myfile3.aedt"``.
-
- >>> hfss = Hfss(specified_version="2023.2", projectname="myfile3.aedt", student_version=True)
- PyAEDT INFO: Project myfile3 has been created.
- PyAEDT INFO: No design is present. Inserting a new design.
- PyAEDT INFO: Added design...
-
- """
- from pyaedt.hfss import Hfss as app
-
- return app(
- projectname=projectname,
- designname=designname,
- solution_type=solution_type,
- setup_name=setup_name,
- specified_version=specified_version,
- non_graphical=non_graphical,
- new_desktop_session=new_desktop_session,
- close_on_exit=close_on_exit,
- student_version=student_version,
- machine=machine,
- port=port,
- aedt_process_id=aedt_process_id,
- )
-
-
-def Icepak(
- projectname=None,
- designname=None,
- solution_type=None,
- setup_name=None,
- specified_version=None,
- non_graphical=False,
- new_desktop_session=False,
- close_on_exit=False,
- student_version=False,
- machine="",
- port=0,
- aedt_process_id=None,
-):
- """Icepak Class.
-
- Parameters
- ----------
- projectname : str, optional
- Name of the project to select or the full path to the project
- or AEDTZ archive to open. The default is ``None``, in which
- case an attempt is made to get an active project. If no
- projects are present, an empty project is created.
- designname : str, optional
- Name of the design to select. The default is ``None``, in
- which case an attempt is made to get an active design. If no
- designs are present, an empty design is created.
- solution_type : str, optional
- Solution type to apply to the design. The default is
- ``None``, in which case the default type is applied.
- setup_name : str, optional
- Name of the setup to use as the nominal. The default is
- ``None``, in which case the active setup is used or
- nothing is used.
- specified_version : str, int, float, optional
- Version of AEDT to use. The default is ``None``, in which case
- the active version or latest installed version is used.
- This parameter is ignored when Script is launched within AEDT.
- Examples of input values are ``232``, ``23.2``,``2023.2``,``"2023.2"``.
- non-graphical : bool, optional
- Whether to launch AEDT in non-graphical mode. The default
- is ``False``, in which case AEDT is launched in graphical mode.
- This parameter is ignored when a script is launched within AEDT.
- new_desktop_session : bool, optional
- Whether to launch an instance of AEDT in a new thread, even if
- another instance of the ``specified_version`` is active on the
- machine. The default is ``False``.
- close_on_exit : bool, optional
- Whether to release AEDT on exit. The default is ``False``.
- student_version : bool, optional
- Whether to open the AEDT student version. The default is ``False``.
- This parameter is ignored when a script is launched within AEDT.
- machine : str, optional
- Machine name to connect the oDesktop session to. This works only in 2022 R2 or later.
- The remote server must be up and running with the command `"ansysedt.exe -grpcsrv portnum"`.
- If the machine is `"localhost"`, the server also starts if not present.
- port : int, optional
- Port number of which to start the oDesktop communication on an already existing server.
- This parameter is ignored when creating a new server. It works only in 2022 R2 or later.
- The remote server must be up and running with the command `"ansysedt.exe -grpcsrv portnum"`.
- aedt_process_id : int, optional
- Process ID for the instance of AEDT to point PyAEDT at. The default is
- ``None``. This parameter is only used when ``new_desktop_session = False``.
-
- Returns
- -------
- :class:`pyaedt.icepak.Icepak`
-
- Examples
- --------
-
- Create an instance of Icepak and connect to an existing Icepak
- design or create a new Icepak design if one does not exist.
-
- >>> from pyaedt import Icepak
- >>> icepak = Icepak()
- PyAEDT INFO: No project is defined. Project ...
- PyAEDT INFO: Active design is set to ...
-
- Create an instance of Icepak and link to a project named
- ``IcepakProject``. If this project does not exist, create one with
- this name.
-
- >>> icepak = Icepak("IcepakProject")
- PyAEDT INFO: Project ...
- PyAEDT INFO: Added design ...
-
- Create an instance of Icepak and link to a design named
- ``IcepakDesign1`` in a project named ``IcepakProject``.
-
- >>> icepak = Icepak("IcepakProject", "IcepakDesign1")
- PyAEDT INFO: Added design 'IcepakDesign1' of type Icepak.
-
- Create an instance of Icepak and open the specified project,
- which is ``myipk.aedt``.
-
- >>> icepak = Icepak("myipk.aedt")
- PyAEDT INFO: Project myipk has been created.
- PyAEDT INFO: No design is present. Inserting a new design.
- PyAEDT INFO: Added design ...
-
- Create an instance of Icepak using the 2023 R2 release and
- open the specified project, which is ``myipk2.aedt``.
-
- >>> icepak = Icepak(specified_version=2023.2, projectname="myipk2.aedt")
- PyAEDT INFO: Project...
- PyAEDT INFO: No design is present. Inserting a new design.
- PyAEDT INFO: Added design...
- """
- from pyaedt.icepak import Icepak as app
-
- return app(
- projectname=projectname,
- designname=designname,
- solution_type=solution_type,
- setup_name=setup_name,
- specified_version=specified_version,
- non_graphical=non_graphical,
- new_desktop_session=new_desktop_session,
- close_on_exit=close_on_exit,
- student_version=student_version,
- machine=machine,
- port=port,
- aedt_process_id=aedt_process_id,
- )
-
-
-def Emit(
- projectname=None,
- designname=None,
- solution_type=None,
- specified_version=None,
- non_graphical=False,
- new_desktop_session=False,
- close_on_exit=False,
- student_version=False,
- machine="",
- port=0,
- aedt_process_id=None,
-):
- """Emit Class.
-
- Parameters
- ----------
- projectname : str, optional
- Name of the project to select or the full path to the project
- or AEDTZ archive to open. The default is ``None``, in which case
- an attempt is made to get an active project. If no projects are
- present, an empty project is created.
- designname : str, optional
- Name of the design to select. The default is ``None``, in which case
- an attempt is made to get an active design. If no designs are
- present, an empty design is created.
- solution_type : str, optional
- Solution type to apply to the design. The default is ``None``, in which
- case the default type is applied.
- specified_version : str, int, float, optional
- Version of AEDT to use. The default is ``None``, in which case
- the active setup is used or the latest installed version is
- used.
- Examples of input values are ``232``, ``23.2``,``2023.2``,``"2023.2"``.
- non_graphical : bool, optional
- Whether to launch AEDT in non-graphical mode. The default
- is ``False``, in which case AEDT is launched in graphical mode.
- This parameter is ignored when a script is launched within AEDT.
- new_desktop_session : bool, optional
- Whether to launch an instance of AEDT in a new thread, even if
- another instance of the ``specified_version`` is active on the
- machine. The default is ``False``.
- close_on_exit : bool, optional
- Whether to release AEDT on exit. The default is ``False``.
- student_version : bool, optional
- Whether to start the AEDT student version. The default is ``False``.
- port : int, optional
- Port number on which to start the oDesktop communication on an already existing server.
- This parameter is ignored when creating a server. This parameter works only in 2022 R2 or later.
- The remote server must be up and running with the command `"ansysedt.exe -grpcsrv portnum"`.
- The default is ``0``.
- machine : str, optional
- Machine name that the Desktop session is to connect to. This
- parameter works only in 2022 R2 and later. The remote server must be
- up and running with the command `"ansysedt.exe -grpcsrv portnum"`.
- If the machine is `"localhost"`, the server starts if it is not present.
- aedt_process_id : int, optional
- Process ID for the instance of AEDT to point PyAEDT at. The default is
- ``None``. This parameter is only used when ``new_desktop_session = False``.
-
- Returns
- -------
- :class:`pyaedt.emit.Emit`
-
- Examples
- --------
- Create an ``Emit`` instance. You can also choose to define parameters for this instance here.
-
- >>> from pyaedt import Emit
- >>> aedtapp = Emit()
-
- Typically, it is desirable to specify a project name, design name, and other parameters.
-
- >>> aedtapp = Emit(projectname, designame, specified_version=232)
-
- Once an ``Emit`` instance is initialized, you can edit the schematic:
-
- >>> rad1 = aedtapp.modeler.components.create_component("Bluetooth")
- >>> ant1 = aedtapp.modeler.components.create_component("Antenna")
- >>> if rad1 and ant1:
- >>> ant1.move_and_connect_to(rad1)
-
- Once the schematic is generated, the ``Emit`` object can be analyzed to generate
- a revision. Each revision is added as an element of the ``Emit`` object member's
- revisions_list.
-
- >>> aedtapp.analyze()
-
- A revision within PyAEDT is analogous to a revision in AEDT. An interaction domain must
- be defined and then used as the input to the run command used on that revision.
-
- >>> domain = aedtapp.interaction_domain()
- >>> domain.rx_radio_name = "UE - HandHeld"
- >>> interaction = aedtapp.revisions_list[0].run(domain)
-
- The output of the run command is an ``interaction`` object. This object summarizes the interaction data
- that is defined in the interaction domain.
-
- >>> instance = interaction.worst_instance(ResultType.SENSITIVITY)
- >>> val = instance.value(ResultType.SENSITIVITY)
- >>> print("Worst-case sensitivity for Rx '{}' is {}dB.".format(domain.rx_radio_name, val))
- """
- from pyaedt.emit import Emit as app
-
- return app(
- projectname=projectname,
- designname=designname,
- solution_type=solution_type,
- specified_version=specified_version,
- non_graphical=non_graphical,
- new_desktop_session=new_desktop_session,
- close_on_exit=close_on_exit,
- student_version=student_version,
- machine=machine,
- port=port,
- aedt_process_id=aedt_process_id,
- )
-
-
-def Hfss3dLayout(
- projectname=None,
- designname=None,
- solution_type=None,
- setup_name=None,
- specified_version=None,
- non_graphical=False,
- new_desktop_session=False,
- close_on_exit=False,
- student_version=False,
- machine="",
- port=0,
- aedt_process_id=None,
- ic_mode=None,
-):
- """Hfss3dLayout Class.
-
- Parameters
- ----------
- projectname : str, optional
- Name of the project to select or the full path to the project
- or AEDTZ archive to open or the path to the ``aedb`` folder or
- ``edb.def`` file. The default is ``None``, in which case an
- attempt is made to get an active project. If no projects are present,
- an empty project is created.
- designname : str, optional
- Name of the design to select. The default is ``None``, in
- which case an attempt is made to get an active design. If no
- designs are present, an empty design is created.
- solution_type : str, optional
- Solution type to apply to the design. The default is
- ``None``, in which case the default type is applied.
- setup_name : str, optional
- Name of the setup to use as the nominal. The default is
- ``None``, in which case the active setup is used or
- nothing is used.
- specified_version : str, int, float, optional
- Version of AEDT to use. The default is ``None``, in which case
- the active version or latest installed version is used.
- Examples of input values are ``232``, ``23.2``,``2023.2``,``"2023.2"``.
- non_graphical : bool, optional
- Whether to launch AEDT in non-graphical mode. The default
- is ``False```, in which case AEDT is launched in graphical mode.
- This parameter is ignored when a script is launched within AEDT.
- new_desktop_session : bool, optional
- Whether to launch an instance of AEDT in a new thread, even if
- another instance of the ``specified_version`` is active on the
- machine. The default is ``False``.
- close_on_exit : bool, optional
- Whether to release AEDT on exit. The default is ``False``.
- student_version : bool, optional
- Whether to open the AEDT student version. The default is ``False``.
- machine : str, optional
- Machine name to connect the oDesktop session to. This works only in 2022 R2 or later.
- The remote server must be up and running with the command `"ansysedt.exe -grpcsrv portnum"`.
- If the machine is `"localhost"`. the server also starts if not present.
- port : int, optional
- Port number on which to start the oDesktop communication on an already existing server.
- This parameter is ignored when creating a new server. It works only in 2022 R2 or later.
- The remote server must be up and running with the command `"ansysedt.exe -grpcsrv portnum"`.
- aedt_process_id : int, optional
- Process ID for the instance of AEDT to point PyAEDT at. The default is
- ``None``. This parameter is only used when ``new_desktop_session = False``.
- ic_mode : bool, optional
- Whether to set the design to IC mode or not. The default is ``None``, which means to retain
- the existing setting.
-
- Returns
- -------
- :class:`pyaedt.hfss3dlayout.Hfss3dLayout`
-
- Examples
- --------
- Create an ``Hfss3dLayout`` object and connect to an existing HFSS
- design or create a new HFSS design if one does not exist.
-
- >>> from pyaedt import Hfss3dLayout
- >>> aedtapp = Hfss3dLayout()
-
- Create an ``Hfss3dLayout`` object and link to a project named
- ``projectname``. If this project does not exist, create one with
- this name.
-
- >>> aedtapp = Hfss3dLayout(projectname)
-
- Create an ``Hfss3dLayout`` object and link to a design named
- ``designname`` in a project named ``projectname``.
-
- >>> aedtapp = Hfss3dLayout(projectname,designame)
-
- Create an ``Hfss3dLayout`` object and open the specified project.
-
- >>> aedtapp = Hfss3dLayout("myfile.aedt")
-
- Create an AEDT 2023 R1 object and then create a
- ``Hfss3dLayout`` object and open the specified project.
-
- >>> aedtapp = Hfss3dLayout(specified_version="2023.1", projectname="myfile.aedt")
-
- Create an instance of ``Hfss3dLayout`` from an ``Edb``
-
- >>> import pyaedt
- >>> edb_path = "/path/to/edbfile.aedb"
- >>> edb = pyaedt.Edb(edb_path, edbversion=231)
- >>> edb.stackup.import_stackup("stackup.xml") # Import stackup. Manipulate edb, ...
- >>> edb.save_edb()
- >>> edb.close_edb()
- >>> aedtapp = pyaedt.Hfss3dLayout(specified_version=231, projectname=edb_path)
- """
- from pyaedt.hfss3dlayout import Hfss3dLayout as app
-
- return app(
- projectname=projectname,
- designname=designname,
- solution_type=solution_type,
- setup_name=setup_name,
- specified_version=specified_version,
- non_graphical=non_graphical,
- new_desktop_session=new_desktop_session,
- close_on_exit=close_on_exit,
- student_version=student_version,
- machine=machine,
- port=port,
- aedt_process_id=aedt_process_id,
- ic_mode=ic_mode,
- )
-
-
-def Maxwell2d(
- projectname=None,
- designname=None,
- solution_type=None,
- setup_name=None,
- specified_version=None,
- non_graphical=False,
- new_desktop_session=False,
- close_on_exit=False,
- student_version=False,
- machine="",
- port=0,
- aedt_process_id=None,
-):
- """Maxwell2d Class.
-
- Parameters
- ----------
- projectname : str, optional
- Name of the project to select or the full path to the project
- or AEDTZ archive to open. The default is ``None``, in which
- case an attempt is made to get an active project. If no
- projects are present, an empty project is created.
- designname : str, optional
- Name of the design to select. The default is ``None``, in
- which case an attempt is made to get an active design. If no
- designs are present, an empty design is created.
- solution_type : str, optional
- Solution type to apply to the design. The default is
- ``None``, in which case the default type is applied.
- setup_name : str, optional
- Name of the setup to use as the nominal. The default is
- ``None``, in which case the active setup is used or
- nothing is used.
- specified_version : str, int, float, optional
- Version of AEDT to use. The default is ``None``, in which case
- the active version or latest installed version is used.
- This parameter is ignored when a script is launched within AEDT.
- Examples of input values are ``232``, ``23.2``,``2023.2``,``"2023.2"``.
- non_graphical : bool, optional
- Whether to launch AEDT in non-graphical mode. The default
- is ``False``, in which case AEDT is launched in graphical mode.
- This parameter is ignored when a script is launched within AEDT.
- new_desktop_session : bool, optional
- Whether to launch an instance of AEDT in a new thread, even if
- another instance of the ``specified_version`` is active on the
- machine. The default is ``False``. This parameter is ignored when
- a script is launched within AEDT.
- close_on_exit : bool, optional
- Whether to release AEDT on exit. The default is ``False``.
- student_version : bool, optional
- Whether to open the AEDT student version. The default is ``False``.
- This parameter is ignored when a script is launched within AEDT.
- machine : str, optional
- Machine name to connect the oDesktop session to. This works only in 2022 R2
- or later. The remote server must be up and running with the command
- `"ansysedt.exe -grpcsrv portnum"`. If the machine is `"localhost"`,
- the server also starts if not present.
- port : int, optional
- Port number of which to start the oDesktop communication on an already existing
- server. This parameter is ignored when creating a new server. It works only in 2022
- R2 or later. The remote server must be up and running with the command `"ansysedt.exe -grpcsrv portnum"`.
- aedt_process_id : int, optional
- Process ID for the instance of AEDT to point PyAEDT at. The default is
- ``None``. This parameter is only used when ``new_desktop_session = False``.
-
- Returns
- -------
- :class:`pyaedt.maxwell.Maxwell2d`"""
- from pyaedt.maxwell import Maxwell2d as app
-
- return app(
- projectname=projectname,
- designname=designname,
- solution_type=solution_type,
- setup_name=setup_name,
- specified_version=specified_version,
- non_graphical=non_graphical,
- new_desktop_session=new_desktop_session,
- close_on_exit=close_on_exit,
- student_version=student_version,
- machine=machine,
- port=port,
- aedt_process_id=aedt_process_id,
- )
-
-
-def Maxwell3d(
- projectname=None,
- designname=None,
- solution_type=None,
- setup_name=None,
- specified_version=None,
- non_graphical=False,
- new_desktop_session=False,
- close_on_exit=False,
- student_version=False,
- machine="",
- port=0,
- aedt_process_id=None,
-):
- """Maxwell3d Class.
-
- Parameters
- ----------
- projectname : str, optional
- Name of the project to select or the full path to the project
- or AEDTZ archive to open. The default is ``None``, in which
- case an attempt is made to get an active project. If no
- projects are present, an empty project is created.
- designname : str, optional
- Name of the design to select. The default is ``None``, in
- which case an attempt is made to get an active design. If no
- designs are present, an empty design is created.
- solution_type : str, optional
- Solution type to apply to the design. The default is
- ``None``, in which case the default type is applied.
- setup_name : str, optional
- Name of the setup to use as the nominal. The default is
- ``None``, in which case the active setup is used or
- nothing is used.
- specified_version : str, int, float, optional
- Version of AEDT to use. The default is ``None``, in which case
- the active version or latest installed version is used. This
- parameter is ignored when a script is launched within AEDT.
- Examples of input values are ``232``, ``23.2``,``2023.2``,``"2023.2"``.
- non_graphical : bool, optional
- Whether to launch AEDT in non-graphical mode. The default
- is ``False``, in which case AEDT is launched in graphical
- mode. This parameter is ignored when a script is launched within
- AEDT.
- new_desktop_session : bool, optional
- Whether to launch an instance of AEDT in a new thread, even if
- another instance of the ``specified_version`` is active on the
- machine. The default is ``False``. This parameter is ignored
- when a script is launched within AEDT.
- close_on_exit : bool, optional
- Whether to release AEDT on exit. The default is ``False``.
- student_version : bool, optional
- Whether to open the AEDT student version. The default is
- ``False``. This parameter is ignored when a script is launched
- within AEDT.
- machine : str, optional
- Machine name to connect the oDesktop session to. This works only in 2022 R2
- or later. The remote server must be up and running with the command
- `"ansysedt.exe -grpcsrv portnum"`. If the machine is `"localhost"`, the
- server also starts if not present.
- port : int, optional
- Port number on which to start the oDesktop communication on an already existing server.
- This parameter is ignored when a new server is created. It works only in 2022 R2 or later.
- The remote server must be up and running with the command `"ansysedt.exe -grpcsrv portnum"`.
- aedt_process_id : int, optional
- Process ID for the instance of AEDT to point PyAEDT at. The default is
- ``None``. This parameter is only used when ``new_desktop_session = False``.
-
- Returns
- -------
- :class:`pyaedt.maxwell.Maxwell3d`
-
- Examples
- --------
- Create an instance of Maxwell 3D and open the specified
- project, which is named ``mymaxwell.aedt``.
-
- >>> from pyaedt import Maxwell3d
- >>> aedtapp = Maxwell3d("mymaxwell.aedt")
- PyAEDT INFO: Added design ...
-
- Create an instance of Maxwell 3D using the 2023 R2 release and open
- the specified project, which is named ``mymaxwell2.aedt``.
-
- >>> aedtapp = Maxwell3d(specified_version="2023.2", projectname="mymaxwell2.aedt")
- PyAEDT INFO: Added design ...
- """
- from pyaedt.maxwell import Maxwell3d as app
-
- return app(
- projectname=projectname,
- designname=designname,
- solution_type=solution_type,
- setup_name=setup_name,
- specified_version=specified_version,
- non_graphical=non_graphical,
- new_desktop_session=new_desktop_session,
- close_on_exit=close_on_exit,
- student_version=student_version,
- machine=machine,
- port=port,
- aedt_process_id=aedt_process_id,
- )
-
-
-def MaxwellCircuit(
- projectname=None,
- designname=None,
- solution_type=None,
- specified_version=None,
- non_graphical=False,
- new_desktop_session=False,
- close_on_exit=False,
- student_version=False,
- machine="",
- port=0,
- aedt_process_id=None,
-):
- """MaxwellCircuit Class.
-
- Parameters
- ----------
- projectname : str, optional
- Name of the project to select or the full path to the project
- or AEDTZ archive to open. The default is ``None``, in which
- case an attempt is made to get an active project. If no
- projects are present, an empty project is created.
- designname : str, optional
- Name of the design to select. The default is ``None``, in
- which case an attempt is made to get an active design. If no
- designs are present, an empty design is created.
- specified_version : str, int, float, optional
- Version of AEDT to use. The default is ``None``. If ``None``,
- the active setup is used or the latest installed version is
- used.
- Examples of input values are ``232``, ``23.2``,``2023.2``,``"2023.2"``.
- non-graphical : bool, optional
- Whether to launch AEDT in non-graphical mode. The default
- is ``False``, in which case AEDT is launched in graphical mode.
- This parameter is ignored when a script is launched within AEDT.
- new_desktop_session : bool, optional
- Whether to launch an instance of AEDT in a new thread, even if
- another instance of the ``specified_version`` is active on the
- machine. The default is ``False``.
- close_on_exit : bool, optional
- Whether to release AEDT on exit. The default is ``False``.
- student_version : bool, optional
- Whether to open the AEDT student version. The default is ``False``.
- machine : str, optional
- Machine name to connect the oDesktop session to. This works only in 2022 R2
- and later. The remote server must be up and running with the command
- `"ansysedt.exe -grpcsrv portnum"`. If the machine is `"localhost"`, the server
- is also started if not present.
- port : int, optional
- Port number on which to start the oDesktop communication on an already existing server.
- This parameter is ignored when creating a new server. It works only in 2022 R2 or
- later. The remote server must be up and running with the command `"ansysedt.exe -grpcsrv portnum"`.
- aedt_process_id : int, optional
- Process ID for the instance of AEDT to point PyAEDT at. The default is
- ``None``. This parameter is only used when ``new_desktop_session = False``.
-
- Returns
- -------
- :class:`pyaedt.maxwellcircuit.MaxwellCircuit`"""
- from pyaedt.maxwellcircuit import MaxwellCircuit as app
-
- return app(
- projectname=projectname,
- designname=designname,
- solution_type=solution_type,
- specified_version=specified_version,
- non_graphical=non_graphical,
- new_desktop_session=new_desktop_session,
- close_on_exit=close_on_exit,
- student_version=student_version,
- machine=machine,
- port=port,
- aedt_process_id=aedt_process_id,
- )
-
-
-def Mechanical(
- projectname=None,
- designname=None,
- solution_type=None,
- setup_name=None,
- specified_version=None,
- non_graphical=False,
- new_desktop_session=False,
- close_on_exit=False,
- student_version=False,
- machine="",
- port=0,
- aedt_process_id=None,
-):
- """Mechanical Class.
-
- Parameters
- ----------
- projectname : str, optional
- Name of the project to select or the full path to the project
- or AEDTZ archive to open. The default is ``None``, in which
- case an attempt is made to get an active project. If no
- projects are present, an empty project is created.
- designname : str, optional
- Name of the design to select. The default is ``None``, in
- which case an attempt is made to get an active design. If no
- designs are present, an empty design is created.
- solution_type : str, optional
- Solution type to apply to the design. The default is
- ``None``, in which case the default type is applied.
- setup_name : str, optional
- Name of the setup to use as the nominal. The default is
- ``None``, in which case the active setup is used or
- nothing is used.
- specified_version : str, int, float, optional
- Version of AEDT to use. The default is ``None``, in which case
- the active version or latest installed version is used.
- This parameter is ignored when a script is launched within AEDT.
- Examples of input values are ``232``, ``23.2``,``2023.2``,``"2023.2"``.
- non_graphical : bool, optional
- Whether to launch AEDT in the non-graphical mode. The default
- is ``False``, in which case AEDT is launched in the graphical mode.
- This parameter is ignored when a script is launched within AEDT.
- new_desktop_session : bool, optional
- Whether to launch an instance of AEDT in a new thread, even if
- another instance of the ``specified_version`` is active on the
- machine. The default is ``False``. This parameter is ignored when
- a script is launched within AEDT.
- close_on_exit : bool, optional
- Whether to release AEDT on exit. The default is ``False``.
- student_version : bool, optional
- Whether to open the AEDT student version. The default is ``False``.
- This parameter is ignored when a script is launched within AEDT.
- machine : str, optional
- Machine name to connect the oDesktop session to. Works only in 2022R2 and
- later. The remote server must be up and running with the command
- `"ansysedt.exe -grpcsrv portnum"`. If the machine is `"localhost"`,
- the server also starts if not present.
- port : int, optional
- Port number on which to start the oDesktop communication on an already existing server.
- This parameter is ignored when creating a new server. It works only in 2022 R2 or
- later. The remote server must be up and running with the command `"ansysedt.exe -grpcsrv portnum"`.
- aedt_process_id : int, optional
- Process ID for the instance of AEDT to point PyAEDT at. The default is
- ``None``. This parameter is only used when ``new_desktop_session = False``.
-
- Returns
- -------
- :class:`pyaedt.mechanical.Mechanical`
-
- Examples
- --------
- Create an instance of Mechanical and connect to an existing
- HFSS design or create a new HFSS design if one does not exist.
-
- >>> from pyaedt import Mechanical
- >>> aedtapp = Mechanical()
-
- Create an instance of Mechanical and link to a project named
- ``"projectname"``. If this project does not exist, create one with
- this name.
-
- >>> aedtapp = Mechanical(projectname)
-
- Create an instance of Mechanical and link to a design named
- ``"designname"`` in a project named ``"projectname"``.
-
- >>> aedtapp = Mechanical(projectname,designame)
-
- Create an instance of Mechanical and open the specified
- project, which is named ``"myfile.aedt"``.
-
- >>> aedtapp = Mechanical("myfile.aedt")
-
- Create a ``Desktop on 2023 R2`` object and then create an
- ``Mechanical`` object and open the specified project, which is
- named ``"myfile.aedt"``.
-
- >>> aedtapp = Mechanical(specified_version=23.2, projectname="myfile.aedt")
- """
- from pyaedt.mechanical import Mechanical as app
-
- return app(
- projectname=projectname,
- designname=designname,
- solution_type=solution_type,
- setup_name=setup_name,
- specified_version=specified_version,
- non_graphical=non_graphical,
- new_desktop_session=new_desktop_session,
- close_on_exit=close_on_exit,
- student_version=student_version,
- machine=machine,
- port=port,
- aedt_process_id=aedt_process_id,
- )
-
-
-def Q2d(
- projectname=None,
- designname=None,
- solution_type=None,
- setup_name=None,
- specified_version=None,
- non_graphical=False,
- new_desktop_session=False,
- close_on_exit=False,
- student_version=False,
- machine="",
- port=0,
- aedt_process_id=None,
-):
- """Q2D Class.
-
- Parameters
- ----------
- projectname : str, optional
- Name of the project to select or the full path to the project
- or AEDTZ archive to open. The default is ``None``, in which
- case an attempt is made to get an active project. If no
- projects are present, an empty project is created.
- designname : str, optional
- Name of the design to select. The default is ``None``, in
- which case an attempt is made to get an active design. If no
- designs are present, an empty design is created.
- solution_type : str, optional
- Solution type to apply to the design. The default is
- ``None``, in which case the default type is applied.
- setup_name : str, optional
- Name of the setup to use as the nominal. The default is
- ``None``, in which case the active setup is used or
- nothing is used.
- specified_version : str, int, float, optional
- Version of AEDT to use. The default is ``None``, in which case
- the active version or latest installed version is used. This
- parameter is ignored when a script is launched within AEDT.
- Examples of input values are ``232``, ``23.2``,``2023.2``,``"2023.2"``.
- non_graphical : bool, optional
- Whether to launch AEDT in non-graphical mode. The default
- is ``False``, in which case AEDT is launched in graphical mode.
- This parameter is ignored when a script is launched within AEDT.
- new_desktop_session : bool, optional
- Whether to launch an instance of AEDT in a new thread, even if
- another instance of the ``specified_version`` is active on the
- machine. The default is ``False``. This parameter is ignored
- when a script is launched within AEDT.
- close_on_exit : bool, optional
- Whether to release AEDT on exit. The default is ``False``.
- student_version : bool, optional
- Whether to open the AEDT student version. This parameter is
- ignored when a script is launched within AEDT.
- machine : str, optional
- Machine name to connect the oDesktop session to. This works only in 2022 R2
- and later. The remote server must be up and running with the command
- `"ansysedt.exe -grpcsrv portnum"`. If the machine is `"localhost"`,
- the server also starts if not present.
- port : int, optional
- Port number on which to start the oDesktop communication on an already existing server.
- This parameter is ignored when creating a new server. It works only in 2022 R2 or later.
- The remote server must be up and running with the command `"ansysedt.exe -grpcsrv portnum"`.
- aedt_process_id : int, optional
- Process ID for the instance of AEDT to point PyAEDT at. The default is
- ``None``. This parameter is only used when ``new_desktop_session = False``.
-
- Returns
- -------
- :class:`pyaedt.q3d.Q2d`"""
- from pyaedt.q3d import Q2d as app
-
- return app(
- projectname=projectname,
- designname=designname,
- solution_type=solution_type,
- setup_name=setup_name,
- specified_version=specified_version,
- non_graphical=non_graphical,
- new_desktop_session=new_desktop_session,
- close_on_exit=close_on_exit,
- student_version=student_version,
- machine=machine,
- port=port,
- aedt_process_id=aedt_process_id,
- )
-
-
-def Q3d(
- projectname=None,
- designname=None,
- solution_type=None,
- setup_name=None,
- specified_version=None,
- non_graphical=False,
- new_desktop_session=False,
- close_on_exit=False,
- student_version=False,
- machine="",
- port=0,
- aedt_process_id=None,
-):
- """Q3D Class.
-
- Parameters
- ----------
- projectname : str, optional
- Name of the project to select or the full path to the project
- or AEDTZ archive to open. The default is ``None``, in which
- case an attempt is made to get an active project. If no
- projects are present, an empty project is created.
- designname : str, optional
- Name of the design to select. The default is ``None``, in
- which case an attempt is made to get an active design. If no
- designs are present, an empty design is created.
- solution_type : str, optional
- Solution type to apply to the design. The default is
- ``None``, in which case the default type is applied.
- setup_name : str, optional
- Name of the setup to use as the nominal. The default is
- ``None``, in which case the active setup is used or nothing
- is used.
- specified_version : str, int, float, optional
- Version of AEDT to use. The default is ``None``, in which case
- the active version or latest installed version is used.
- This parameter is ignored when Script is launched within AEDT.
- Examples of input values are ``232``, ``23.2``,``2023.2``,``"2023.2"``.
- non_graphical : bool, optional
- Whether to launch AEDT in non-graphical mode. The default
- is ``False``, in which case AEDT is launched in graphical mode.
- This parameter is ignored when a script is launched within AEDT.
- new_desktop_session : bool, optional
- Whether to launch an instance of AEDT in a new thread, even if
- another instance of the ``specified_version`` is active on the
- machine. The default is ``False``. This parameter is ignored when
- a script is launched within AEDT.
- close_on_exit : bool, optional
- Whether to release AEDT on exit. The default is ``False``.
- student_version : bool, optional
- Whether to open the AEDT student version. The default is ``False``.
- This parameter is ignored when a script is launched within AEDT.
- machine : str, optional
- Machine name to connect the oDesktop session to. This works only in
- 2022 R2 and later. The remote server must be up and running with the
- command `"ansysedt.exe -grpcsrv portnum"`. If the machine is `"localhost"`,
- the server also starts if not present.
- port : int, optional
- Port number on which to start the oDesktop communication on an already
- existing server. This parameter is ignored when a new server is created.
- It works only in 2022 R2 and later. The remote server must be up and
- running with the command `"ansysedt.exe -grpcsrv portnum"`.
- aedt_process_id : int, optional
- Process ID for the instance of AEDT to point PyAEDT at. The default is
- ``None``. This parameter is only used when ``new_desktop_session = False``.
-
- Returns
- -------
- :class:`pyaedt.q3d.Q3d`"""
- from pyaedt.q3d import Q3d as app
-
- return app(
- projectname=projectname,
- designname=designname,
- solution_type=solution_type,
- setup_name=setup_name,
- specified_version=specified_version,
- non_graphical=non_graphical,
- new_desktop_session=new_desktop_session,
- close_on_exit=close_on_exit,
- student_version=student_version,
- machine=machine,
- port=port,
- aedt_process_id=aedt_process_id,
- )
-
-
-def Rmxprt(
- projectname=None,
- designname=None,
- solution_type=None,
- setup_name=None,
- specified_version=None,
- non_graphical=False,
- new_desktop_session=False,
- close_on_exit=False,
- student_version=False,
- machine="",
- port=0,
- aedt_process_id=None,
-):
- """Rmxprt Class.
-
- Parameters
- ----------
- projectname : str, optional
- Name of the project to select or the full path to the project
- or AEDTZ archive to open. The default is ``None``, in which
- case an attempt is made to get an active project. If no
- projects are present, an empty project is created.
- designname : str, optional
- Name of the design to select. The default is ``None``, in
- which case an attempt is made to get an active design. If no
- designs are present, an empty design is created.
- solution_type : str, optional
- Solution type to apply to the design. The default is
- ``None``, in which case the default type is applied.
- setup_name : str, optional
- Name of the setup to use as the nominal. The default is
- ``None``, in which case the active setup is used or
- nothing is used.
- specified_version : str, int, float, optional
- Version of AEDT to use. The default is ``None``, in which case
- the active setup is used or the latest installed version is
- used.
- Examples of input values are ``232``, ``23.2``,``2023.2``,``"2023.2"``.
- non_graphical : bool, optional
- Whether to launch AEDT in non-graphical mode. The default
- is ``False``, in which case AEDT is launched in graphical mode.
- This parameter is ignored when a script is launched within AEDT.
- new_desktop_session : bool, optional
- Whether to launch an instance of AEDT in a new thread, even if
- another instance of the ``specified_version`` is active on the
- machine. The default is ``False``.
- close_on_exit : bool, optional
- Whether to release AEDT on exit. The default is ``False``.
- student_version : bool, optional
- Whether to open the AEDT student version. The default is ``False``.
- machine : str, optional
- Machine name to connect the oDesktop session to. This works only in 2022 R2 or
- later. The remote server must be up and running with the command
- `"ansysedt.exe -grpcsrv portnum"`. If the machine is `"localhost"`, the
- server also starts if not present.
- port : int, optional
- Port number on which to start the oDesktop communication on an already existing server.
- This parameter is ignored when creating a new server. It works only in 2022 R2 or later.
- The remote server must be up and running with the command `"ansysedt.exe -grpcsrv portnum"`.
- aedt_process_id : int, optional
- Process ID for the instance of AEDT to point PyAEDT at. The default is
- ``None``. This parameter is only used when ``new_desktop_session = False``.
-
- Returns
- -------
- :class:`pyaedt.rmxprt.Rmxprt`"""
- from pyaedt.rmxprt import Rmxprt as app
-
- return app(
- projectname=projectname,
- designname=designname,
- solution_type=solution_type,
- setup_name=setup_name,
- specified_version=specified_version,
- non_graphical=non_graphical,
- new_desktop_session=new_desktop_session,
- close_on_exit=close_on_exit,
- student_version=student_version,
- machine=machine,
- port=port,
- aedt_process_id=aedt_process_id,
- )
-
-
-def TwinBuilder(
- projectname=None,
- designname=None,
- solution_type=None,
- setup_name=None,
- specified_version=None,
- non_graphical=False,
- new_desktop_session=False,
- close_on_exit=False,
- student_version=False,
- machine="",
- port=0,
- aedt_process_id=None,
-):
- """TwinBuilder Class.
-
- Parameters
- ----------
- projectname : str, optional
- Name of the project to select or the full path to the project
- or AEDTZ archive to open. The default is ``None``, in which
- case an attempt is made to get an active project. If no
- projects are present, an empty project is created.
- designname : str, optional
- Name of the design to select. The default is ``None``, in
- which case an attempt is made to get an active design. If no
- designs are present, an empty design is created.
- solution_type : str, optional
- Solution type to apply to the design. The default is
- ``None``, in which case the default type is applied.
- setup_name : str, optional
- Name of the setup to use as the nominal. The default is
- ``None``, in which case the active setup is used or
- nothing is used.
- specified_version : str, int, float, optional
- Version of AEDT to use. The default is ``None``, in which
- case the active setup or latest installed version is
- used.
- Examples of input values are ``232``, ``23.2``,``2023.2``,``"2023.2"``.
- non_graphical : bool, optional
- Whether to launch AEDT in non-graphical mode. The default
- is ``False``, in which case AEDT is launched in graphical mode.
- This parameter is ignored when a script is launched within AEDT.
- new_desktop_session : bool, optional
- Whether to launch an instance of AEDT in a new thread, even if
- another instance of the ``specified_version`` is active on the
- machine. The default is ``False``.
- close_on_exit : bool, optional
- Whether to release AEDT on exit. The default is ``False``.
- student_version : bool, optional
- Whether to open the AEDT student version. The default is ``False``.
- machine : str, optional
- Machine name to connect the oDesktop session to. This works only in 2022 R2
- or later. The remote server must be up and running with the command
- `"ansysedt.exe -grpcsrv portnum"`. If the machine is `"localhost"`,
- the server also starts if not present.
- port : int, optional
- Port number on which to start the oDesktop communication on an already existing server.
- This parameter is ignored when creating a new server. It works only in 2022 R2 or later.
- The remote server must be up and running with command `"ansysedt.exe -grpcsrv portnum"`.
- aedt_process_id : int, optional
- Process ID for the instance of AEDT to point PyAEDT at. The default is
- ``None``. This parameter is only used when ``new_desktop_session = False``.
-
- Returns
- -------
- :class:`pyaedt.twinbuilder.TwinBuilder`"""
- from pyaedt.twinbuilder import TwinBuilder as app
-
- return app(
- projectname=projectname,
- designname=designname,
- solution_type=solution_type,
- setup_name=setup_name,
- specified_version=specified_version,
- non_graphical=non_graphical,
- new_desktop_session=new_desktop_session,
- close_on_exit=close_on_exit,
- student_version=student_version,
- machine=machine,
- port=port,
- aedt_process_id=aedt_process_id,
- )
-
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
-def Simplorer(
- projectname=None,
- designname=None,
- solution_type=None,
- setup_name=None,
- specified_version=None,
- non_graphical=False,
- new_desktop_session=False,
- close_on_exit=False,
- student_version=False,
- machine="",
- port=0,
- aedt_process_id=None,
-):
- """Simplorer Class.
-
- Parameters
- ----------
- projectname : str, optional
- Name of the project to select or the full path to the project
- or AEDTZ archive to open. The default is ``None``, in which
- case an attempt is made to get an active project. If no
- projects are present, an empty project is created.
- designname : str, optional
- Name of the design to select. The default is ``None``, in
- which case an attempt is made to get an active design. If no
- designs are present, an empty design is created.
- solution_type : str, optional
- Solution type to apply to the design. The default is
- ``None``, in which case the default type is applied.
- setup_name : str, optional
- Name of the setup to use as the nominal. The default is
- ``None``, in which case the active setup is used or
- nothing is used.
- specified_version : str, int, float, optional
- Version of AEDT to use. The default is ``None``, in which
- case the active setup or latest installed version is
- used.
- Examples of input values are ``232``, ``23.2``,``2023.2``,``"2023.2"``.
- non_graphical : bool, optional
- Whether to launch AEDT in non-graphical mode. The default
- is ``False``, in which case AEDT is launched in graphical mode.
- This parameter is ignored when a script is launched within AEDT.
- new_desktop_session : bool, optional
- Whether to launch an instance of AEDT in a new thread, even if
- another instance of the ``specified_version`` is active on the
- machine. The default is ``False``.
- close_on_exit : bool, optional
- Whether to release AEDT on exit. The default is ``False``.
- student_version : bool, optional
- Whether to open the AEDT student version. The default is ``False``.
- machine : str, optional
- Machine name to connect the oDesktop session to. This works only in 2022 R2
- or later. The remote server must be up and running with the command
- `"ansysedt.exe -grpcsrv portnum"`. If the machine is `"localhost"`,
- the server also starts if not present.
- port : int, optional
- Port number on which to start the oDesktop communication on an already existing server.
- This parameter is ignored when creating a new server. It works only in 2022 R2 or later.
- The remote server must be up and running with command `"ansysedt.exe -grpcsrv portnum"`.
- aedt_process_id : int, optional
- Process ID for the instance of AEDT to point PyAEDT at. The default is
- ``None``. This parameter is only used when ``new_desktop_session = False``.
-
- Returns
- -------
- :class:`pyaedt.twinbuilder.TwinBuilder`"""
- from pyaedt.twinbuilder import TwinBuilder as app
-
- return app(
- projectname=projectname,
- designname=designname,
- solution_type=solution_type,
- setup_name=setup_name,
- specified_version=specified_version,
- non_graphical=non_graphical,
- new_desktop_session=new_desktop_session,
- close_on_exit=close_on_exit,
- student_version=student_version,
- machine=machine,
- port=port,
- aedt_process_id=aedt_process_id,
- )
-
-
-def Desktop(
- specified_version=None,
- non_graphical=False,
- new_desktop_session=True,
- close_on_exit=True,
- student_version=False,
- machine="",
- port=0,
- aedt_process_id=None,
-):
- """Desktop Class.
- Parameters
- ----------
- specified_version : str, int, float, optional
- Version of AEDT to use. The default is ``None``, in which case the
- active setup or latest installed version is used.
- Examples of input values are ``232``, ``23.2``,``2023.2``,``"2023.2"``.
- non_graphical : bool, optional
- Whether to launch AEDT in non-graphical mode. The default
- is ``False``, in which case AEDT is launched in graphical mode.
- This parameter is ignored when a script is launched within AEDT.
- new_desktop_session : bool, optional
- Whether to launch an instance of AEDT in a new thread, even if
- another instance of the ``specified_version`` is active on the machine.
- The default is ``True``.
- close_on_exit : bool, optional
- Whether to close AEDT on exit. The default is ``True``.
- This option is used only when Desktop is used in a context manager (``with`` statement).
- If Desktop is used outside a context manager, see the ``release_desktop`` arguments.
- student_version : bool, optional
- Whether to open the AEDT student version. The default is
- ``False``.
- machine : str, optional
- Machine name to connect the oDesktop session to. This parameter works only in 2022 R2
- and later. The remote server must be up and running with the command
- `"ansysedt.exe -grpcsrv portnum"`. If the machine is `"localhost"`, the server also
- starts if not present.
- port : int, optional
- Port number on which to start the oDesktop communication on the already existing server.
- This parameter is ignored when creating a new server. It works only in 2022 R2 and
- later. The remote server must be up and running with the command `"ansysedt.exe -grpcsrv portnum"`.
- aedt_process_id : int, optional
- Process ID for the instance of AEDT to point PyAEDT at. The default is
- ``None``. This parameter is only used when ``new_desktop_session = False``.
-
- Returns
- -------
- :class:`pyaedt.desktop.Desktop`
-
- Examples
- --------
- Launch AEDT 2023 R1 in non-graphical mode and initialize HFSS.
-
- >>> import pyaedt
- >>> desktop = pyaedt.Desktop(specified_version="2023.2", non_graphical=True)
- PyAEDT INFO: pyaedt v...
- PyAEDT INFO: Python version ...
- >>> hfss = pyaedt.Hfss(designname="HFSSDesign1")
- PyAEDT INFO: Project...
- PyAEDT INFO: Added design 'HFSSDesign1' of type HFSS.
+import re
+import sys
+import time
- Launch AEDT 2023 R2 in graphical mode and initialize HFSS.
+from pyaedt.circuit import Circuit
+from pyaedt.desktop import Desktop
- >>> desktop = Desktop(232)
- PyAEDT INFO: pyaedt v...
- PyAEDT INFO: Python version ...
- >>> hfss = pyaedt.Hfss(designname="HFSSDesign1")
- PyAEDT INFO: No project is defined. Project...
- """
- from pyaedt.desktop import Desktop as app
+Emit = None
+if not ("IronPython" in sys.version or ".NETFramework" in sys.version): # pragma: no cover
+ from pyaedt.emit import Emit
+from pyaedt.generic.general_methods import is_linux
+from pyaedt.generic.settings import settings
+from pyaedt.hfss3dlayout import Hfss3dLayout
+from pyaedt.hfss import Hfss
+from pyaedt.icepak import Icepak
+from pyaedt.maxwell import Maxwell2d
+from pyaedt.maxwell import Maxwell3d
+from pyaedt.maxwellcircuit import MaxwellCircuit
+from pyaedt.mechanical import Mechanical
+from pyaedt.q3d import Q2d
+from pyaedt.q3d import Q3d
+from pyaedt.rmxprt import Rmxprt
+from pyaedt.twinbuilder import TwinBuilder
- return app(
- specified_version=specified_version,
- non_graphical=non_graphical,
- new_desktop_session=new_desktop_session,
- close_on_exit=close_on_exit,
- student_version=student_version,
- machine=machine,
- port=port,
- aedt_process_id=aedt_process_id,
- )
+Simplorer = TwinBuilder
def launch_desktop(
- specified_version=None,
+ version=None,
non_graphical=False,
- new_desktop_session=True,
+ new_desktop=True,
close_on_exit=True,
student_version=False,
machine="",
@@ -1562,14 +63,14 @@ def launch_desktop(
Parameters
----------
- specified_version : str, int, float, optional
+ version : str, int, float, optional
Version of AEDT to use. The default is ``None``, in which case the
active setup or latest installed version is used.
non_graphical : bool, optional
Whether to launch AEDT in non-graphical mode. The default
is ``False``, in which case AEDT is launched in graphical mode.
This parameter is ignored when a script is launched within AEDT.
- new_desktop_session : bool, optional
+ new_desktop : bool, optional
Whether to launch an instance of AEDT in a new thread, even if
another instance of the ``specified_version`` is active on the machine.
The default is ``False``.
@@ -1589,7 +90,7 @@ def launch_desktop(
later. The remote server must be up and running with the command `"ansysedt.exe -grpcsrv portnum"`.
aedt_process_id : int, optional
Process ID for the instance of AEDT to point PyAEDT at. The default is
- ``None``. This parameter is only used when ``new_desktop_session = False``.
+ ``None``. This parameter is only used when ``new_desktop = False``.
Returns
-------
@@ -1604,7 +105,7 @@ def launch_desktop(
>>> desktop = pyaedt.launch_desktop("2022.2", non_graphical=True)
PyAEDT INFO: pyaedt v...
PyAEDT INFO: Python version ...
- >>> hfss = pyaedt.Hfss(designname="HFSSDesign1")
+ >>> hfss = pyaedt.Hfss(design="HFSSDesign1")
PyAEDT INFO: Project...
PyAEDT INFO: Added design 'HFSSDesign1' of type HFSS.
@@ -1613,13 +114,13 @@ def launch_desktop(
>>> desktop = Desktop("2021.2")
PyAEDT INFO: pyaedt v...
PyAEDT INFO: Python version ...
- >>> hfss = pyaedt.Hfss(designname="HFSSDesign1")
+ >>> hfss = pyaedt.Hfss(design="HFSSDesign1")
PyAEDT INFO: No project is defined. Project...
"""
d = Desktop(
- specified_version=specified_version,
+ version=version,
non_graphical=non_graphical,
- new_desktop_session=new_desktop_session,
+ new_desktop=new_desktop,
close_on_exit=close_on_exit,
student_version=student_version,
machine=machine,
@@ -1629,110 +130,6 @@ def launch_desktop(
return d
-def Edb(
- edbpath=None,
- cellname=None,
- isreadonly=False,
- edbversion=None,
- isaedtowned=False,
- oproject=None,
- student_version=False,
- use_ppe=False,
- technology_file=None,
-):
- """Provides the EDB application interface.
-
- This module inherits all objects that belong to EDB.
-
- Parameters
- ----------
- edbpath : str, int, float optional
- Full path to the ``aedb`` folder. The variable can also contain
- the path to a layout to import. Allowed formats are BRD,
- XML (IPC2581), GDS, and DXF. The default is ``None``.
- For GDS import, the Ansys control file (also XML) should have the same
- name as the GDS file. Only the file extension differs.
- cellname : str, optional
- Name of the cell to select. The default is ``None``.
- isreadonly : bool, optional
- Whether to open EBD in read-only mode when it is
- owned by HFSS 3D Layout. The default is ``False``.
- edbversion : str, optional
- Version of EDB to use. The default is ``"2021.2"``.
- isaedtowned : bool, optional
- Whether to launch EDB from HFSS 3D Layout. The
- default is ``False``.
- oproject : optional
- Reference to the AEDT project object.
- student_version : bool, optional
- Whether to open the AEDT student version. The default is ``False.``
- technology_file : str, optional
- Full path to technology file to be converted to xml before importing or xml. Supported by GDS format only.
-
- Returns
- -------
- :class:`pyaedt.edb.Edb`
-
- Examples
- --------
- Create an ``Edb`` object and a new EDB cell.
-
- >>> from pyaedt import Edb
- >>> app = Edb()
-
- Add a new variable named "s1" to the ``Edb`` instance.
-
- >>> app['s1'] = "0.25 mm"
- >>> app['s1'].tofloat
- >>> 0.00025
- >>> app['s1'].tostring
- >>> "0.25mm"
-
- or add a new parameter with description:
-
- >>> app['s2'] = ["20um", "Spacing between traces"]
- >>> app['s2'].value
- >>> 1.9999999999999998e-05
- >>> app['s2'].description
- >>> 'Spacing between traces'
-
-
- Create an ``Edb`` object and open the specified project.
-
- >>> app = Edb("myfile.aedb")
-
- Create an ``Edb`` object from GDS and control files.
- The XML control file resides in the same directory as the GDS file: (myfile.xml).
-
- >>> app = Edb("/path/to/file/myfile.gds")
-
- """
- from pyedb import Edb as app
-
- return app(
- edbpath=edbpath,
- cellname=cellname,
- isreadonly=isreadonly,
- edbversion=edbversion,
- isaedtowned=isaedtowned,
- oproject=oproject,
- student_version=student_version,
- use_ppe=use_ppe,
- technology_file=technology_file,
- )
-
-
-def Siwave(
- specified_version=None,
-):
- """Siwave Class."""
- from pyedb.siwave import Siwave as app
-
- return app(
- specified_version=specified_version,
- )
-
-
app_map = {
"Maxwell 2D": Maxwell2d,
"Maxwell 3D": Maxwell3d,
@@ -1747,9 +144,6 @@ def Siwave(
"Rmxprt": Rmxprt,
"HFSS 3D Layout Design": Hfss3dLayout,
"EMIT": Emit,
- "EDB": Edb,
- "Desktop": Desktop,
- "Siwave": Siwave,
}
@@ -1821,5 +215,5 @@ def get_pyaedt_app(project_name=None, design_name=None, desktop=None):
if design_type in list(app_map.keys()):
version = odesktop.GetVersion().split(".")
v = ".".join([version[0], version[1]])
- return app_map[design_type](project_name, design_name, specified_version=v, aedt_process_id=process_id)
+ return app_map[design_type](project_name, design_name, version=v, aedt_process_id=process_id)
return None
diff --git a/pyaedt/generic/desktop_sessions.py b/pyaedt/generic/desktop_sessions.py
index 87032cbae18..d348a47d551 100644
--- a/pyaedt/generic/desktop_sessions.py
+++ b/pyaedt/generic/desktop_sessions.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
# This contains the Desktops database.
# When AEDT will support multiple desktops, it will be filled with additional properties and methods
diff --git a/pyaedt/generic/filesystem.py b/pyaedt/generic/filesystem.py
index 694351b7a6d..06f206e3f98 100644
--- a/pyaedt/generic/filesystem.py
+++ b/pyaedt/generic/filesystem.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import os
import random
import shutil
@@ -124,9 +148,7 @@ def copyfolder(self, src_folder, destfolder):
-------
"""
- from distutils.dir_util import copy_tree
-
- copy_tree(src_folder, destfolder)
+ shutil.copytree(src_folder, destfolder, dirs_exist_ok=True)
return True
def __enter__(self):
diff --git a/pyaedt/generic/general_methods.py b/pyaedt/generic/general_methods.py
index c3569028787..7d06b7d67cc 100644
--- a/pyaedt/generic/general_methods.py
+++ b/pyaedt/generic/general_methods.py
@@ -1,4 +1,27 @@
# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
from __future__ import absolute_import
import ast
@@ -25,6 +48,7 @@
from pyaedt.aedt_logger import pyaedt_logger
from pyaedt.generic.constants import CSS4_COLORS
from pyaedt.generic.settings import settings
+from pyaedt.misc.misc import installed_versions
is_ironpython = "IronPython" in sys.version or ".NETFramework" in sys.version
is_linux = os.name == "posix"
@@ -34,6 +58,16 @@
if not is_ironpython:
import psutil
+inclusion_list = [
+ "CreateVia",
+ "PasteDesign",
+ "Paste",
+ "PushExcitations",
+ "Rename",
+ "RestoreProjectArchive",
+ "ImportGerber",
+]
+
class GrpcApiError(Exception):
""" """
@@ -195,6 +229,8 @@ def raise_exception_or_return_false(e):
for v in list(_desktop_sessions.values())[:]:
v.release_desktop(v.launched_by_pyaedt, v.launched_by_pyaedt)
raise e
+ elif "__init__" in str(e): # pragma: no cover
+ return
else:
return False
@@ -810,15 +846,6 @@ def _retry_ntimes(n, function, *args, **kwargs):
pyaedt_logger.debug("An error occurred while accessing the arguments of a function " "called multiple times.")
retry = 0
ret_val = None
- inclusion_list = [
- "CreateVia",
- "PasteDesign",
- "Paste",
- "PushExcitations",
- "Rename",
- "RestoreProjectArchive",
- "ImportGerber",
- ]
# if func_name and func_name not in inclusion_list and not func_name.startswith("Get"):
if func_name and func_name not in inclusion_list:
n = 1
@@ -944,6 +971,73 @@ def is_project_locked(project_path):
return check_if_path_exists(project_path + ".lock")
+@pyaedt_function_handler()
+def is_license_feature_available(feature="electronics_desktop", count=1): # pragma: no cover
+ """Check if license feature is available.
+
+ Parameters
+ ----------
+ feature : str
+ Feature increment name. The default is the electronics desktop one.
+ count : int
+ Number of increments of the same feature available.
+
+ Returns
+ -------
+ bool
+ ``True`` when feature available, ``False`` when feature not available.
+ """
+ import subprocess # nosec B404
+
+ aedt_install_folder = list(installed_versions().values())[0]
+
+ if is_linux:
+ ansysli_util_path = os.path.join(aedt_install_folder, "licensingclient", "linx64", "ansysli_util")
+ else:
+ ansysli_util_path = os.path.join(aedt_install_folder, "licensingclient", "winx64", "ansysli_util")
+ my_env = os.environ.copy()
+
+ tempfile_status = tempfile.NamedTemporaryFile(suffix=".txt", delete=False).name
+ tempfile_checkout = tempfile.NamedTemporaryFile(suffix=".txt", delete=False).name
+
+ # License server status
+ cmd = [ansysli_util_path, "-statli"]
+
+ f = open(tempfile_status, "w")
+
+ subprocess.Popen(cmd, stdout=f, stderr=f, env=my_env).wait() # nosec
+
+ f.close()
+
+ is_server_down = False
+ with open_file(tempfile_status, "r") as f:
+ for line in f:
+ if line == "ansysli_server process could not be found.\n":
+ is_server_down = True
+ break
+
+ if is_server_down:
+ pyaedt_logger.warning("License server process could not be found.")
+ return False
+
+ cmd = [ansysli_util_path, "-checkcount", str(count), "-checkout", feature]
+
+ f = open(tempfile_checkout, "w")
+
+ subprocess.Popen(cmd, stdout=f, stderr=f, env=my_env).wait() # nosec
+
+ f.close()
+
+ checkout_lines = []
+ with open_file(tempfile_checkout, "r") as f:
+ for line in f:
+ checkout_lines.append(line)
+ if "CHECKOUT FAILED" in checkout_lines[1] or len(checkout_lines) != 2:
+ pyaedt_logger.warning(checkout_lines[0])
+ return False
+ return True
+
+
@pyaedt_function_handler()
def remove_project_lock(project_path):
"""Check if an AEDT project exists and try to remove the lock file.
@@ -1681,9 +1775,9 @@ def conversion_function(data, function=None): # pragma: no cover
return data
-@pyaedt_function_handler()
+@pyaedt_function_handler(file_name="input_file")
def parse_excitation_file(
- file_name,
+ input_file,
is_time_domain=True,
x_scale=1,
y_scale=1,
@@ -1697,7 +1791,7 @@ def parse_excitation_file(
Parameters
----------
- file_name : str
+ input_file : str
Full name of the input file.
is_time_domain : bool, optional
Either if the input data is Time based or Frequency Based. Frequency based data are Mag/Phase (deg).
@@ -1726,7 +1820,7 @@ def parse_excitation_file(
except ImportError:
pyaedt_logger.error("NumPy is not available. Install it.")
return False
- df = read_csv_pandas(file_name, encoding=encoding)
+ df = read_csv_pandas(input_file, encoding=encoding)
if is_time_domain:
time = df[df.keys()[0]].values * x_scale
val = df[df.keys()[1]].values * y_scale
diff --git a/pyaedt/generic/grpc_plugin_dll_class.py b/pyaedt/generic/grpc_plugin_dll_class.py
index 41104c659aa..f9504503aa0 100644
--- a/pyaedt/generic/grpc_plugin_dll_class.py
+++ b/pyaedt/generic/grpc_plugin_dll_class.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
from ctypes import CFUNCTYPE
from ctypes import PyDLL
from ctypes import c_bool
@@ -12,6 +36,7 @@
from pyaedt.generic.general_methods import GrpcApiError
from pyaedt.generic.general_methods import _retry_ntimes
+from pyaedt.generic.general_methods import inclusion_list
from pyaedt.generic.general_methods import settings
logger = settings.logger
@@ -88,7 +113,7 @@ def __Invoke__(self, funcName, argv):
if settings.enable_debug_grpc_api_logger:
settings.logger.debug("{} {}".format(funcName, argv))
try:
- if settings.use_multi_desktop and funcName not in exclude_list:
+ if (settings.use_multi_desktop and funcName not in exclude_list) or funcName in inclusion_list:
self.dllapi.recreate_application(True)
ret = _retry_ntimes(
settings.number_of_grpc_api_retries,
@@ -294,6 +319,7 @@ def __init__(self, pathDir):
self.AedtAPI = AedtAPI
self.SetPyObjCalbacks()
self.aedt = None
+ self.non_graphical = False
def SetPyObjCalbacks(self):
self.callback_type = CFUNCTYPE(py_object, c_int, c_bool, py_object)
@@ -330,6 +356,7 @@ def CreateAedtApplication(self, machine="", port=0, NGmode=False, alwaysNew=True
if not self.aedt:
raise GrpcApiError("Failed to connect to Desktop Session")
self.machine = machine
+ self.non_graphical = NGmode
if port == 0:
self.port = self.aedt.GetAppDesktop().GetGrpcServerPort()
else:
@@ -351,7 +378,7 @@ def run():
self.__init__(self.original_path)
self.port = port
self.machine = machine
- self.aedt = self.AedtAPI.CreateAedtApplication(self.machine, self.port, False, False)
+ self.aedt = self.AedtAPI.CreateAedtApplication(self.machine, self.port, self.non_graphical, False)
return self.aedt
if force:
diff --git a/pyaedt/generic/ibis_reader.py b/pyaedt/generic/ibis_reader.py
index bbc4bc29698..25bd8078a4d 100644
--- a/pyaedt/generic/ibis_reader.py
+++ b/pyaedt/generic/ibis_reader.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import json
import os
import re
diff --git a/pyaedt/generic/near_field_import.py b/pyaedt/generic/near_field_import.py
index 34c403a2455..fa27440a399 100644
--- a/pyaedt/generic/near_field_import.py
+++ b/pyaedt/generic/near_field_import.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import csv
import os
import re
diff --git a/pyaedt/generic/pdf.py b/pyaedt/generic/pdf.py
index e9d7fb9b2c2..64cc29b29bb 100644
--- a/pyaedt/generic/pdf.py
+++ b/pyaedt/generic/pdf.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
from dataclasses import dataclass
from dataclasses import field
import json
diff --git a/pyaedt/generic/plot.py b/pyaedt/generic/plot.py
index a2ed87de43e..549f7550a6c 100644
--- a/pyaedt/generic/plot.py
+++ b/pyaedt/generic/plot.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import ast
from collections import defaultdict
import csv
@@ -8,11 +32,11 @@
import time
import warnings
-from pyaedt import pyaedt_function_handler
from pyaedt.generic.constants import AEDT_UNITS
from pyaedt.generic.constants import CSS4_COLORS
from pyaedt.generic.general_methods import is_ironpython
from pyaedt.generic.general_methods import open_file
+from pyaedt.generic.general_methods import pyaedt_function_handler
if not is_ironpython:
try:
@@ -469,8 +493,9 @@ def plot_2d_chart(
Matplotlib figure object.
"""
dpi = 100.0
- figsize = (size[0] / dpi, size[1] / dpi)
- fig, ax = plt.subplots(figsize=figsize)
+ ax = plt.subplot(111)
+ fig = plt.gcf()
+ fig.set_size_inches(size[0] / dpi, size[1] / dpi)
label_id = 1
for plo_obj in plot_data:
if isinstance(plo_obj[0], np.ndarray):
@@ -479,7 +504,10 @@ def plot_2d_chart(
else:
x = np.array([i for i, j in zip(plo_obj[0], plo_obj[1]) if j])
y = np.array([i for i in plo_obj[1] if i])
- ax.plot(x, y)
+ label = "Plot {}".format(str(label_id))
+ if len(plo_obj) > 2:
+ label = plo_obj[2]
+ ax.plot(x, y, label=label)
label_id += 1
ax.set(xlabel=xlabel, ylabel=ylabel, title=title)
@@ -488,7 +516,7 @@ def plot_2d_chart(
if snapshot_path:
fig.savefig(snapshot_path)
- elif not is_notebook():
+ elif show and not is_notebook():
fig.show()
return fig
diff --git a/pyaedt/generic/python_optimizers.py b/pyaedt/generic/python_optimizers.py
index 2d0bf18df25..57ac916e7cc 100644
--- a/pyaedt/generic/python_optimizers.py
+++ b/pyaedt/generic/python_optimizers.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import sys
import threading
import warnings
diff --git a/pyaedt/generic/report_file_parser.py b/pyaedt/generic/report_file_parser.py
index 55c2467e560..1a45b3cd21b 100644
--- a/pyaedt/generic/report_file_parser.py
+++ b/pyaedt/generic/report_file_parser.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
from pyaedt.generic.LoadAEDTFile import load_keyword_in_aedt_file
from pyaedt.generic.constants import SI_UNITS
from pyaedt.generic.constants import unit_system
diff --git a/pyaedt/generic/settings.py b/pyaedt/generic/settings.py
index 40e962b3a8b..7c23d27251a 100644
--- a/pyaedt/generic/settings.py
+++ b/pyaedt/generic/settings.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import os
import time
@@ -73,7 +97,7 @@ def __init__(self):
self._retry_n_times_time_interval = 0.1
self._wait_for_license = False
self.__lazy_load = True
- self.__objects_lazy_load = False
+ self.__objects_lazy_load = True
@property
def release_on_exception(self):
diff --git a/pyaedt/generic/spisim.py b/pyaedt/generic/spisim.py
index df5f1910880..5203dfdb230 100644
--- a/pyaedt/generic/spisim.py
+++ b/pyaedt/generic/spisim.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
# coding=utf-8
from collections import OrderedDict
import os
@@ -9,13 +33,13 @@
from numpy import float64
from numpy import zeros
-from pyaedt import generate_unique_folder_name
from pyaedt import generate_unique_name
-from pyaedt import is_linux
-from pyaedt import pyaedt_function_handler
-from pyaedt import settings
from pyaedt.generic.general_methods import env_value
+from pyaedt.generic.general_methods import generate_unique_folder_name
from pyaedt.generic.general_methods import open_file
+from pyaedt.generic.general_methods import pyaedt_function_handler
+from pyaedt.generic.settings import is_linux
+from pyaedt.generic.settings import settings
from pyaedt.misc import current_version
from pyaedt.misc.spisim_com_configuration_files.com_parameters import COMParametersVer3p4
diff --git a/pyaedt/generic/touchstone_parser.py b/pyaedt/generic/touchstone_parser.py
index e70e07fc381..bed51504ac1 100644
--- a/pyaedt/generic/touchstone_parser.py
+++ b/pyaedt/generic/touchstone_parser.py
@@ -1,10 +1,34 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
from copy import copy
import itertools
import os
import re
import subprocess
-from pyaedt import is_ironpython
+from pyaedt.generic.general_methods import is_ironpython
from pyaedt.misc.misc import installed_versions
if not is_ironpython:
diff --git a/pyaedt/hfss.py b/pyaedt/hfss.py
index ecd98a0ca37..40590f4131b 100644
--- a/pyaedt/hfss.py
+++ b/pyaedt/hfss.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
"""This module contains these classes: ``Hfss`` and ``BoundaryType``."""
from __future__ import absolute_import # noreorder
@@ -40,12 +64,12 @@ class Hfss(FieldAnalysis3D, ScatteringMethods):
Parameters
----------
- projectname : str, optional
+ project : str, optional
Name of the project to select or the full path to the project
or AEDTZ archive to open. The default is ``None``, in which
case an attempt is made to get an active project. If no
projects are present, an empty project is created.
- designname : str, optional
+ design : str, optional
Name of the design to select. The default is ``None``, in
which case an attempt is made to get an active design. If no
designs are present, an empty design is created.
@@ -61,11 +85,11 @@ class Hfss(FieldAnalysis3D, ScatteringMethods):
- "Transient"
- "Eigenmode"
- setup_name : str, optional
+ setup : str, optional
Name of the setup to use as the nominal. The default is
``None``, in which case the active setup is used or
nothing is used.
- specified_version : str, int, float, optional
+ version : str, int, float, optional
Version of AEDT to use. The default is ``None``, in which case
the active version or latest installed version is used.
This parameter is ignored when a script is launched within AEDT.
@@ -74,7 +98,7 @@ class Hfss(FieldAnalysis3D, ScatteringMethods):
Whether to run AEDT in non-graphical mode. The default
is ``False``, in which case AEDT is launched in graphical mode.
This parameter is ignored when a script is launched within AEDT.
- new_desktop_session : bool, optional
+ new_desktop : bool, optional
Whether to launch an instance of AEDT in a new thread, even if
another instance of the ``specified_version`` is active on the
machine. The default is ``False``. This parameter is ignored when
@@ -96,7 +120,11 @@ class Hfss(FieldAnalysis3D, ScatteringMethods):
The remote server must be up and running with the command `"ansysedt.exe -grpcsrv portnum"`.
aedt_process_id : int, optional
Process ID for the instance of AEDT to point PyAEDT at. The default is
- ``None``. This parameter is only used when ``new_desktop_session = False``.
+ ``None``. This parameter is only used when ``new_desktop = False``.
+ remove_lock : bool, optional
+ Whether to remove lock to project before opening it or not.
+ The default is ``False``, which means to not unlock
+ the existing project if needed and raise an exception.
Examples
--------
@@ -138,7 +166,7 @@ class Hfss(FieldAnalysis3D, ScatteringMethods):
Create an instance of HFSS using the 2023 R2 release and open
the specified project, which is named ``"myfile2.aedt"``.
- >>> hfss = Hfss(specified_version=232, projectname="myfile2.aedt")
+ >>> hfss = Hfss(version=232, project="myfile2.aedt")
PyAEDT INFO: Project myfile2 has been created.
PyAEDT INFO: No design is present. Inserting a new design.
PyAEDT INFO: Added design...
@@ -147,7 +175,7 @@ class Hfss(FieldAnalysis3D, ScatteringMethods):
Create an instance of HFSS using the 2023 R2 student version and open
the specified project, which is named ``"myfile3.aedt"``.
- >>> hfss = Hfss(specified_version="2023.2", projectname="myfile3.aedt", student_version=True)
+ >>> hfss = Hfss(version="2023.2", project="myfile3.aedt", student_version=True)
PyAEDT INFO: Project myfile3 has been created.
PyAEDT INFO: No design is present. Inserting a new design.
PyAEDT INFO: Added design...
@@ -162,36 +190,45 @@ class Hfss(FieldAnalysis3D, ScatteringMethods):
# except Exception:
# return "HFSS Module"
+ @pyaedt_function_handler(
+ designname="design",
+ projectname="project",
+ specified_version="version",
+ setup_name="setup",
+ new_desktop_session="new_desktop",
+ )
def __init__(
self,
- projectname=None,
- designname=None,
+ project=None,
+ design=None,
solution_type=None,
- setup_name=None,
- specified_version=None,
+ setup=None,
+ version=None,
non_graphical=False,
- new_desktop_session=False,
+ new_desktop=False,
close_on_exit=False,
student_version=False,
machine="",
port=0,
aedt_process_id=None,
+ remove_lock=False,
):
FieldAnalysis3D.__init__(
self,
"HFSS",
- projectname,
- designname,
+ project,
+ design,
solution_type,
- setup_name,
- specified_version,
+ setup,
+ version,
non_graphical,
- new_desktop_session,
+ new_desktop,
close_on_exit,
student_version,
machine,
port,
aedt_process_id,
+ remove_lock=remove_lock,
)
ScatteringMethods.__init__(self, self)
self._field_setups = []
@@ -937,7 +974,12 @@ def create_linear_count_sweep(
return False
@pyaedt_function_handler(
- setupname="setup", freqstart="start_frequency", freqstop="stop_frequency", sweepname="name"
+ setup_name="setup",
+ setupname="setup",
+ freqstart="start_frequency",
+ freqstop="stop_frequency",
+ sweepname="name",
+ sweep_name="name",
)
def create_linear_step_sweep(
self,
@@ -1173,10 +1215,10 @@ def create_sbr_linked_antenna(
>>> from pyaedt import Hfss
>>> target_project = "my/path/to/targetProject.aedt"
>>> source_project = "my/path/to/sourceProject.aedt"
- >>> target = Hfss(projectname=target_project, solution_type="SBR+",
- ... specified_version="2021.2", new_desktop_session=False) # doctest: +SKIP
- >>> source = Hfss(projectname=source_project, designname="feeder",
- ... specified_version="2021.2", new_desktop_session=False) # doctest: +SKIP
+ >>> target = Hfss(project=target_project, solution_type="SBR+",
+ ... version="2021.2", new_desktop=False) # doctest: +SKIP
+ >>> source = Hfss(project=source_project, design="feeder",
+ ... version="2021.2", new_desktop=False) # doctest: +SKIP
>>> target.create_sbr_linked_antenna(source,target_cs="feederPosition",field_type="farfield") # doctest: +SKIP
"""
@@ -3585,11 +3627,11 @@ def edit_source(self, assignment=None, power="1W", phase="0deg"):
)
return True
- @pyaedt_function_handler(portandmode="assignment")
+ @pyaedt_function_handler(portandmode="assignment", file_name="input_file")
def edit_source_from_file(
self,
assignment,
- file_name,
+ input_file,
is_time_domain=True,
x_scale=1,
y_scale=1,
@@ -3606,7 +3648,7 @@ def edit_source_from_file(
assignment : str
Port name and mode. For example, ``"Port1:1"``.
The port name must be defined if the solution type is other than Eigenmodal.
- file_name : str
+ input_file : str
Full name of the input file.
is_time_domain : bool, optional
Whether the input data is time-based or frequency-based. Frequency based data are Mag/Phase (deg).
@@ -3638,7 +3680,7 @@ def find_scale(data, header_line):
return data[td]
return None
- with open(file_name, "r") as f:
+ with open(input_file, "r") as f:
header = f.readlines()[0]
time_data = {"[ps]": 1e-12, "[ns]": 1e-9, "[us]": 1e-6, "[ms]": 1e-3, "[s]": 1}
curva_data_V = {
@@ -3686,7 +3728,7 @@ def find_scale(data, header_line):
else:
out = "Voltage"
freq, mag, phase = parse_excitation_file(
- file_name=file_name,
+ input_file=input_file,
is_time_domain=is_time_domain,
x_scale=x_scale,
y_scale=y_scale,
@@ -3703,14 +3745,14 @@ def find_scale(data, header_line):
self.design_datasets[ds_name_mag].y = mag
self.design_datasets[ds_name_mag].update()
else:
- self.create_dataset1d_design(ds_name_mag, freq, mag, xunit="Hz")
+ self.create_dataset1d_design(ds_name_mag, freq, mag, x_unit="Hz")
if self.dataset_exists(ds_name_phase, False):
self.design_datasets[ds_name_phase].x = freq
self.design_datasets[ds_name_phase].y = phase
self.design_datasets[ds_name_phase].update()
else:
- self.create_dataset1d_design(ds_name_phase, freq, phase, xunit="Hz", yunit="deg")
+ self.create_dataset1d_design(ds_name_phase, freq, phase, x_unit="Hz", y_unit="deg")
self.osolution.EditSources(
[
["IncludePortPostProcessing:=", True, "SpecifySystemPower:=", False],
diff --git a/pyaedt/hfss3dlayout.py b/pyaedt/hfss3dlayout.py
index f95be62f400..57f70613fe4 100644
--- a/pyaedt/hfss3dlayout.py
+++ b/pyaedt/hfss3dlayout.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
"""This module contains the ``Hfss3dLayout`` class."""
from __future__ import absolute_import # noreorder
@@ -8,10 +32,10 @@
import os
import re
-from pyaedt import is_ironpython
from pyaedt.application.Analysis3DLayout import FieldAnalysis3DLayout
from pyaedt.application.analysis_hf import ScatteringMethods
from pyaedt.generic.general_methods import generate_unique_name
+from pyaedt.generic.general_methods import is_ironpython
from pyaedt.generic.general_methods import open_file
from pyaedt.generic.general_methods import parse_excitation_file
from pyaedt.generic.general_methods import pyaedt_function_handler
@@ -29,32 +53,32 @@ class Hfss3dLayout(FieldAnalysis3DLayout, ScatteringMethods):
Parameters
----------
- projectname : str, optional
+ project : str, optional
Name of the project to select or the full path to the project
or AEDTZ archive to open or the path to the ``aedb`` folder or
``edb.def`` file. The default is ``None``, in which case an
attempt is made to get an active project. If no projects are present,
an empty project is created.
- designname : str, optional
+ design : str, optional
Name of the design to select. The default is ``None``, in
which case an attempt is made to get an active design. If no
designs are present, an empty design is created.
solution_type : str, optional
Solution type to apply to the design. The default is
``None``, in which case the default type is applied.
- setup_name : str, optional
+ setup : str, optional
Name of the setup to use as the nominal. The default is
``None``, in which case the active setup is used or
nothing is used.
- specified_version : str, int, float, optional
+ version : str, int, float, optional
Version of AEDT to use. The default is ``None``, in which case
the active version or latest installed version is used.
Examples of input values are ``232``, ``23.2``,``2023.2``,``"2023.2"``.
non_graphical : bool, optional
Whether to launch AEDT in non-graphical mode. The default
- is ``False```, in which case AEDT is launched in graphical mode.
+ is ``True```, in which case AEDT is launched in graphical mode.
This parameter is ignored when a script is launched within AEDT.
- new_desktop_session : bool, optional
+ new_desktop : bool, optional
Whether to launch an instance of AEDT in a new thread, even if
another instance of the ``specified_version`` is active on the
machine. The default is ``False``.
@@ -72,10 +96,14 @@ class Hfss3dLayout(FieldAnalysis3DLayout, ScatteringMethods):
The remote server must be up and running with the command `"ansysedt.exe -grpcsrv portnum"`.
aedt_process_id : int, optional
Process ID for the instance of AEDT to point PyAEDT at. The default is
- ``None``. This parameter is only used when ``new_desktop_session = False``.
+ ``None``. This parameter is only used when ``new_desktop = False``.
ic_mode : bool, optional
Whether to set the design to IC mode or not. The default is ``None``, which means to retain
the existing setting.
+ remove_lock : bool, optional
+ Whether to remove lock to project before opening it or not.
+ The default is ``False``, which means to not unlock
+ the existing project if needed and raise an exception.
Examples
--------
@@ -103,7 +131,7 @@ class Hfss3dLayout(FieldAnalysis3DLayout, ScatteringMethods):
Create an AEDT 2023 R1 object and then create a
``Hfss3dLayout`` object and open the specified project.
- >>> aedtapp = Hfss3dLayout(specified_version="2023.1", projectname="myfile.aedt")
+ >>> aedtapp = Hfss3dLayout(version="2023.1", project="myfile.aedt")
Create an instance of ``Hfss3dLayout`` from an ``Edb``
@@ -113,42 +141,51 @@ class Hfss3dLayout(FieldAnalysis3DLayout, ScatteringMethods):
>>> edb.stackup.import_stackup("stackup.xml") # Import stackup. Manipulate edb, ...
>>> edb.save_edb()
>>> edb.close_edb()
- >>> aedtapp = pyaedt.Hfss3dLayout(specified_version=231, projectname=edb_path)
+ >>> aedtapp = pyaedt.Hfss3dLayout(version=231, project=edb_path)
"""
+ @pyaedt_function_handler(
+ designname="design",
+ projectname="project",
+ specified_version="version",
+ setup_name="setup",
+ new_desktop_session="new_desktop",
+ )
def __init__(
self,
- projectname=None,
- designname=None,
+ project=None,
+ design=None,
solution_type=None,
- setup_name=None,
- specified_version=None,
+ setup=None,
+ version=None,
non_graphical=False,
- new_desktop_session=False,
+ new_desktop=False,
close_on_exit=False,
student_version=False,
machine="",
port=0,
aedt_process_id=None,
ic_mode=None,
+ remove_lock=False,
):
FieldAnalysis3DLayout.__init__(
self,
"HFSS 3D Layout Design",
- projectname,
- designname,
+ project,
+ design,
solution_type,
- setup_name,
- specified_version,
+ setup,
+ version,
non_graphical,
- new_desktop_session,
+ new_desktop,
close_on_exit,
student_version,
machine,
port,
aedt_process_id,
ic_mode,
+ remove_lock=remove_lock,
)
ScatteringMethods.__init__(self, self)
@@ -710,7 +747,7 @@ def import_edb(self, input_folder):
self._close_edb()
project_name = self.desktop_class.active_project().GetName()
design_name = self.desktop_class.active_design(self.desktop_class.active_project()).GetName().split(";")[-1]
- self.__init__(projectname=project_name, designname=design_name)
+ self.__init__(project=project_name, design=design_name)
return True
@pyaedt_function_handler(outputdir="output_dir")
@@ -1036,7 +1073,12 @@ def create_linear_count_sweep(
return False
@pyaedt_function_handler(
- setupname="setup", freqstart="start_frequency", freqstop="stop_frequency", sweepname="name"
+ setup_name="setup",
+ setupname="setup",
+ freqstart="start_frequency",
+ freqstop="stop_frequency",
+ sweepname="name",
+ sweep_name="name",
)
def create_linear_step_sweep(
self,
@@ -2035,9 +2077,59 @@ def edit_source_from_file(
-------
bool
"""
+
+ def find_scale(data, header_line):
+ for td in data.keys():
+ if td in header_line:
+ return data[td]
+ return None
+
+ with open(input_file, "r") as f:
+ header = f.readlines()[0]
+ time_data = {"[ps]": 1e-12, "[ns]": 1e-9, "[us]": 1e-6, "[ms]": 1e-3, "[s]": 1}
+ curva_data_V = {
+ "[nV]": 1e-9,
+ "[pV]": 1e-12,
+ "[uV]": 1e-6,
+ "[mV]": 1e-3,
+ "[V]": 1,
+ "[kV]": 1e3,
+ }
+ curva_data_W = {
+ "[nW]": 1e-9,
+ "[pW]": 1e-12,
+ "[uW]": 1e-6,
+ "[mW]": 1e-3,
+ "[W]": 1,
+ "[kW]": 1e3,
+ }
+ curva_data_A = {
+ "[nA]": 1e-9,
+ "[pA]": 1e-12,
+ "[uA]": 1e-6,
+ "[mA]": 1e-3,
+ "[A]": 1,
+ "[kA]": 1e3,
+ }
+ scale = find_scale(time_data, header)
+ x_scale = scale if scale else x_scale
+ scale = find_scale(curva_data_V, header)
+ if scale:
+ y_scale = scale
+ data_format = "Voltage"
+ else:
+ scale = find_scale(curva_data_W, header)
+ if scale:
+ y_scale = scale
+ data_format = "Power"
+ else:
+ scale = find_scale(curva_data_A, header)
+ if scale:
+ y_scale = scale
+ data_format = "Current"
out = "Voltage"
freq, mag, phase = parse_excitation_file(
- file_name=input_file,
+ input_file=input_file,
is_time_domain=is_time_domain,
x_scale=x_scale,
y_scale=y_scale,
@@ -2054,14 +2146,14 @@ def edit_source_from_file(
self.design_datasets[ds_name_mag].y = mag
self.design_datasets[ds_name_mag].update()
else:
- self.create_dataset1d_design(ds_name_mag, freq, mag, xunit="Hz")
+ self.create_dataset1d_design(ds_name_mag, freq, mag, x_unit="Hz")
if self.dataset_exists(ds_name_phase, False):
self.design_datasets[ds_name_phase].x = freq
self.design_datasets[ds_name_phase].y = phase
self.design_datasets[ds_name_phase].update()
else:
- self.create_dataset1d_design(ds_name_phase, freq, phase, xunit="Hz", yunit="deg")
+ self.create_dataset1d_design(ds_name_phase, freq, phase, x_unit="Hz", y_unit="deg")
for p in self.boundaries:
if p.name == source:
str_val = ["TotalVoltage"]
diff --git a/pyaedt/icepak.py b/pyaedt/icepak.py
index 01e92a528fa..375c106e602 100644
--- a/pyaedt/icepak.py
+++ b/pyaedt/icepak.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
"""This module contains the ``Icepak`` class."""
from __future__ import absolute_import # noreorder
@@ -9,7 +33,6 @@
import warnings
import pyaedt
-from pyaedt import is_linux
from pyaedt.application.Analysis3D import FieldAnalysis3D
from pyaedt.application.Design import DesignSettingsManipulation
from pyaedt.generic.DataHandlers import _arg2dict
@@ -20,6 +43,7 @@
from pyaedt.generic.general_methods import generate_unique_name
from pyaedt.generic.general_methods import open_file
from pyaedt.generic.general_methods import pyaedt_function_handler
+from pyaedt.generic.settings import is_linux
from pyaedt.generic.settings import settings
from pyaedt.modeler.cad.components_3d import UserDefinedComponent
from pyaedt.modeler.cad.elements3d import FacePrimitive
@@ -49,32 +73,32 @@ class Icepak(FieldAnalysis3D):
Parameters
----------
- projectname : str, optional
+ project : str, optional
Name of the project to select or the full path to the project
or AEDTZ archive to open. The default is ``None``, in which
case an attempt is made to get an active project. If no
projects are present, an empty project is created.
- designname : str, optional
+ design : str, optional
Name of the design to select. The default is ``None``, in
which case an attempt is made to get an active design. If no
designs are present, an empty design is created.
solution_type : str, optional
Solution type to apply to the design. The default is
``None``, in which case the default type is applied.
- setup_name : str, optional
+ setup : str, optional
Name of the setup to use as the nominal. The default is
``None``, in which case the active setup is used or
nothing is used.
- specified_version : str, int, float, optional
+ version : str, int, float, optional
Version of AEDT to use. The default is ``None``, in which case
the active version or latest installed version is used.
This parameter is ignored when Script is launched within AEDT.
Examples of input values are ``232``, ``23.2``,``2023.2``,``"2023.2"``.
- non-graphical : bool, optional
+ non_graphical : bool, optional
Whether to launch AEDT in non-graphical mode. The default
is ``False``, in which case AEDT is launched in graphical mode.
This parameter is ignored when a script is launched within AEDT.
- new_desktop_session : bool, optional
+ new_desktop : bool, optional
Whether to launch an instance of AEDT in a new thread, even if
another instance of the ``specified_version`` is active on the
machine. The default is ``False``.
@@ -93,7 +117,11 @@ class Icepak(FieldAnalysis3D):
The remote server must be up and running with the command `"ansysedt.exe -grpcsrv portnum"`.
aedt_process_id : int, optional
Process ID for the instance of AEDT to point PyAEDT at. The default is
- ``None``. This parameter is only used when ``new_desktop_session = False``.
+ ``None``. This parameter is only used when ``new_desktop = False``.
+ remove_lock : bool, optional
+ Whether to remove lock to project before opening it or not.
+ The default is ``False``, which means to not unlock
+ the existing project if needed and raise an exception.
Examples
--------
@@ -131,42 +159,51 @@ class Icepak(FieldAnalysis3D):
Create an instance of Icepak using the 2023 R2 release and
open the specified project, which is ``myipk2.aedt``.
- >>> icepak = Icepak(specified_version=2023.2, projectname="myipk2.aedt")
+ >>> icepak = Icepak(version=2023.2, project="myipk2.aedt")
PyAEDT INFO: Project...
PyAEDT INFO: No design is present. Inserting a new design.
PyAEDT INFO: Added design...
"""
+ @pyaedt_function_handler(
+ designname="design",
+ projectname="project",
+ specified_version="version",
+ setup_name="setup",
+ new_desktop_session="new_desktop",
+ )
def __init__(
self,
- projectname=None,
- designname=None,
+ project=None,
+ design=None,
solution_type=None,
- setup_name=None,
- specified_version=None,
+ setup=None,
+ version=None,
non_graphical=False,
- new_desktop_session=False,
+ new_desktop=False,
close_on_exit=False,
student_version=False,
machine="",
port=0,
aedt_process_id=None,
+ remove_lock=False,
):
FieldAnalysis3D.__init__(
self,
"Icepak",
- projectname,
- designname,
+ project,
+ design,
solution_type,
- setup_name,
- specified_version,
+ setup,
+ version,
non_graphical,
- new_desktop_session,
+ new_desktop,
close_on_exit,
student_version,
machine,
port,
aedt_process_id,
+ remove_lock=remove_lock,
)
self._monitor = Monitor(self)
self._configurations = ConfigurationsIcepak(self)
@@ -2587,7 +2624,7 @@ def create_pcb_from_3dlayout(
if close_linked_project_after_import and ".aedt" in project_name:
prjname = os.path.splitext(os.path.basename(project_name))[0]
- self.close_project(prjname, save_project=False)
+ self.close_project(prjname, save=False)
self.logger.info("PCB component correctly created in Icepak.")
return status
@@ -3996,7 +4033,7 @@ def assign_stationary_wall_with_htc(
)
@pyaedt_function_handler(setupname="name", setuptype="setup_type")
- def create_setup(self, name="MySetupAuto", setup_type=None, **kwargs):
+ def create_setup(self, name=None, setup_type=None, **kwargs):
"""Create an analysis setup for Icepak.
Optional arguments are passed along with ``setup_type`` and ``name``. Keyword
names correspond to the ``setup_type``
@@ -4009,7 +4046,7 @@ def create_setup(self, name="MySetupAuto", setup_type=None, **kwargs):
Parameters
----------
name : str, optional
- Name of the setup. The default is ``"Setup1"``.
+ Name of the setup.
setup_type : int, str, optional
Type of the setup. Options are ``"IcepakSteadyState"``
and ``"IcepakTransient"``. The default is ``"IcepakSteadyState"``.
@@ -4130,7 +4167,7 @@ def assign_source(
>>> from pyaedt import Icepak
>>> app = Icepak()
>>> box = app.modeler.create_box([0, 0, 0],[20, 20, 20],name="box")
- >>> ds = app.create_dataset1d_design("Test_DataSet", [1, 2, 3], [3, 4, 5])
+ >>> ds = app.create_dataset1d_design("Test_DataSet",[1, 2, 3],[3, 4, 5])
>>> app.solution_type = "Transient"
>>> b = app.assign_source("box", "Total Power", assignment_value={"Type": "Temp Dep",
... "Function": "Piecewise Linear", "Values": "Test_DataSet"})
@@ -4551,7 +4588,7 @@ def get_fans_operating_point(self, export_file=None, setup_name=None, time_step=
export_file : str, optional
Name of the file in which the fans' operating point is saved. The default is
``None``, in which case the filename is automatically generated.
- setup_name : str, optional
+ setup : str, optional
Setup name from which to determine the fans' operating point. The default is
``None``, in which case the first available setup is used.
time_step : str, optional
diff --git a/pyaedt/maxwell.py b/pyaedt/maxwell.py
index eb46ce4fadb..b1bbe65663f 100644
--- a/pyaedt/maxwell.py
+++ b/pyaedt/maxwell.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
"""This module contains these Maxwell classes: ``Maxwell``, ``Maxwell2d``, and ``Maxwell3d``."""
from __future__ import absolute_import # noreorder
@@ -8,7 +32,6 @@
import re
import time
-from pyaedt import settings
from pyaedt.application.Analysis3D import FieldAnalysis3D
from pyaedt.application.Variables import decompose_variable_value
from pyaedt.generic.constants import SOLUTIONS
@@ -18,6 +41,7 @@
from pyaedt.generic.general_methods import pyaedt_function_handler
from pyaedt.generic.general_methods import read_configuration_file
from pyaedt.generic.general_methods import write_configuration_file
+from pyaedt.generic.settings import settings
from pyaedt.modeler.geometry_operators import GeometryOperators
from pyaedt.modules.Boundary import BoundaryObject
from pyaedt.modules.Boundary import MaxwellParameters
@@ -281,7 +305,7 @@ def assign_matrix(
Set matrix in a Maxwell magnetostatic analysis.
>>> from pyaedt import Maxwell2d
- >>> m2d = Maxwell2d(solution_type="MagnetostaticXY",specified_version="2022.1",close_on_exit=True)
+ >>> m2d = Maxwell2d(solution_type="MagnetostaticXY",version="2022.1",close_on_exit=True)
>>> coil1 = m2d.modeler.create_rectangle([0, 1.5, 0], [8, 3], is_covered=True, name="Coil_1")
>>> coil2 = m2d.modeler.create_rectangle([8.5, 1.5, 0], [8, 3], is_covered=True, name="Coil_2")
>>> coil3 = m2d.modeler.create_rectangle([16, 1.5, 0], [8, 3], is_covered=True, name="Coil_3")
@@ -2084,23 +2108,23 @@ class Maxwell3d(Maxwell, FieldAnalysis3D, object):
Parameters
----------
- projectname : str, optional
+ project : str, optional
Name of the project to select or the full path to the project
or AEDTZ archive to open. The default is ``None``, in which
case an attempt is made to get an active project. If no
projects are present, an empty project is created.
- designname : str, optional
+ design : str, optional
Name of the design to select. The default is ``None``, in
which case an attempt is made to get an active design. If no
designs are present, an empty design is created.
solution_type : str, optional
Solution type to apply to the design. The default is
``None``, in which case the default type is applied.
- setup_name : str, optional
+ setup : str, optional
Name of the setup to use as the nominal. The default is
``None``, in which case the active setup is used or
nothing is used.
- specified_version : str, int, float, optional
+ version : str, int, float, optional
Version of AEDT to use. The default is ``None``, in which case
the active version or latest installed version is used. This
parameter is ignored when a script is launched within AEDT.
@@ -2110,7 +2134,7 @@ class Maxwell3d(Maxwell, FieldAnalysis3D, object):
is ``False``, in which case AEDT is launched in graphical
mode. This parameter is ignored when a script is launched within
AEDT.
- new_desktop_session : bool, optional
+ new_desktop : bool, optional
Whether to launch an instance of AEDT in a new thread, even if
another instance of the ``specified_version`` is active on the
machine. The default is ``False``. This parameter is ignored
@@ -2132,7 +2156,11 @@ class Maxwell3d(Maxwell, FieldAnalysis3D, object):
The remote server must be up and running with the command `"ansysedt.exe -grpcsrv portnum"`.
aedt_process_id : int, optional
Process ID for the instance of AEDT to point PyAEDT at. The default is
- ``None``. This parameter is only used when ``new_desktop_session = False``.
+ ``None``. This parameter is only used when ``new_desktop = False``.
+ remove_lock : bool, optional
+ Whether to remove lock to project before opening it or not.
+ The default is ``False``, which means to not unlock
+ the existing project if needed and raise an exception.
Examples
--------
@@ -2146,7 +2174,7 @@ class Maxwell3d(Maxwell, FieldAnalysis3D, object):
Create an instance of Maxwell 3D using the 2024 R1 release and open
the specified project, which is named ``mymaxwell2.aedt``.
- >>> m3d = Maxwell3d(specified_version="2024.1", projectname="mymaxwell2.aedt")
+ >>> m3d = Maxwell3d(version="2024.1", project="mymaxwell2.aedt")
PyAEDT INFO: Added design ...
"""
@@ -2156,20 +2184,28 @@ def dim(self):
"""Dimensions."""
return "3D"
+ @pyaedt_function_handler(
+ designname="design",
+ projectname="project",
+ specified_version="version",
+ setup_name="setup",
+ new_desktop_session="new_desktop",
+ )
def __init__(
self,
- projectname=None,
- designname=None,
+ project=None,
+ design=None,
solution_type=None,
- setup_name=None,
- specified_version=None,
+ setup=None,
+ version=None,
non_graphical=False,
- new_desktop_session=False,
+ new_desktop=False,
close_on_exit=False,
student_version=False,
machine="",
port=0,
aedt_process_id=None,
+ remove_lock=False,
):
"""
Initialize the ``Maxwell`` class.
@@ -2178,18 +2214,19 @@ def __init__(
FieldAnalysis3D.__init__(
self,
"Maxwell 3D",
- projectname,
- designname,
+ project,
+ design,
solution_type,
- setup_name,
- specified_version,
+ setup,
+ version,
non_graphical,
- new_desktop_session,
+ new_desktop,
close_on_exit,
student_version,
machine,
port,
aedt_process_id,
+ remove_lock=remove_lock,
)
Maxwell.__init__(self)
@@ -2838,23 +2875,23 @@ class Maxwell2d(Maxwell, FieldAnalysis3D, object):
Parameters
----------
- projectname : str, optional
+ project : str, optional
Name of the project to select or the full path to the project
or AEDTZ archive to open. The default is ``None``, in which
case an attempt is made to get an active project. If no
projects are present, an empty project is created.
- designname : str, optional
+ design : str, optional
Name of the design to select. The default is ``None``, in
which case an attempt is made to get an active design. If no
designs are present, an empty design is created.
solution_type : str, optional
Solution type to apply to the design. The default is
``None``, in which case the default type is applied.
- setup_name : str, optional
+ setup : str, optional
Name of the setup to use as the nominal. The default is
``None``, in which case the active setup is used or
nothing is used.
- specified_version : str, int, float, optional
+ version : str, int, float, optional
Version of AEDT to use. The default is ``None``, in which case
the active version or latest installed version is used.
This parameter is ignored when a script is launched within AEDT.
@@ -2863,7 +2900,7 @@ class Maxwell2d(Maxwell, FieldAnalysis3D, object):
Whether to launch AEDT in non-graphical mode. The default
is ``False``, in which case AEDT is launched in graphical mode.
This parameter is ignored when a script is launched within AEDT.
- new_desktop_session : bool, optional
+ new_desktop : bool, optional
Whether to launch an instance of AEDT in a new thread, even if
another instance of the ``specified_version`` is active on the
machine. The default is ``False``. This parameter is ignored when
@@ -2884,7 +2921,11 @@ class Maxwell2d(Maxwell, FieldAnalysis3D, object):
R2 or later. The remote server must be up and running with the command `"ansysedt.exe -grpcsrv portnum"`.
aedt_process_id : int, optional
Process ID for the instance of AEDT to point PyAEDT at. The default is
- ``None``. This parameter is only used when ``new_desktop_session = False``.
+ ``None``. This parameter is only used when ``new_desktop = False``.
+ remove_lock : bool, optional
+ Whether to remove lock to project before opening it or not.
+ The default is ``False``, which means to not unlock
+ the existing project if needed and raise an exception.
Examples
--------
@@ -2923,37 +2964,46 @@ def geometry_mode(self):
>>> oDesign.GetGeometryMode"""
return self.odesign.GetGeometryMode()
+ @pyaedt_function_handler(
+ designname="design",
+ projectname="project",
+ specified_version="version",
+ setup_name="setup",
+ new_desktop_session="new_desktop",
+ )
def __init__(
self,
- projectname=None,
- designname=None,
+ project=None,
+ design=None,
solution_type=None,
- setup_name=None,
- specified_version=None,
+ setup=None,
+ version=None,
non_graphical=False,
- new_desktop_session=False,
+ new_desktop=False,
close_on_exit=False,
student_version=False,
machine="",
port=0,
aedt_process_id=None,
+ remove_lock=False,
):
self.is3d = False
FieldAnalysis3D.__init__(
self,
"Maxwell 2D",
- projectname,
- designname,
+ project,
+ design,
solution_type,
- setup_name,
- specified_version,
+ setup,
+ version,
non_graphical,
- new_desktop_session,
+ new_desktop,
close_on_exit,
student_version,
machine,
port,
aedt_process_id,
+ remove_lock=remove_lock,
)
Maxwell.__init__(self)
diff --git a/pyaedt/maxwellcircuit.py b/pyaedt/maxwellcircuit.py
index cc191e7cea3..2a70a8354b4 100644
--- a/pyaedt/maxwellcircuit.py
+++ b/pyaedt/maxwellcircuit.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
"""This module contains the ``MaxwellCircuit`` class."""
from __future__ import absolute_import # noreorder
@@ -15,25 +39,25 @@ class MaxwellCircuit(AnalysisMaxwellCircuit, object):
Parameters
----------
- projectname : str, optional
+ project : str, optional
Name of the project to select or the full path to the project
or AEDTZ archive to open. The default is ``None``, in which
case an attempt is made to get an active project. If no
projects are present, an empty project is created.
- designname : str, optional
+ design : str, optional
Name of the design to select. The default is ``None``, in
which case an attempt is made to get an active design. If no
designs are present, an empty design is created.
- specified_version : str, int, float, optional
+ version : str, int, float, optional
Version of AEDT to use. The default is ``None``. If ``None``,
the active setup is used or the latest installed version is
used.
Examples of input values are ``232``, ``23.2``,``2023.2``,``"2023.2"``.
- non-graphical : bool, optional
+ non_graphical : bool, optional
Whether to launch AEDT in non-graphical mode. The default
is ``False``, in which case AEDT is launched in graphical mode.
This parameter is ignored when a script is launched within AEDT.
- new_desktop_session : bool, optional
+ new_desktop : bool, optional
Whether to launch an instance of AEDT in a new thread, even if
another instance of the ``specified_version`` is active on the
machine. The default is ``False``.
@@ -52,7 +76,11 @@ class MaxwellCircuit(AnalysisMaxwellCircuit, object):
later. The remote server must be up and running with the command `"ansysedt.exe -grpcsrv portnum"`.
aedt_process_id : int, optional
Process ID for the instance of AEDT to point PyAEDT at. The default is
- ``None``. This parameter is only used when ``new_desktop_session = False``.
+ ``None``. This parameter is only used when ``new_desktop = False``.
+ remove_lock : bool, optional
+ Whether to remove lock to project before opening it or not.
+ The default is ``False``, which means to not unlock
+ the existing project if needed and raise an exception.
Examples
--------
@@ -80,34 +108,43 @@ class MaxwellCircuit(AnalysisMaxwellCircuit, object):
>>> app = MaxwellCircuit("myfile.aedt")
"""
+ @pyaedt_function_handler(
+ designname="design",
+ projectname="project",
+ specified_version="version",
+ setup_name="setup",
+ new_desktop_session="new_desktop",
+ )
def __init__(
self,
- projectname=None,
- designname=None,
+ project=None,
+ design=None,
solution_type=None,
- specified_version=None,
+ version=None,
non_graphical=False,
- new_desktop_session=False,
+ new_desktop=False,
close_on_exit=False,
student_version=False,
machine="",
port=0,
aedt_process_id=None,
+ remove_lock=False,
):
"""Constructor."""
AnalysisMaxwellCircuit.__init__(
self,
"Maxwell Circuit",
- projectname,
- designname,
- specified_version,
+ project,
+ design,
+ version,
non_graphical,
- new_desktop_session,
+ new_desktop,
close_on_exit,
student_version,
machine,
port,
aedt_process_id,
+ remove_lock=remove_lock,
)
def _init_from_design(self, *args, **kwargs):
diff --git a/pyaedt/mechanical.py b/pyaedt/mechanical.py
index 7bd52e6e314..163e4d126b4 100644
--- a/pyaedt/mechanical.py
+++ b/pyaedt/mechanical.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
"""This module contains the ``Mechanical`` class."""
from __future__ import absolute_import # noreorder
@@ -16,23 +40,23 @@ class Mechanical(FieldAnalysis3D, object):
Parameters
----------
- projectname : str, optional
+ project : str, optional
Name of the project to select or the full path to the project
or AEDTZ archive to open. The default is ``None``, in which
case an attempt is made to get an active project. If no
projects are present, an empty project is created.
- designname : str, optional
+ design : str, optional
Name of the design to select. The default is ``None``, in
which case an attempt is made to get an active design. If no
designs are present, an empty design is created.
solution_type : str, optional
Solution type to apply to the design. The default is
``None``, in which case the default type is applied.
- setup_name : str, optional
+ setup : str, optional
Name of the setup to use as the nominal. The default is
``None``, in which case the active setup is used or
nothing is used.
- specified_version : str, int, float, optional
+ version : str, int, float, optional
Version of AEDT to use. The default is ``None``, in which case
the active version or latest installed version is used.
This parameter is ignored when a script is launched within AEDT.
@@ -41,7 +65,7 @@ class Mechanical(FieldAnalysis3D, object):
Whether to launch AEDT in the non-graphical mode. The default
is ``False``, in which case AEDT is launched in the graphical mode.
This parameter is ignored when a script is launched within AEDT.
- new_desktop_session : bool, optional
+ new_desktop : bool, optional
Whether to launch an instance of AEDT in a new thread, even if
another instance of the ``specified_version`` is active on the
machine. The default is ``False``. This parameter is ignored when
@@ -62,7 +86,11 @@ class Mechanical(FieldAnalysis3D, object):
later. The remote server must be up and running with the command `"ansysedt.exe -grpcsrv portnum"`.
aedt_process_id : int, optional
Process ID for the instance of AEDT to point PyAEDT at. The default is
- ``None``. This parameter is only used when ``new_desktop_session = False``.
+ ``None``. This parameter is only used when ``new_desktop = False``.
+ remove_lock : bool, optional
+ Whether to remove lock to project before opening it or not.
+ The default is ``False``, which means to not unlock
+ the existing project if needed and raise an exception.
Examples
--------
@@ -92,40 +120,49 @@ class Mechanical(FieldAnalysis3D, object):
``Mechanical`` object and open the specified project, which is
named ``"myfile.aedt"``.
- >>> aedtapp = Mechanical(specified_version=23.2, projectname="myfile.aedt")
+ >>> aedtapp = Mechanical(version=23.2, project="myfile.aedt")
"""
+ @pyaedt_function_handler(
+ designname="design",
+ projectname="project",
+ specified_version="version",
+ setup_name="setup",
+ new_desktop_session="new_desktop",
+ )
def __init__(
self,
- projectname=None,
- designname=None,
+ project=None,
+ design=None,
solution_type=None,
- setup_name=None,
- specified_version=None,
+ setup=None,
+ version=None,
non_graphical=False,
- new_desktop_session=False,
+ new_desktop=False,
close_on_exit=False,
student_version=False,
machine="",
port=0,
aedt_process_id=None,
+ remove_lock=False,
):
FieldAnalysis3D.__init__(
self,
"Mechanical",
- projectname,
- designname,
+ project,
+ design,
solution_type,
- setup_name,
- specified_version,
+ setup,
+ version,
non_graphical,
- new_desktop_session,
+ new_desktop,
close_on_exit,
student_version,
machine,
port,
aedt_process_id,
+ remove_lock=remove_lock,
)
def _init_from_design(self, *args, **kwargs):
diff --git a/pyaedt/misc/__init__.py b/pyaedt/misc/__init__.py
index 0a5470b6bf7..5cbb8146ac5 100644
--- a/pyaedt/misc/__init__.py
+++ b/pyaedt/misc/__init__.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
from pyaedt.misc.misc import current_student_version
from pyaedt.misc.misc import current_version
from pyaedt.misc.misc import installed_versions
diff --git a/pyaedt/misc/create_remote_dir.py b/pyaedt/misc/create_remote_dir.py
index 61750cebc7a..2996053836f 100644
--- a/pyaedt/misc/create_remote_dir.py
+++ b/pyaedt/misc/create_remote_dir.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import os
import sys
diff --git a/pyaedt/misc/expression_catalog.toml b/pyaedt/misc/expression_catalog.toml
new file mode 100644
index 00000000000..809dd4873ae
--- /dev/null
+++ b/pyaedt/misc/expression_catalog.toml
@@ -0,0 +1,367 @@
+# Voltage
+
+[voltage_line]
+name = "Voltage_Line"
+description = "Voltage drop along a line"
+design_type = ["HFSS", "Q3D Extractor"]
+fields_type = ["Fields", "CG Fields"]
+solution_type = ""
+primary_sweep = "Freq"
+assignment = ""
+assignment_type = ["Line"]
+operations = ["Fundamental_Quantity('E')",
+ "Operation('Real')",
+ "Operation('Tangent')",
+ "Operation('Dot')",
+ "EnterLine('assignment')",
+ "Operation('LineValue')",
+ "Operation('Integrate')",
+ "Operation('CmplxR')",
+ "Fundamental_Quantity('E')",
+ "Operation('Imag')",
+ "Operation('Tangent')",
+ "Operation('Dot')",
+ "EnterLine('assignment')",
+ "Operation('LineValue')",
+ "Operation('Integrate')",
+ "Operation('CmplxI')",
+ "Operation('+')"]
+dependent_expressions = []
+report = ["Data Table", "Rectangular Plot"]
+
+[voltage_line_time]
+name = "Voltage_Line"
+description = "Voltage drop along a line"
+design_type = ["HFSS"]
+fields_type = ["Fields"]
+solution_type = "Transient"
+primary_sweep = "Time"
+assignment = ""
+assignment_type = ["Line"]
+operations = ["Fundamental_Quantity('E_t')",
+ "Operation('Tangent')",
+ "Operation('Dot')",
+ "EnterLine('assignment')",
+ "Operation('LineValue')",
+ "Operation('Integrate')"
+]
+dependent_expressions = []
+report = ["Data Table", "Rectangular Plot"]
+
+[voltage_line_maxwell]
+name = "Voltage_Line"
+description = "Voltage drop along a line"
+design_type = ["Maxwell 3D"]
+fields_type = ["Fields"]
+solution_type = ""
+primary_sweep = "Freq"
+assignment = ""
+assignment_type = ["Line"]
+operations = ["NameOfExpression('')",
+ "Operation('Real')",
+ "Operation('Tangent')",
+ "Operation('Dot')",
+ "EnterLine('assignment')",
+ "Operation('LineValue')",
+ "Operation('Integrate')",
+ "Operation('CmplxR')",
+ "NameOfExpression('')",
+ "Operation('Imag')",
+ "Operation('Tangent')",
+ "Operation('Dot')",
+ "EnterLine('assignment')",
+ "Operation('LineValue')",
+ "Operation('Integrate')",
+ "Operation('CmplxI')",
+ "Operation('+')"]
+dependent_expressions = []
+report = ["Data Table", "Rectangular Plot"]
+
+[voltage_drop]
+name = "Voltage_Drop"
+description = "Voltage drop in Q3D"
+design_type = ["Q3D Extractor"]
+fields_type = ["DC R/L Fields"]
+solution_type = ""
+primary_sweep = "Freq"
+assignment = ""
+assignment_type = ["Line", "Face", "Sheet", "Solid"]
+constants = {"vrm"= 3.3}
+operations = ["Fundamental_Quantity('dcvPhi')",
+ "Scalar_Function(FuncValue='vrm')",
+ "Operation('+')"]
+dependent_expressions = []
+report = ["Field_3D"]
+
+# Current
+
+[current_line]
+name = "Current_Line"
+description = "Current along a line"
+design_type = ["HFSS", "Q3D Extractor"]
+fields_type = ["Fields", "CG Fields"]
+solution_type = ""
+primary_sweep = "Freq"
+assignment = ""
+assignment_type = ["Line"]
+operations = ["NameOfExpression('')",
+ "Operation('Real')",
+ "Operation('Tangent')",
+ "Operation('Dot')",
+ "EnterLine('assignment')",
+ "Operation('LineValue')",
+ "Operation('Integrate')",
+ "Operation('CmplxR')",
+ "NameOfExpression('')",
+ "Operation('Imag')",
+ "Operation('Tangent')",
+ "Operation('Dot')",
+ "EnterLine('assignment')",
+ "Operation('LineValue')",
+ "Operation('Integrate')",
+ "Operation('CmplxI')",
+ "Operation('+')"]
+dependent_expressions = []
+report = ["Data Table", "Rectangular Plot"]
+
+[current_line_time]
+name = "Current_Line"
+description = "Current along a line"
+design_type = ["HFSS"]
+fields_type = ["Fields"]
+solution_type = "Transient"
+primary_sweep = "Time"
+assignment = ""
+assignment_type = ["Line"]
+operations = ["Fundamental_Quantity('H_t')",
+ "Operation('Tangent')",
+ "Operation('Dot')",
+ "EnterLine('assignment')",
+ "Operation('LineValue')",
+ "Operation('Integrate')"]
+dependent_expressions = []
+report = ["Data Table", "Rectangular Plot"]
+
+# Power
+
+[power_flow]
+name = "Power_Flow"
+description = "Power flow through a surface"
+design_type = ["HFSS"]
+fields_type = ["Fields"]
+solution_type = ""
+primary_sweep = "Freq"
+assignment = ""
+assignment_type = ["Sheet", "Solid"]
+operations = ["NameOfExpression('Poynting')",
+ "Operation('Real')",
+ "Operation('Normal')",
+ "Operation('Dot')",
+ "EnterSurface('assignment')",
+ "Operation('SurfaceValue')",
+ "Operation('Integrate')"]
+dependent_expressions = []
+report = ["Data Table", "Rectangular Plot"]
+
+# Misc
+
+[wave_impedance_x]
+name = "Wave_Impedance_X"
+description = "Wave impedance along a line in X"
+design_type = ["HFSS"]
+fields_type = ["Fields"]
+solution_type = ""
+primary_sweep = "Freq"
+assignment = ""
+assignment_type = ["Line"]
+operations = ["Fundamental_Quantity('E')",
+ "Operation('Smooth')",
+ "Operation('CmplxMag')",
+ "Vector_Constant(1, 0, 0)",
+ "Operation('Cross')",
+ "Operation('Mag')",
+ "NameOfExpression('')",
+ "Operation('Smooth')",
+ "Operation('CmplxMag')",
+ "Vector_Constant(1, 0, 0)",
+ "Operation('Cross')",
+ "Operation('Mag')",
+ "Operation('/')"
+]
+dependent_expressions = []
+report = ["Data Table", "Rectangular Plot"]
+
+[wave_impedance_y]
+name = "Wave_Impedance_Y"
+description = "Wave impedance along a line in Y"
+design_type = ["HFSS"]
+fields_type = ["Fields"]
+solution_type = ""
+primary_sweep = "Freq"
+assignment = ""
+assignment_type = ["Line"]
+operations = ["Fundamental_Quantity('E')",
+ "Operation('Smooth')",
+ "Operation('CmplxMag')",
+ "Vector_Constant(0, 1, 0)",
+ "Operation('Cross')",
+ "Operation('Mag')",
+ "NameOfExpression('')",
+ "Operation('Smooth')",
+ "Operation('CmplxMag')",
+ "Vector_Constant(0, 1, 0)",
+ "Operation('Cross')",
+ "Operation('Mag')",
+ "Operation('/')"
+]
+dependent_expressions = []
+report = ["Data Table", "Rectangular Plot"]
+
+[wave_impedance_z]
+name = "Wave_Impedance_Z"
+description = "Wave impedance along a line in Z"
+design_type = ["HFSS"]
+fields_type = ["Fields"]
+solution_type = ""
+primary_sweep = "Freq"
+assignment = ""
+assignment_type = ["Line"]
+operations = ["Fundamental_Quantity('E')",
+ "Operation('Smooth')",
+ "Operation('CmplxMag')",
+ "Vector_Constant(0, 0, 1)",
+ "Operation('Cross')",
+ "Operation('Mag')",
+ "NameOfExpression('')",
+ "Operation('Smooth')",
+ "Operation('CmplxMag')",
+ "Vector_Constant(0, 0, 1)",
+ "Operation('Cross')",
+ "Operation('Mag')",
+ "Operation('/')"
+]
+dependent_expressions = []
+report = ["Data Table", "Rectangular Plot"]
+
+# Electrostatic
+
+[electric_charge]
+name = "Electric_Charge"
+description = "Total electric charge on a surface"
+design_type = ["Maxwell 3D"]
+fields_type = ["Fields"]
+solution_type = ""
+primary_sweep = "Freq"
+assignment = ""
+assignment_type = ["Sheet", "Solid"]
+operations = ["NameOfExpression('')",
+ "Operation('Normal')",
+ "Operation('Dot')",
+ "EnterSurface('assignment')",
+ "Operation('SurfaceValue')",
+ "Operation('Integrate')"]
+dependent_expressions = []
+report = ["Data Table", "Rectangular Plot"]
+
+[e_line]
+name = "E_Line"
+description = "E field tangential component along a line"
+design_type = ["Maxwell 2D"]
+fields_type = ["Fields"]
+solution_type = ""
+primary_sweep = "Distance"
+assignment = ""
+assignment_type = ["Line"]
+operations = ["NameOfExpression('')",
+ "Operation('Tangent')",
+ "Operation('Dot')"]
+dependent_expressions = []
+report = ["Data Table", "Rectangular Plot"]
+
+[b_radial]
+name = "Radial_Component_Magnetic_Field"
+description = "Radial component of magnetic field"
+design_type = ["Maxwell 2D"]
+fields_type = ["Fields"]
+solution_type = ""
+primary_sweep = "Distance"
+assignment = ""
+assignment_type = ["Line"]
+operations = ["Fundamental_Quantity('B')",
+ "Operation('ScalarX')",
+ "Scalar_Function(FuncValue='PHI')",
+ "Operation('UMathFunc', 'Cos')",
+ "Operation('*')",
+ "Fundamental_Quantity('B')",
+ "Operation('ScalarY')",
+ "Scalar_Function(FuncValue='PHI')",
+ "Operation('UMathFunc', 'Sin')",
+ "Operation('*')",
+ "Operation('+')"]
+dependent_expressions = []
+report = ["Data Table", "Rectangular Plot"]
+
+[b_tangential]
+name = "Tangential_Component_Magnetic_Field"
+description = "Tangential component of magnetic field"
+design_type = ["Maxwell 2D"]
+fields_type = ["Fields"]
+solution_type = ""
+primary_sweep = "Distance"
+assignment = ""
+assignment_type = ["Line"]
+operations = ["Fundamental_Quantity('B')",
+ "Operation('ScalarX')",
+ "Scalar_Function(FuncValue='PHI')",
+ "Operation('UMathFunc', 'Sin')",
+ "Operation('*')",
+ "Operation('Neg')",
+ "Fundamental_Quantity('B')",
+ "Operation('ScalarY')",
+ "Scalar_Function(FuncValue='PHI')",
+ "Operation('UMathFunc', 'Cos')",
+ "Operation('*')",
+ "Operation('+')"]
+dependent_expressions = []
+report = ["Data Table", "Rectangular Plot"]
+
+[radial_stress_tensor]
+name = "Radial_Stress_Tensor"
+description = "Radial stress tensor"
+design_type = ["Maxwell 2D"]
+fields_type = ["Fields"]
+solution_type = ""
+primary_sweep = "Distance"
+assignment = ""
+assignment_type = ["Line"]
+dependent_expressions = ["b_radial", "b_tangential"]
+operations = ["NameOfExpression('b_radial')",
+ "NameOfExpression('b_radial')",
+ "Operation('*')",
+ "NameOfExpression('b_tangential')",
+ "NameOfExpression('b_tangential')",
+ "Operation('*')",
+ "Operation('Neg')",
+ "Operation('+')",
+ "Scalar_Constant(1.25664e-06)",
+ "Operation('/')",
+ "Scalar_Constant(2)",
+ "Operation('/')"]
+report = ["Data Table", "Rectangular Plot"]
+
+[tangential_stress_tensor]
+name = "Tangential_Stress_Tensor"
+description = "Tangential stress tensor"
+design_type = ["Maxwell 2D"]
+fields_type = ["Fields"]
+solution_type = ""
+primary_sweep = "Distance"
+assignment = ""
+assignment_type = ["Line"]
+dependent_expressions = ["b_radial", "b_tangential"]
+operations = ["NameOfExpression('b_radial')",
+ "NameOfExpression('b_tangential')",
+ "Operation('*')",
+ "Scalar_Constant(1.25664e-06)",
+ "Operation('/')"]
+report = ["Data Table", "Rectangular Plot"]
diff --git a/pyaedt/misc/misc.py b/pyaedt/misc/misc.py
index e3668e7865c..35d37c070aa 100644
--- a/pyaedt/misc/misc.py
+++ b/pyaedt/misc/misc.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
"""Miscellaneous Methods for PyAEDT."""
import os
@@ -75,3 +99,21 @@ def current_student_version():
if "SV" in version_key:
return version_key
return ""
+
+
+def is_safe_path(path, allowed_extensions=None):
+ """Validate if a path is safe to use."""
+ # Ensure path is an existing file or directory
+ if not os.path.exists(path) or not os.path.isfile(path):
+ return False
+
+ # Restrict to allowed file extensions:
+ if allowed_extensions:
+ if not any(path.endswith(extension) for extension in allowed_extensions):
+ return False
+
+ # Ensure path does not contain dangerous characters
+ if any(char in path for char in (";", "|", "&", "$", "<", ">", "`")):
+ return False
+
+ return True
diff --git a/pyaedt/misc/spisim_com_configuration_files/__init__.py b/pyaedt/misc/spisim_com_configuration_files/__init__.py
index c23e620fcaf..addb0938ec4 100644
--- a/pyaedt/misc/spisim_com_configuration_files/__init__.py
+++ b/pyaedt/misc/spisim_com_configuration_files/__init__.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
from pathlib import Path
workdir = Path(__file__).parent
diff --git a/pyaedt/misc/spisim_com_configuration_files/com_parameters.py b/pyaedt/misc/spisim_com_configuration_files/com_parameters.py
index 7aaeddda5c7..1bec9c5c696 100644
--- a/pyaedt/misc/spisim_com_configuration_files/com_parameters.py
+++ b/pyaedt/misc/spisim_com_configuration_files/com_parameters.py
@@ -1,9 +1,33 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
from enum import Enum
import json
from pathlib import Path
-from pyaedt import pyaedt_function_handler
-from pyaedt import settings
+from pyaedt.generic.general_methods import pyaedt_function_handler
+from pyaedt.generic.settings import settings
from pyaedt.misc.spisim_com_configuration_files.com_settings_mapping import spimsim_matlab_keywords_mapping
logger = settings.logger
diff --git a/pyaedt/misc/spisim_com_configuration_files/com_settings_mapping.py b/pyaedt/misc/spisim_com_configuration_files/com_settings_mapping.py
index 942f327492c..7c30eac24ca 100644
--- a/pyaedt/misc/spisim_com_configuration_files/com_settings_mapping.py
+++ b/pyaedt/misc/spisim_com_configuration_files/com_settings_mapping.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
spimsim_matlab_keywords_mapping = {
# Matlab keyword -> SPIsim keyword
# OP_IO_CTRL
diff --git a/pyaedt/modeler/__init__.py b/pyaedt/modeler/__init__.py
index e69de29bb2d..9c4476773da 100644
--- a/pyaedt/modeler/__init__.py
+++ b/pyaedt/modeler/__init__.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
diff --git a/pyaedt/modeler/advanced_cad/__init__.py b/pyaedt/modeler/advanced_cad/__init__.py
index e69de29bb2d..9c4476773da 100644
--- a/pyaedt/modeler/advanced_cad/__init__.py
+++ b/pyaedt/modeler/advanced_cad/__init__.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
diff --git a/pyaedt/modeler/advanced_cad/actors.py b/pyaedt/modeler/advanced_cad/actors.py
index c68f198cbf0..811be43a412 100644
--- a/pyaedt/modeler/advanced_cad/actors.py
+++ b/pyaedt/modeler/advanced_cad/actors.py
@@ -1,4 +1,28 @@
-from pyaedt import pyaedt_function_handler
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+from pyaedt.generic.general_methods import pyaedt_function_handler
from pyaedt.generic.general_methods import read_json
from pyaedt.modeler.advanced_cad.multiparts import Actor
from pyaedt.modeler.advanced_cad.multiparts import MultiPartComponent
@@ -363,7 +387,7 @@ def speed_expression(self, s):
@pyaedt_function_handler()
def _add_speed(self, app):
app.variable_manager.set_variable(
- variable_name=self.speed_name, expression=self.speed_expression, description="radar speed"
+ name=self.speed_name, expression=self.speed_expression, description="radar speed"
)
# Update expressions for x and y position in app:
app[self.offset_names[0]] = (
diff --git a/pyaedt/modeler/advanced_cad/multiparts.py b/pyaedt/modeler/advanced_cad/multiparts.py
index 7f29aabbbbb..f57bde5199b 100644
--- a/pyaedt/modeler/advanced_cad/multiparts.py
+++ b/pyaedt/modeler/advanced_cad/multiparts.py
@@ -1,4 +1,27 @@
# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import os
from pyaedt.generic.filesystem import get_json_files
@@ -401,20 +424,18 @@ def position_in_app(self, app):
for m in range(3):
# app[self.offset_names[m]] = self.offset[m]
app.variable_manager.set_variable(
- variable_name=self.offset_names[m],
+ name=self.offset_names[m],
expression=self.offset[m],
description=self.name + " " + xyz[m] + "-position",
)
- app.variable_manager.set_variable(
- variable_name=self.yaw_name, expression=self.yaw, description=self.name + " yaw"
- )
+ app.variable_manager.set_variable(name=self.yaw_name, expression=self.yaw, description=self.name + " yaw")
app.variable_manager.set_variable(
- variable_name=self.pitch_name, expression=self.pitch, description=self.name + " pitch"
+ name=self.pitch_name, expression=self.pitch, description=self.name + " pitch"
)
app.variable_manager.set_variable(
- variable_name=self.roll_name, expression=self.roll, description=self.name + " roll"
+ name=self.roll_name, expression=self.roll, description=self.name + " roll"
)
cs_origin = self.offset_names
@@ -618,7 +639,7 @@ def speed_expression(self, s): # TODO: Add validation of the expression.
@pyaedt_function_handler()
def _add_speed(self, app):
app.variable_manager.set_variable(
- variable_name=self.speed_name, expression=self.speed_expression, description="object speed"
+ name=self.speed_name, expression=self.speed_expression, description="object speed"
)
# Update expressions for x and y position in app:
app[self.offset_names[0]] = (
diff --git a/pyaedt/modeler/advanced_cad/oms.py b/pyaedt/modeler/advanced_cad/oms.py
index 9f230692036..f496b0b56b2 100644
--- a/pyaedt/modeler/advanced_cad/oms.py
+++ b/pyaedt/modeler/advanced_cad/oms.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import os
import warnings
diff --git a/pyaedt/modeler/advanced_cad/parts.py b/pyaedt/modeler/advanced_cad/parts.py
index 87f5cbf0dd5..1d5809dd46a 100644
--- a/pyaedt/modeler/advanced_cad/parts.py
+++ b/pyaedt/modeler/advanced_cad/parts.py
@@ -1,6 +1,30 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import os
-from pyaedt import pyaedt_function_handler
+from pyaedt.generic.general_methods import pyaedt_function_handler
from pyaedt.modeler.geometry_operators import GeometryOperators
diff --git a/pyaedt/modeler/advanced_cad/stackup_3d.py b/pyaedt/modeler/advanced_cad/stackup_3d.py
index b9e9f37ac8e..84ad110bd08 100644
--- a/pyaedt/modeler/advanced_cad/stackup_3d.py
+++ b/pyaedt/modeler/advanced_cad/stackup_3d.py
@@ -1,7 +1,31 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
from collections import OrderedDict
import os
-from pyaedt import is_ironpython
+from pyaedt.generic.general_methods import is_ironpython
if not is_ironpython:
try:
@@ -806,7 +830,7 @@ def add_trace(
>>> from pyaedt import Hfss
>>> from pyaedt.modeler.stackup_3d import Stackup3D
- >>> hfss = Hfss(new_desktop_session=True)
+ >>> hfss = Hfss(new_desktop=True)
>>> my_stackup = Stackup3D(hfss, 2.5e9)
>>> gnd = my_stackup.add_ground_layer("gnd")
>>> my_stackup.add_dielectric_layer("diel1", thickness=1.5, material="Duroid (tm)")
@@ -1232,7 +1256,7 @@ class Stackup3D(object):
>>> from pyaedt import Hfss
>>> from pyaedt.modeler.stackup_3d import Stackup3D
- >>> hfss = Hfss(new_desktop_session=True)
+ >>> hfss = Hfss(new_desktop=True)
>>> my_stackup = Stackup3D(hfss, 2.5e9)
"""
@@ -2637,7 +2661,7 @@ class Trace(CommonObject, object):
--------
>>> from pyaedt import Hfss
>>> from pyaedt.modeler.stackup_3d import Stackup3D
- >>> hfss = Hfss(new_desktop_session=True)
+ >>> hfss = Hfss(new_desktop=True)
>>> my_stackup = Stackup3D(hfss, 2.5e9)
>>> gnd = my_stackup.add_ground_layer("gnd")
>>> my_stackup.add_dielectric_layer("diel1", thickness=1.5, material="Duroid (tm)")
@@ -3220,7 +3244,7 @@ def create_lumped_port(self, reference_layer, opposite_side=False, port_name=Non
--------
>>> from pyaedt import Hfss
>>> from pyaedt.modeler.stackup_3d import Stackup3D
- >>> hfss = Hfss(new_desktop_session=True)
+ >>> hfss = Hfss(new_desktop=True)
>>> my_stackup = Stackup3D(hfss, 2.5e9)
>>> gnd = my_stackup.add_ground_layer("gnd")
>>> my_stackup.add_dielectric_layer("diel1", thickness=1.5, material="Duroid (tm)")
@@ -3296,7 +3320,7 @@ class Polygon(CommonObject, object):
>>> from pyaedt import Hfss
>>> from pyaedt.modeler.stackup_3d import Stackup3D
- >>> hfss = Hfss(new_desktop_session=True)
+ >>> hfss = Hfss(new_desktop=True)
>>> my_stackup = Stackup3D(hfss, 2.5e9)
>>> gnd = my_stackup.add_ground_layer("gnd", thickness=None)
>>> my_stackup.add_dielectric_layer("diel1", thickness=1.5, material="Duroid (tm)")
diff --git a/pyaedt/modeler/cad/Modeler.py b/pyaedt/modeler/cad/Modeler.py
index be58a4ab7c6..848a2325642 100644
--- a/pyaedt/modeler/cad/Modeler.py
+++ b/pyaedt/modeler/cad/Modeler.py
@@ -1,4 +1,27 @@
# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
"""
This module contains these classes: `BaseCoordinateSystem`, `FaceCoordinateSystem`, `CoordinateSystem`, `Modeler`,
`Position`, and `SweepOptions`.
diff --git a/pyaedt/modeler/cad/Primitives.py b/pyaedt/modeler/cad/Primitives.py
index f6ab146fa0f..8119b97298d 100644
--- a/pyaedt/modeler/cad/Primitives.py
+++ b/pyaedt/modeler/cad/Primitives.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
"""
This module contains these Primitives classes: `Polyline` and `Primitives`.
"""
@@ -584,7 +608,7 @@ def solid_names(self):
Returns
-------
- List
+ list
"""
self._refresh_solids()
return self._solids
@@ -595,7 +619,7 @@ def sheet_names(self):
Returns
-------
- str
+ list
"""
self._refresh_sheets()
return self._sheets
@@ -606,7 +630,7 @@ def line_names(self):
Returns
-------
- str
+ list
"""
self._refresh_lines()
return self._lines
@@ -617,7 +641,7 @@ def unclassified_names(self):
Returns
-------
- str
+ list
"""
self._refresh_unclassified()
return self._unclassified
@@ -628,7 +652,7 @@ def object_names(self):
Returns
-------
- str
+ list
"""
self._refresh_object_types()
return [i for i in self._all_object_names if i not in self._unclassified and i not in self._points]
@@ -639,7 +663,7 @@ def point_names(self):
Returns
-------
- str
+ list
"""
self._refresh_points()
return self._points
@@ -2904,6 +2928,7 @@ def duplicate_around_axis(
str(clones),
]
vArg3 = ["NAME:Options", "DuplicateAssignments:=", duplicate_assignment]
+ self.add_new_objects()
added_objs = self.oeditor.DuplicateAroundAxis(vArg1, vArg2, vArg3)
self._duplicate_added_objects_tuple()
if is_3d_comp:
@@ -2972,6 +2997,7 @@ def duplicate_along_line(
vArg2.append("ZComponent:="), vArg2.append(Zpos)
vArg2.append("Numclones:="), vArg2.append(str(clones))
vArg3 = ["NAME:Options", "DuplicateAssignments:=", duplicate_assignment]
+ self.add_new_objects()
self.oeditor.DuplicateAlongLine(vArg1, vArg2, vArg3)
if is_3d_comp:
return self._duplicate_added_components_tuple()
@@ -3678,6 +3704,7 @@ def paste(self):
>>> oEditor.Paste
"""
+ self.add_new_objects()
self.oeditor.Paste()
new_objects = self.add_new_objects()
return new_objects
@@ -4607,6 +4634,108 @@ def get_vertices_of_line(self, assignment):
return position_list
+ @pyaedt_function_handler(
+ object_list="assignment_to_export",
+ removed_objects="assignment_to_remove",
+ fileName="file_name",
+ filePath="file_path",
+ fileFormat="file_format",
+ )
+ def export_3d_model(
+ self,
+ file_name="",
+ file_path="",
+ file_format=".step",
+ assignment_to_export=None,
+ assignment_to_remove=None,
+ major_version=-1,
+ minor_version=-1,
+ ):
+ """Export the 3D model.
+
+ Parameters
+ ----------
+ file_name : str, optional
+ Name of the file.
+ file_path : str, optional
+ Path for the file.
+ file_format : str, optional
+ Format of the file. The default is ``".step"``.
+ assignment_to_export : list, optional
+ List of objects to export. The default is ``None``.
+ assignment_to_remove : list, optional
+ List of objects to remove. The default is ``None``.
+ major_version : int, optional
+ File format major version. The default is -1.
+ minor_version : int, optional
+ File format major version. The default is -1.
+
+ Returns
+ -------
+ bool
+ ``True`` when successful, ``False`` when failed.
+
+ References
+ ----------
+
+ >>> oEditor.Export
+ """
+
+ if not file_name:
+ file_name = self.project_name + "_" + self.design_name
+ if not file_path:
+ file_path = self.working_directory
+ if assignment_to_export is None:
+ assignment_to_export = []
+ if assignment_to_remove is None:
+ assignment_to_remove = []
+
+ sub_regions = []
+ if self._app.settings.aedt_version > "2023.2":
+ sub_regions = [o for o in self.non_model_objects if self[o].history().command == "CreateSubRegion"]
+
+ if not assignment_to_export:
+ allObjects = self.object_names
+ if assignment_to_remove:
+ for rem in assignment_to_remove:
+ allObjects.remove(rem)
+ else:
+ if "Region" in allObjects:
+ allObjects.remove("Region")
+ for o in sub_regions:
+ allObjects.remove(o)
+ else:
+ allObjects = assignment_to_export[:]
+
+ self.logger.debug("Exporting {} objects".format(len(allObjects)))
+
+ # actual version supported by AEDT is 29.0
+ if major_version == -1:
+ if file_format in [".sm3", ".sat", ".sab"]:
+ major_version = 29
+ if minor_version == -1:
+ if file_format in [".sm3", ".sat", ".sab"]:
+ minor_version = 0
+ stringa = ",".join(allObjects)
+ arg = [
+ "NAME:ExportParameters",
+ "AllowRegionDependentPartSelectionForPMLCreation:=",
+ True,
+ "AllowRegionSelectionForPMLCreation:=",
+ True,
+ "Selections:=",
+ stringa,
+ "File Name:=",
+ os.path.join(file_path, file_name + file_format).replace("\\", "/"),
+ "Major Version:=",
+ major_version,
+ "Minor Version:=",
+ minor_version,
+ ]
+
+ self.oeditor.Export(arg)
+ return True
+
@pyaedt_function_handler(filename="input_file")
def import_3d_cad(
self,
@@ -6568,7 +6697,7 @@ def create_polyline(
>>> from pyaedt.modeler.cad.polylines import PolylineSegment
>>> from pyaedt import Desktop
>>> from pyaedt import Maxwell3d
- >>> desktop=Desktop(specified_version="2021.2", new_desktop_session=False)
+ >>> desktop=Desktop(version="2021.2", new_desktop=False)
>>> aedtapp = Maxwell3d()
>>> aedtapp.modeler.model_units = "mm"
>>> modeler = aedtapp.modeler
diff --git a/pyaedt/modeler/cad/Primitives2D.py b/pyaedt/modeler/cad/Primitives2D.py
index bec2cae27d6..c2157373ce2 100644
--- a/pyaedt/modeler/cad/Primitives2D.py
+++ b/pyaedt/modeler/cad/Primitives2D.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
from pyaedt.generic.general_methods import pyaedt_function_handler
from pyaedt.modeler.cad.Primitives import GeometryModeler
diff --git a/pyaedt/modeler/cad/Primitives3D.py b/pyaedt/modeler/cad/Primitives3D.py
index e712ba8b18f..59378eddad0 100644
--- a/pyaedt/modeler/cad/Primitives3D.py
+++ b/pyaedt/modeler/cad/Primitives3D.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import copy
import json
from math import asin
@@ -1469,18 +1493,8 @@ def insert_3d_component(
else:
is_project_dataset = False
dsname = key
- self._app.create_dataset(
- dsname,
- dat["x"],
- dat["y"],
- dat["z"],
- dat["v"],
- is_project_dataset,
- dat["xunit"],
- dat["yunit"],
- dat["zunit"],
- dat["vunit"],
- )
+ self._app.create_dataset(dsname, dat["x"], dat["y"], dat["z"], dat["v"], is_project_dataset,
+ dat["xunit"], dat["yunit"], dat["zunit"], dat["vunit"])
udm_obj = self._create_user_defined_component(new_object_name)
if name and not auxiliary_parameters:
udm_obj.name = name
@@ -1536,7 +1550,7 @@ def insert_3d_component(
cs.ref_cs = coordinate_system
if aux_dict.get("monitors", None):
temp_proj_name = generate_unique_project_name()
- ipkapp_temp = Icepak(projectname=os.path.join(self._app.toolkit_directory, temp_proj_name))
+ ipkapp_temp = Icepak(project=os.path.join(self._app.toolkit_directory, temp_proj_name))
ipkapp_temp.delete_design(ipkapp_temp.design_name)
self._app.oproject.CopyDesign(self._app.design_name)
ipkapp_temp.oproject.Paste()
diff --git a/pyaedt/modeler/cad/__init__.py b/pyaedt/modeler/cad/__init__.py
index e69de29bb2d..9c4476773da 100644
--- a/pyaedt/modeler/cad/__init__.py
+++ b/pyaedt/modeler/cad/__init__.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
diff --git a/pyaedt/modeler/cad/component_array.py b/pyaedt/modeler/cad/component_array.py
index b0da2e6bd38..f175115721d 100644
--- a/pyaedt/modeler/cad/component_array.py
+++ b/pyaedt/modeler/cad/component_array.py
@@ -1,12 +1,36 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
from __future__ import absolute_import
from collections import OrderedDict
import os
import re
-from pyaedt import pyaedt_function_handler
from pyaedt.generic.constants import AEDT_UNITS
from pyaedt.generic.general_methods import _uname
+from pyaedt.generic.general_methods import pyaedt_function_handler
from pyaedt.generic.general_methods import read_csv
@@ -25,7 +49,7 @@ class ComponentArray(object):
Basic usage demonstrated with an HFSS design with an existing array:
>>> from pyaedt import Hfss
- >>> aedtapp = Hfss(projectname="Array.aedt")
+ >>> aedtapp = Hfss(project="Array.aedt")
>>> array_names = aedtapp.component_array_names[0]
>>> array = aedtapp.component_array[array_names[0]]
"""
@@ -386,7 +410,7 @@ def parse_array_info_from_csv(self, input_file): # pragma: no cover
Examples
--------
>>> from pyaedt import Hfss
- >>> aedtapp = Hfss(projectname="Array.aedt")
+ >>> aedtapp = Hfss(project="Array.aedt")
>>> array_names = aedtapp.component_array_names[0]
>>> array = aedtapp.component_array[array_names[0]]
>>> array_csv = array.export_array_info()
diff --git a/pyaedt/modeler/cad/components_3d.py b/pyaedt/modeler/cad/components_3d.py
index 1ed2f3feced..8595dfb1686 100644
--- a/pyaedt/modeler/cad/components_3d.py
+++ b/pyaedt/modeler/cad/components_3d.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
from __future__ import absolute_import
from collections import OrderedDict
@@ -6,10 +30,10 @@
import re
import warnings
-from pyaedt import Edb
-from pyaedt import pyaedt_function_handler
+from pyaedt.edb import Edb
from pyaedt.generic.desktop_sessions import _edb_sessions
from pyaedt.generic.general_methods import _uname
+from pyaedt.generic.general_methods import pyaedt_function_handler
from pyaedt.modeler.cad.elements3d import BinaryTreeNode
from pyaedt.modeler.cad.elements3d import _dict2arg
diff --git a/pyaedt/modeler/cad/elements3d.py b/pyaedt/modeler/cad/elements3d.py
index ea55690aa8a..c609c3855f5 100644
--- a/pyaedt/modeler/cad/elements3d.py
+++ b/pyaedt/modeler/cad/elements3d.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
from __future__ import absolute_import
from collections import OrderedDict
@@ -1116,7 +1140,6 @@ def coordinate_system(self, new_coordinate_system):
coordinate_system = ["NAME:Orientation", "Value:=", new_coordinate_system]
self._change_property(coordinate_system)
self._point_coordinate_system = new_coordinate_system
- return True
@pyaedt_function_handler()
def delete(self):
diff --git a/pyaedt/modeler/cad/object3d.py b/pyaedt/modeler/cad/object3d.py
index 423a30436b7..26029d9089d 100644
--- a/pyaedt/modeler/cad/object3d.py
+++ b/pyaedt/modeler/cad/object3d.py
@@ -1,4 +1,27 @@
# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
"""
This module contains these classes: `Components3DLayout`,`CircuitComponent',
`EdgePrimitive`, `EdgeTypePrimitive`, `FacePrimitive`, `Geometries3DLayout`,
diff --git a/pyaedt/modeler/cad/polylines.py b/pyaedt/modeler/cad/polylines.py
index 3df25284627..c6c23443f13 100644
--- a/pyaedt/modeler/cad/polylines.py
+++ b/pyaedt/modeler/cad/polylines.py
@@ -1,13 +1,37 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
from __future__ import absolute_import
import math
import warnings
-from pyaedt import pyaedt_function_handler
from pyaedt.application.Variables import decompose_variable_value
from pyaedt.generic.constants import PLANE
from pyaedt.generic.constants import unit_converter
from pyaedt.generic.general_methods import _dim_arg
+from pyaedt.generic.general_methods import pyaedt_function_handler
from pyaedt.modeler.cad.object3d import Object3d
from pyaedt.modeler.geometry_operators import GeometryOperators
diff --git a/pyaedt/modeler/calculators.py b/pyaedt/modeler/calculators.py
index 5e802073ac8..621baaa23ab 100644
--- a/pyaedt/modeler/calculators.py
+++ b/pyaedt/modeler/calculators.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import math
from pyaedt import constants
diff --git a/pyaedt/modeler/circuits/PrimitivesCircuit.py b/pyaedt/modeler/circuits/PrimitivesCircuit.py
index 87dc0caf6c1..098cbcef3eb 100644
--- a/pyaedt/modeler/circuits/PrimitivesCircuit.py
+++ b/pyaedt/modeler/circuits/PrimitivesCircuit.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import math
import os
import random
@@ -318,7 +342,7 @@ def create_interface_port(self, name, location=None, angle=0):
return False
@pyaedt_function_handler()
- def create_page_port(self, name, location=[], angle=0):
+ def create_page_port(self, name, location=None, angle=0):
"""Create a page port.
Parameters
@@ -326,7 +350,8 @@ def create_page_port(self, name, location=[], angle=0):
name : str
Name of the port.
location : list, optional
- Position on the X and Y axis. The default is ``None``.
+ Position on the X and Y axis.
+ If not provided the default is ``None``, in which case an empty list is set.
angle : optional
Angle rotation in degrees. The default is ``0``.
@@ -340,6 +365,7 @@ def create_page_port(self, name, location=[], angle=0):
>>> oEditor.CreatePagePort
"""
+ location = [] if location is None else location
xpos, ypos = self._get_location(location)
id = self.create_unique_id()
diff --git a/pyaedt/modeler/circuits/PrimitivesEmit.py b/pyaedt/modeler/circuits/PrimitivesEmit.py
index 34f65476fce..89063faae70 100644
--- a/pyaedt/modeler/circuits/PrimitivesEmit.py
+++ b/pyaedt/modeler/circuits/PrimitivesEmit.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
from collections import defaultdict
from pyaedt.emit_core import emit_constants as emit_consts
@@ -764,7 +788,7 @@ def set_band_start_frequency(self, band_node, band_start_freq, units=""):
Examples
--------
>>> from pyaedt import Emit
- >>> aedtapp = Emit(new_desktop_session=False)
+ >>> aedtapp = Emit(new_desktop=False)
>>> radio = aedtapp.modeler.components.create_component("New Radio")
>>> band = radio.bands()[0]
>>> start_freq = 10
@@ -810,7 +834,7 @@ def set_band_stop_frequency(self, band_node, band_stop_freq, units=""):
Examples
--------
>>> from pyaedt import Emit
- >>> aedtapp = Emit(new_desktop_session=False)
+ >>> aedtapp = Emit(new_desktop=False)
>>> radio = aedtapp.modeler.components.create_component("New Radio")
>>> band = radio.bands()[0]
>>> stop_freq = 10
diff --git a/pyaedt/modeler/circuits/PrimitivesMaxwellCircuit.py b/pyaedt/modeler/circuits/PrimitivesMaxwellCircuit.py
index b01717f0d6a..9fedbb602de 100644
--- a/pyaedt/modeler/circuits/PrimitivesMaxwellCircuit.py
+++ b/pyaedt/modeler/circuits/PrimitivesMaxwellCircuit.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
from pyaedt.generic.general_methods import pyaedt_function_handler
from pyaedt.modeler.circuits.PrimitivesCircuit import CircuitComponents
diff --git a/pyaedt/modeler/circuits/PrimitivesNexxim.py b/pyaedt/modeler/circuits/PrimitivesNexxim.py
index a4e81202ac9..050cff65412 100644
--- a/pyaedt/modeler/circuits/PrimitivesNexxim.py
+++ b/pyaedt/modeler/circuits/PrimitivesNexxim.py
@@ -1,11 +1,33 @@
# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import os
import random
import re
import time
import warnings
-from pyaedt import settings
from pyaedt.application.Variables import decompose_variable_value
from pyaedt.generic.LoadAEDTFile import load_keyword_in_aedt_file
from pyaedt.generic.constants import AEDT_UNITS
@@ -13,6 +35,7 @@
from pyaedt.generic.general_methods import is_linux
from pyaedt.generic.general_methods import open_file
from pyaedt.generic.general_methods import pyaedt_function_handler
+from pyaedt.generic.settings import settings
from pyaedt.modeler.circuits.PrimitivesCircuit import CircuitComponents
from pyaedt.modeler.circuits.PrimitivesCircuit import ComponentCatalog
from pyaedt.modeler.circuits.object3dcircuit import CircuitComponent
@@ -1218,8 +1241,8 @@ def create_new_component_from_symbol(
time_stamp=1591858313,
description="",
refbase="x",
- parameters=[],
- values=[],
+ parameters=None,
+ values=None,
gref="",
):
"""Create a component from a symbol.
@@ -1237,9 +1260,11 @@ def create_new_component_from_symbol(
refbase : str, optional
Reference base. The default is ``"U"``.
parameters : list
- List of parameters. The default is ``[]``.
+ List of parameters.
+ If not provided the default is ``None``, in which case an empty list is set.
values : list
- List of parameter values. The default is ``[]``.
+ List of parameter values.
+ If not provided the default is ``None``, in which case an empty list is set.
gref : str, optional
Global Reference
@@ -1254,6 +1279,8 @@ def create_new_component_from_symbol(
>>> oModelManager.Add
>>> oComponentManager.Add
"""
+ parameters = [] if parameters is None else parameters
+ values = [] if values is None else values
arg = [
"NAME:" + name,
"Info:=",
@@ -1957,7 +1984,7 @@ def create_component_from_spicemodel(
Examples
--------
>>> from pyaedt import Circuit
- >>> cir = Circuit(specified_version="2023.2")
+ >>> cir = Circuit(version="2023.2")
>>> model = os.path.join("Your path", "test.lib")
>>> cir.modeler.schematic.create_component_from_spicemodel(input_file=model,model="GRM1234",symbol="nexx_cap")
>>> cir.release_desktop(False, False)
diff --git a/pyaedt/modeler/circuits/PrimitivesTwinBuilder.py b/pyaedt/modeler/circuits/PrimitivesTwinBuilder.py
index 1a76aa0b9f8..499538aaf40 100644
--- a/pyaedt/modeler/circuits/PrimitivesTwinBuilder.py
+++ b/pyaedt/modeler/circuits/PrimitivesTwinBuilder.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
from pyaedt.generic.general_methods import pyaedt_function_handler
from pyaedt.modeler.circuits.PrimitivesCircuit import CircuitComponents
from pyaedt.modeler.circuits.PrimitivesCircuit import ComponentCatalog
diff --git a/pyaedt/modeler/circuits/__init__.py b/pyaedt/modeler/circuits/__init__.py
index e69de29bb2d..9c4476773da 100644
--- a/pyaedt/modeler/circuits/__init__.py
+++ b/pyaedt/modeler/circuits/__init__.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
diff --git a/pyaedt/modeler/circuits/object3dcircuit.py b/pyaedt/modeler/circuits/object3dcircuit.py
index a6d8dcd3d56..ac3bb1c2888 100644
--- a/pyaedt/modeler/circuits/object3dcircuit.py
+++ b/pyaedt/modeler/circuits/object3dcircuit.py
@@ -1,15 +1,38 @@
# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
from __future__ import absolute_import
from collections import OrderedDict
import math
import time
-from pyaedt import pyaedt_function_handler
from pyaedt.application.Variables import decompose_variable_value
from pyaedt.generic.constants import AEDT_UNITS
from pyaedt.generic.general_methods import _arg2dict
from pyaedt.generic.general_methods import _dim_arg
+from pyaedt.generic.general_methods import pyaedt_function_handler
from pyaedt.modeler.cad.elements3d import _dict2arg
from pyaedt.modeler.geometry_operators import GeometryOperators as go
diff --git a/pyaedt/modeler/geometry_operators.py b/pyaedt/modeler/geometry_operators.py
index d55705d34c7..00aded2db2b 100644
--- a/pyaedt/modeler/geometry_operators.py
+++ b/pyaedt/modeler/geometry_operators.py
@@ -1,4 +1,27 @@
# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import math
import re
import sys
@@ -102,7 +125,7 @@ def parse_dim_arg(string, scale_to_unit=None, variable_manager=None):
else:
if variable_manager:
if not variable_manager.set_variable("temp_var", string):
- if not variable_manager.set_variable("temp_var", string, postprocessing=True):
+ if not variable_manager.set_variable("temp_var", string, is_post_processing=True):
return string
value = variable_manager["temp_var"].value / sunit
del variable_manager["temp_var"]
diff --git a/pyaedt/modeler/modeler2d.py b/pyaedt/modeler/modeler2d.py
index 7698682ad46..009787dd312 100644
--- a/pyaedt/modeler/modeler2d.py
+++ b/pyaedt/modeler/modeler2d.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import math
from warnings import warn
diff --git a/pyaedt/modeler/modeler3d.py b/pyaedt/modeler/modeler3d.py
index 4be69c3f03e..791e8ae0c1a 100644
--- a/pyaedt/modeler/modeler3d.py
+++ b/pyaedt/modeler/modeler3d.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
from __future__ import absolute_import # noreorder
import copy
@@ -7,13 +31,13 @@
import warnings
from pyaedt.application.Variables import generate_validation_errors
-from pyaedt.generic.constants import CSS4_COLORS
from pyaedt.generic.general_methods import GrpcApiError
from pyaedt.generic.general_methods import generate_unique_name
from pyaedt.generic.general_methods import open_file
from pyaedt.generic.general_methods import pyaedt_function_handler
from pyaedt.modeler.cad.Primitives3D import Primitives3D
from pyaedt.modeler.geometry_operators import GeometryOperators
+from pyaedt.modules.solutions import nastran_to_stl
class Modeler3D(Primitives3D):
@@ -992,328 +1016,6 @@ def objects_in_bounding_box(self, bounding_box, check_solids=True, check_lines=T
return objects
- @pyaedt_function_handler()
- def _parse_nastran(self, file_path):
-
- nas_to_dict = {"Points": [], "PointsId": {}, "Assemblies": {}}
- includes = []
-
- def parse_lines(input_lines, input_pid=0, in_assembly="Main"):
- if in_assembly not in nas_to_dict["Assemblies"]:
- nas_to_dict["Assemblies"][in_assembly] = {"Triangles": {}, "Solids": {}, "Lines": {}}
- for lk in range(len(input_lines)):
- line = input_lines[lk]
- line_type = line[:8].strip()
- if line.startswith("$") or line.startswith("*"):
- continue
- elif line_type in ["GRID", "CTRIA3", "CQUAD4"]:
- grid_id = int(line[8:16])
- if line_type in ["CTRIA3", "CQUAD4"]:
- tria_id = int(line[16:24])
- if tria_id not in nas_to_dict["Assemblies"][in_assembly]["Triangles"]:
- nas_to_dict["Assemblies"][in_assembly]["Triangles"][tria_id] = []
- n1 = line[24:32].strip()
- if "-" in n1[1:] and "e" not in n1[1:].lower():
- n1 = n1[0] + n1[1:].replace("-", "e-")
- n2 = line[32:40].strip()
- if "-" in n2[1:] and "e" not in n2[1:].lower():
- n2 = n2[0] + n2[1:].replace("-", "e-")
- n3 = line[40:48].strip()
- if "-" in n3[1:] and "e" not in n3[1:].lower():
- n3 = n3[0] + n3[1:].replace("-", "e-")
- if line_type == "GRID":
- nas_to_dict["PointsId"][grid_id] = input_pid
- nas_to_dict["Points"].append([float(n1), float(n2), float(n3)])
- input_pid += 1
- elif line_type == "CTRIA3":
- tri = [
- nas_to_dict["PointsId"][int(n1)],
- nas_to_dict["PointsId"][int(n2)],
- nas_to_dict["PointsId"][int(n3)],
- ]
- nas_to_dict["Assemblies"][in_assembly]["Triangles"][tria_id].append(tri)
- elif line_type == "CQUAD4":
- n4 = line[48:56].strip()
- if "-" in n4[1:] and "e" not in n4[1:].lower():
- n4 = n4[0] + n4[1:].replace("-", "e-")
- tri = [
- nas_to_dict["PointsId"][int(n1)],
- nas_to_dict["PointsId"][int(n2)],
- nas_to_dict["PointsId"][int(n3)],
- ]
- nas_to_dict["Assemblies"][in_assembly]["Triangles"][tria_id].append(tri)
- tri = [
- nas_to_dict["PointsId"][int(n1)],
- nas_to_dict["PointsId"][int(n3)],
- nas_to_dict["PointsId"][int(n4)],
- ]
- nas_to_dict["Assemblies"][in_assembly]["Triangles"][tria_id].append(tri)
- elif line_type in ["GRID*", "CTRIA3*", "CQUAD4*"]:
- grid_id = int(line[8:24])
- if line_type in ["CTRIA3*", "CQUAD4*"]:
- tria_id = int(line[24:40])
- if tria_id not in nas_to_dict["Assemblies"][in_assembly]["Triangles"]:
- nas_to_dict["Assemblies"][in_assembly]["Triangles"][tria_id] = []
- n1 = line[40:56].strip()
- if "-" in n1[1:] and "e" not in n1[1:].lower():
- n1 = n1[0] + n1[1:].replace("-", "e-")
- n2 = line[56:72].strip()
- if "-" in n2[1:] and "e" not in n2[1:].lower():
- n2 = n2[0] + n2[1:].replace("-", "e-")
-
- n3 = line[72:88].strip()
- idx = 88
- if not n3 or n3.startswith("*"):
- lk += 1
- n3 = input_lines[lk][8:24].strip()
- idx = 24
- if "-" in n3[1:] and "e" not in n3[1:].lower():
- n3 = n3[0] + n3[1:].replace("-", "e-")
- if line_type == "GRID*":
- try:
- nas_to_dict["Points"].append([float(n1), float(n2), float(n3)])
- except Exception: # nosec
- continue
- nas_to_dict["PointsId"][grid_id] = input_pid
- input_pid += 1
- elif line_type == "CTRIA3*":
- tri = [
- nas_to_dict["PointsId"][int(n1)],
- nas_to_dict["PointsId"][int(n2)],
- nas_to_dict["PointsId"][int(n3)],
- ]
- nas_to_dict["Assemblies"][in_assembly]["Triangles"][tria_id].append(tri)
- elif line_type == "CQUAD4*":
- n4 = input_lines[lk][idx : idx + 16].strip()
- if not n4 or n4.startswith("*"):
- lk += 1
- n4 = input_lines[lk][8:24].strip()
- if "-" in n4[1:] and "e" not in n4[1:].lower():
- n4 = n4[0] + n4[1:].replace("-", "e-")
- tri = [
- nas_to_dict["PointsId"][int(n1)],
- nas_to_dict["PointsId"][int(n2)],
- nas_to_dict["PointsId"][int(n3)],
- ]
- nas_to_dict["Assemblies"][in_assembly]["Triangles"][tria_id].append(tri)
- tri = [
- nas_to_dict["PointsId"][int(n1)],
- nas_to_dict["PointsId"][int(n3)],
- nas_to_dict["PointsId"][int(n4)],
- ]
- nas_to_dict["Assemblies"][in_assembly]["Triangles"][tria_id].append(tri)
- elif line_type in [
- "CTETRA",
- "CPYRAM",
- "CPYRA",
- ]:
- # obj_id = line[8:16].strip()
- n = []
- el_id = line[16:24].strip()
- if el_id not in nas_to_dict["Assemblies"][in_assembly]["Solids"]:
- nas_to_dict["Assemblies"][in_assembly]["Solids"][el_id] = []
-
- n.append(int(line[24:32]))
- n.append(int(line[32:40]))
- n.append(int(line[40:48]))
- n.append(int(line[48:56]))
- if line_type in ["CPYRA", "CPYRAM"]:
- n.append(int(line[56:64]))
-
- from itertools import combinations
-
- for k in list(combinations(n, 3)):
- # tri = [int(k[0]), int(k[1]), int(k[2])]
- tri = [
- nas_to_dict["PointsId"][int(k[0])],
- nas_to_dict["PointsId"][int(k[1])],
- nas_to_dict["PointsId"][int(k[2])],
- ]
- tri.sort()
- tri = tuple(tri)
- nas_to_dict["Assemblies"][in_assembly]["Solids"][el_id].append(tri)
-
- elif line_type in [
- "CTETRA*",
- "CPYRAM*",
- "CPYRA*",
- ]:
- # obj_id = line[8:24].strip()
- n = []
- el_id = line[24:40].strip()
- if el_id not in nas_to_dict["Assemblies"][in_assembly]["Solids"]:
- nas_to_dict["Assemblies"][in_assembly]["Solids"][el_id] = []
- # n.append(line[24:40].strip())
- n.append(line[40:56].strip())
-
- n.append(line[56:72].strip())
- lk += 1
- n.extend([input_lines[lk][i : i + 16] for i in range(16, len(input_lines[lk]), 16)])
-
- from itertools import combinations
-
- if line_type == "CTETRA*":
- for k in list(combinations(n, 3)):
- # tri = [int(k[0]), int(k[1]), int(k[2])]
- tri = [
- nas_to_dict["PointsId"][int(k[0])],
- nas_to_dict["PointsId"][int(k[1])],
- nas_to_dict["PointsId"][int(k[2])],
- ]
- tri.sort()
- tri = tuple(tri)
- nas_to_dict["Assemblies"][in_assembly]["Solids"][el_id].append(tri)
- else:
- spli1 = [n[0], n[1], n[2], n[4]]
- for k in list(combinations(spli1, 3)):
- tri = [
- nas_to_dict["PointsId"][int(k[0])],
- nas_to_dict["PointsId"][int(k[1])],
- nas_to_dict["PointsId"][int(k[2])],
- ]
- tri.sort()
- tri = tuple(tri)
- nas_to_dict["Assemblies"][in_assembly]["Solids"][el_id].append(tri)
- spli1 = [n[0], n[2], n[3], n[4]]
- for k in list(combinations(spli1, 3)):
- tri = [
- nas_to_dict["PointsId"][int(k[0])],
- nas_to_dict["PointsId"][int(k[1])],
- nas_to_dict["PointsId"][int(k[2])],
- ]
- tri.sort()
- tri = tuple(tri)
- nas_to_dict["Assemblies"][in_assembly]["Solids"][el_id].append(tri)
-
- elif line_type in ["CROD", "CBEAM", "CBAR"]:
- obj_id = int(line[16:24])
- n1 = int(line[24:32])
- n2 = int(line[32:40])
- if obj_id in nas_to_dict["Assemblies"][in_assembly]["Lines"]:
- nas_to_dict["Assemblies"][in_assembly]["Lines"][obj_id].append(
- [nas_to_dict["PointsId"][int(n1)], nas_to_dict["PointsId"][int(n2)]]
- )
- else:
- nas_to_dict["Assemblies"][in_assembly]["Lines"][obj_id] = [
- [nas_to_dict["PointsId"][int(n1)], nas_to_dict["PointsId"][int(n2)]]
- ]
- elif line_type in ["CROD*", "CBEAM*", "CBAR*"]:
- obj_id = int(line[24:40])
- n1 = int(line[40:56])
- n2 = int(line[56:72])
- if obj_id in nas_to_dict["Assemblies"][in_assembly]["Lines"]:
- nas_to_dict["Assemblies"][in_assembly]["Lines"][obj_id].append(
- [nas_to_dict["PointsId"][int(n1)], nas_to_dict["PointsId"][int(n2)]]
- )
- else:
- nas_to_dict["Assemblies"][in_assembly]["Lines"][obj_id] = [
- [nas_to_dict["PointsId"][int(n1)], nas_to_dict["PointsId"][int(n2)]]
- ]
- return input_pid
-
- self.logger.reset_timer()
- self.logger.info("Loading file")
- with open_file(file_path, "r") as f:
- lines = f.read().splitlines()
- for line in lines:
- if line.startswith("INCLUDE"):
- includes.append(line.split(" ")[1].replace("'", "").strip())
- pid = parse_lines(lines)
- for include in includes:
- with open_file(os.path.join(os.path.dirname(file_path), include), "r") as f:
- lines = f.read().splitlines()
- name = include.split(".")[0]
- if name in self.oeditor.GetChildNames("Groups"):
- name = generate_unique_name(include.split(".")[0], n=2)
- pid = parse_lines(lines, pid, name)
- self.logger.info("File loaded")
- for assembly in list(nas_to_dict["Assemblies"].keys())[::]:
- if (
- nas_to_dict["Assemblies"][assembly]["Triangles"]
- == nas_to_dict["Assemblies"][assembly]["Solids"]
- == nas_to_dict["Assemblies"][assembly]["Lines"]
- == {}
- ):
- del nas_to_dict["Assemblies"][assembly]
- return nas_to_dict
-
- @pyaedt_function_handler()
- def _write_stl(self, nas_to_dict, decimation, enable_planar_merge, pv):
- def _write_solid_stl(triangle, pp):
- try:
- # points = [nas_to_dict["Points"][id] for id in triangle]
- points = [pp[i] for i in triangle]
- except KeyError: # pragma: no cover
- return
- fc = GeometryOperators.get_polygon_centroid(points)
- v1 = points[0]
- v2 = points[1]
- cv1 = GeometryOperators.v_points(fc, v1)
- cv2 = GeometryOperators.v_points(fc, v2)
- if cv2[0] == cv1[0] == 0.0 and cv2[1] == cv1[1] == 0.0:
- n = [0, 0, 1] # pragma: no cover
- elif cv2[0] == cv1[0] == 0.0 and cv2[2] == cv1[2] == 0.0:
- n = [0, 1, 0] # pragma: no cover
- elif cv2[1] == cv1[1] == 0.0 and cv2[2] == cv1[2] == 0.0:
- n = [1, 0, 0] # pragma: no cover
- else:
- n = GeometryOperators.v_cross(cv1, cv2)
-
- normal = GeometryOperators.normalize_vector(n)
- if normal:
- f.write(" facet normal {} {} {}\n".format(normal[0], normal[1], normal[2]))
- f.write(" outer loop\n")
- f.write(" vertex {} {} {}\n".format(points[0][0], points[0][1], points[0][2]))
- f.write(" vertex {} {} {}\n".format(points[1][0], points[1][1], points[1][2]))
- f.write(" vertex {} {} {}\n".format(points[2][0], points[2][1], points[2][2]))
- f.write(" endloop\n")
- f.write(" endfacet\n")
-
- self.logger.info("Creating STL file with detected faces")
- enable_stl_merge = False if enable_planar_merge == "False" or enable_planar_merge is False else True
-
- def decimate(points_in, faces_in):
- fin = [[3] + list(i) for i in faces_in]
- mesh = pv.PolyData(points_in, faces=fin)
- new_mesh = mesh.decimate_pro(decimation, preserve_topology=True, boundary_vertex_deletion=False)
- points_out = list(new_mesh.points)
- faces_out = [i[1:] for i in new_mesh.faces.reshape(-1, 4) if i[0] == 3]
- return points_out, faces_out
-
- output_stls = []
- for assembly_name, assembly in nas_to_dict["Assemblies"].items():
- output_stl = os.path.join(self._app.working_directory, assembly_name + ".stl")
- f = open(output_stl, "w")
- for tri_id, triangles in assembly["Triangles"].items():
- tri_out = triangles
- p_out = nas_to_dict["Points"][::]
- if decimation > 0 and len(triangles) > 20:
- p_out, tri_out = decimate(nas_to_dict["Points"], tri_out)
- f.write("solid Sheet_{}\n".format(tri_id))
- if enable_planar_merge == "Auto" and len(tri_out) > 50000:
- enable_stl_merge = False # pragma: no cover
- for triangle in tri_out:
- _write_solid_stl(triangle, p_out)
- f.write("endsolid\n")
- for solidid, solid_triangles in assembly["Solids"].items():
- f.write("solid Solid_{}\n".format(solidid))
- import pandas as pd
-
- df = pd.Series(solid_triangles)
- tri_out = df.drop_duplicates(keep=False).to_list()
- p_out = nas_to_dict["Points"][::]
- if decimation > 0 and len(solid_triangles) > 20:
- p_out, tri_out = decimate(nas_to_dict["Points"], tri_out)
- if enable_planar_merge == "Auto" and len(tri_out) > 50000:
- enable_stl_merge = False # pragma: no cover
- for triangle in tri_out:
- _write_solid_stl(triangle, p_out)
- f.write("endsolid\n")
- f.close()
- output_stls.append(output_stl)
- self.logger.info("STL file created")
- return output_stls, enable_stl_merge
-
@pyaedt_function_handler()
def import_nastran(
self,
@@ -1359,95 +1061,19 @@ def import_nastran(
-------
List of :class:`pyaedt.modeler.Object3d.Object3d`
"""
- pv = None
- if decimation > 0 or preview:
- try:
- import pyvista as pv
- except Exception: # pragma: no cover
- self.logger.error("Package pyvista is needed to perform model simplification.")
- self.logger.error("Please install it using pip.")
- decimation = 0
- preview = False
autosave = (
True if self._app.odesktop.GetRegistryInt("Desktop/Settings/ProjectOptions/DoAutoSave") == 1 else False
)
self._app.odesktop.EnableAutoSave(False)
-
- nas_to_dict = self._parse_nastran(file_path)
-
objs_before = [i for i in self.object_names]
- empty = True
- for assembly in nas_to_dict["Assemblies"].values():
- if assembly["Triangles"] or assembly["Solids"] or assembly["Lines"]:
- empty = False
- break
- if empty: # pragma: no cover
- self.logger.error("Failed to import file. Check the model and retry")
- return False
- output_stls, enable_stl_merge = self._write_stl(nas_to_dict, decimation, enable_planar_merge, pv)
- if preview:
- if decimation > 0:
- pl = pv.Plotter(shape=(1, 2))
- else: # pragma: no cover
- pl = pv.Plotter()
- dargs = dict(show_edges=True)
- css4_colors = list(CSS4_COLORS.values())
- colors = []
- color_by_assembly = True
- if len(nas_to_dict["Assemblies"]) == 1:
- color_by_assembly = False
-
- def preview_pyvista(dict_in):
- k = 0
- p_out = nas_to_dict["Points"][::]
- for assembly in dict_in["Assemblies"].values():
- if color_by_assembly:
- h = css4_colors[k].lstrip("#")
- colors.append(tuple(int(h[i : i + 2], 16) for i in (0, 2, 4)))
- k += 1
-
- for triangles in assembly["Triangles"].values():
- tri_out = triangles
- fin = [[3] + list(i) for i in tri_out]
- if not color_by_assembly:
- h = css4_colors[k].lstrip("#")
- colors.append(tuple(int(h[i : i + 2], 16) for i in (0, 2, 4)))
- k = k + 1 if k < len(css4_colors) - 1 else 0
- pl.add_mesh(pv.PolyData(p_out, faces=fin), color=colors[-1], **dargs)
-
- for triangles in assembly["Solids"].values():
- import pandas as pd
-
- df = pd.Series(triangles)
- tri_out = df.drop_duplicates(keep=False).to_list()
- p_out = nas_to_dict["Points"][::]
- fin = [[3] + list(i) for i in tri_out]
- if not color_by_assembly:
- h = css4_colors[k].lstrip("#")
- colors.append(tuple(int(h[i : i + 2], 16) for i in (0, 2, 4)))
- k = k + 1 if k < len(css4_colors) - 1 else 0
-
- pl.add_mesh(pv.PolyData(p_out, faces=fin), color=colors[-1], **dargs)
-
- preview_pyvista(nas_to_dict)
- pl.add_text("Input mesh", font_size=24)
- pl.reset_camera()
- if decimation > 0 and output_stls:
- k = 0
- pl.reset_camera()
- pl.subplot(0, 1)
- for output_stl in output_stls:
- mesh = pv.read(output_stl)
- h = css4_colors[k].lstrip("#")
- colors.append(tuple(int(h[i : i + 2], 16) for i in (0, 2, 4)))
- pl.add_mesh(mesh, color=colors[-1], **dargs)
- k = k + 1 if k < len(css4_colors) - 1 else 0
- pl.add_text("Decimated mesh", font_size=24)
- pl.reset_camera()
- pl.link_views()
- if "PYTEST_CURRENT_TEST" not in os.environ:
- pl.show() # pragma: no cover
- self.logger.info("STL files created")
+
+ output_stls, nas_to_dict, enable_stl_merge = nastran_to_stl(
+ input_file=file_path,
+ decimation=decimation,
+ output_folder=self._app.working_directory,
+ enable_planar_merge=enable_planar_merge,
+ preview=preview,
+ )
if save_only_stl:
return output_stls
@@ -1462,10 +1088,14 @@ def preview_pyvista(dict_in):
merge_planar_faces=enable_stl_merge,
)
self.logger.info("Model {} imported".format(os.path.split(output_stl)[-1]))
+ self._app.save_project()
if group_parts:
self.logger.info("Grouping parts...")
aedt_objs = self.object_names[::]
for assembly, _ in nas_to_dict["Assemblies"].items():
+ assembly_group_name = assembly
+ if assembly in self.oeditor.GetChildNames("Groups"):
+ assembly_group_name = generate_unique_name(assembly, n=2)
new_group = []
for el in nas_to_dict["Assemblies"][assembly]["Solids"].keys():
obj_names = [i for i in aedt_objs if i.startswith("Solid_{}".format(el))]
@@ -1477,16 +1107,16 @@ def preview_pyvista(dict_in):
]
if obj_names:
new_group.append(self.create_group(obj_names, group_name=str(el)))
- if assembly in self.oeditor.GetChildNames("Groups"):
+ if assembly_group_name in self.oeditor.GetChildNames("Groups"):
self.oeditor.MoveEntityToGroup(
[
"Groups:=",
new_group,
],
- ["ParentGroup:=", assembly],
+ ["ParentGroup:=", assembly_group_name],
)
else:
- new_name = self.create_group(new_group, group_name=assembly)
+ new_name = self.create_group(new_group, group_name=assembly_group_name)
self.oeditor.MoveEntityToGroup(
[
"Groups:=",
@@ -1495,33 +1125,44 @@ def preview_pyvista(dict_in):
["ParentGroup:=", new_name],
)
self.logger.info("Parts grouped")
+ self._app.save_project()
if import_lines:
+ if lines_thickness:
+ self._app["x_section_thickness"] = self._arg_with_dim(lines_thickness)
self.logger.info("Importing lines. This operation can take time....")
for assembly_name, assembly in nas_to_dict["Assemblies"].items():
if assembly["Lines"]:
for line_name, lines in assembly["Lines"].items():
- if lines_thickness:
- self._app["x_section_{}".format(line_name)] = lines_thickness
polys = []
id = 0
for line in lines:
try:
- points = [nas_to_dict["Points"][line[0]], nas_to_dict["Points"][line[1]]]
+ # points = [nas_to_dict["Points"][line[0]], nas_to_dict["Points"][line[1]]]
+ points = [nas_to_dict["Points"][i] for i in line]
except KeyError:
continue
- if lines_thickness:
- polys.append(
- self.create_polyline(
- points,
- name="Poly_{}_{}".format(line_name, id),
- xsection_type="Circle",
- xsection_width="x_section_{}".format(line_name),
- xsection_num_seg=6,
- )
- )
+ p_line = self.create_polyline(
+ points,
+ name="Poly_{}_{}".format(line_name, id),
+ xsection_type="Circle" if lines_thickness else None,
+ xsection_width="x_section_thickness" if lines_thickness else 1,
+ )
+
+ if p_line:
+ polys.append(p_line)
else:
- polys.append(self.create_polyline(points, name="Poly_{}_{}".format(line_name, id)))
+ self.logger.warning("Failed to create Polyline as a union of segments.")
+ self.logger.warning("Trying to create single segments.")
+ for i in range(len(points) - 1):
+ p_line = self.create_polyline(
+ points[i : i + 2],
+ name=generate_unique_name("Poly_{}_{}".format(line_name, id)),
+ xsection_type="Circle" if lines_thickness else None,
+ xsection_width="x_section_thickness" if lines_thickness else 1,
+ )
+ if p_line:
+ polys.append(p_line)
id += 1
if group_parts:
pids = [i.name for i in polys]
@@ -1542,11 +1183,6 @@ def preview_pyvista(dict_in):
],
["ParentGroup:=", group_name],
)
-
- if len(polys) > 1:
- out_poly = self.unite(polys, purge=not lines_thickness)
- if not lines_thickness and out_poly:
- self.generate_object_history(out_poly)
self.logger.info("Lines imported")
objs_after = [i for i in self.object_names]
diff --git a/pyaedt/modeler/modelerpcb.py b/pyaedt/modeler/modelerpcb.py
index 4e17524d6c6..aab82cc68a3 100644
--- a/pyaedt/modeler/modelerpcb.py
+++ b/pyaedt/modeler/modelerpcb.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import os
import re
from warnings import warn
@@ -402,7 +426,7 @@ def colinear_heal(self, assignment, tolerance=0.1):
Examples
--------
>>> from pyaedt import Hfss3dLayout
- >>> h3d=Hfss3dLayout(specified_version="2021.2")
+ >>> h3d=Hfss3dLayout(version="2021.2")
>>> h3d.modeler.layers.add_layer("TOP")
>>> l1=h3d.modeler.create_line("TOP",[[0,0],[100,0]],0.5)
>>> l2=h3d.modeler.create_line("TOP",[[100,0],[120,-35]],0.5)
@@ -457,7 +481,7 @@ def expand(self, assignment, size=1, expand_type="ROUND", replace_original=False
Examples
--------
>>> from pyaedt import Hfss3dLayout
- >>> h3d=Hfss3dLayout(specified_version="2021.2")
+ >>> h3d=Hfss3dLayout(version="2021.2")
>>> h3d.modeler.layers.add_layer("TOP")
>>> h3d.modeler.create_rectangle("TOP", [20,20],[50,50], name="rect_1")
>>> h3d.modeler.create_line("TOP",[[25,25],[40,40]])
diff --git a/pyaedt/modeler/pcb/Primitives3DLayout.py b/pyaedt/modeler/pcb/Primitives3DLayout.py
index a457a33684d..3833b9ab1ae 100644
--- a/pyaedt/modeler/pcb/Primitives3DLayout.py
+++ b/pyaedt/modeler/pcb/Primitives3DLayout.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import os
# import sys
@@ -57,7 +81,7 @@ def __getitem__(self, partname):
if partname in self.geometries:
return self.geometries[partname]
if partname in self.vias:
- return self.nets[partname]
+ return self.vias[partname]
if partname in self.nets:
return self.nets[partname]
if not isinstance(partname, (str, int, float, list, tuple)):
diff --git a/pyaedt/modeler/pcb/__init__.py b/pyaedt/modeler/pcb/__init__.py
index e69de29bb2d..9c4476773da 100644
--- a/pyaedt/modeler/pcb/__init__.py
+++ b/pyaedt/modeler/pcb/__init__.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
diff --git a/pyaedt/modeler/pcb/object3dlayout.py b/pyaedt/modeler/pcb/object3dlayout.py
index f6d238370b5..426a44dbc8a 100644
--- a/pyaedt/modeler/pcb/object3dlayout.py
+++ b/pyaedt/modeler/pcb/object3dlayout.py
@@ -1,4 +1,27 @@
# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
"""
This module provides methods and data structures for managing all properties of
objects (points, lines, sheeets, and solids) within the AEDT 3D Layout Modeler.
@@ -9,9 +32,9 @@
import math
import re
-from pyaedt import pyaedt_function_handler
from pyaedt.generic.constants import unit_converter
from pyaedt.generic.general_methods import _dim_arg
+from pyaedt.generic.general_methods import pyaedt_function_handler
from pyaedt.modeler.geometry_operators import GeometryOperators
@@ -95,7 +118,11 @@ def set_property_value(self, name, value):
>>> oEditor.ChangeProperty
"""
- vProp = ["NAME:" + name, "Value:=", value]
+ if "Pt" in name:
+ coordinates = value.split(",")
+ vProp = ["NAME:" + name, "X:=", coordinates[0], "Y:=", coordinates[1]]
+ else:
+ vProp = ["NAME:" + name, "Value:=", value]
return self.change_property(vProp)
@property
@@ -805,6 +832,18 @@ def components(self):
comps[c] = self._primitives.components[c]
return comps
+ @property
+ def geometry_names(self):
+ """List of geometry names.
+
+ Returns
+ -------
+ list
+ Geometries that belong to the selected net."""
+ comps = self._primitives._get_names(["component", "pin", "via"])
+ geo = [i for i in self._oeditor.FindObjects("Net", self.name) if i not in comps]
+ return geo
+
class Pins3DLayout(Object3DLayout, object):
"""Contains the pins in HFSS 3D Layout."""
diff --git a/pyaedt/modeler/schematic.py b/pyaedt/modeler/schematic.py
index c6be0544f93..cc9100ad4b8 100644
--- a/pyaedt/modeler/schematic.py
+++ b/pyaedt/modeler/schematic.py
@@ -1,15 +1,44 @@
# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import random
import re
+import sys
import time
+import warnings
-from pyaedt import settings
from pyaedt.generic.constants import AEDT_UNITS
from pyaedt.generic.general_methods import is_linux
from pyaedt.generic.general_methods import pyaedt_function_handler
+from pyaedt.generic.settings import settings
from pyaedt.modeler.cad.Modeler import Modeler
-from pyaedt.modeler.circuits.PrimitivesEmit import EmitComponent
-from pyaedt.modeler.circuits.PrimitivesEmit import EmitComponents
+
+if (3, 8) < sys.version_info < (3, 12):
+ from pyaedt.modeler.circuits.PrimitivesEmit import EmitComponent
+ from pyaedt.modeler.circuits.PrimitivesEmit import EmitComponents
+else: # pragma: no cover
+ warnings.warn("Emit API is only available for Python 3.8+,<3.12.")
from pyaedt.modeler.circuits.PrimitivesMaxwellCircuit import MaxwellCircuitComponents
from pyaedt.modeler.circuits.PrimitivesNexxim import NexximComponents
from pyaedt.modeler.circuits.PrimitivesTwinBuilder import TwinBuilderComponents
@@ -436,7 +465,7 @@ def _get_components_selections(self, selections, return_as_list=True):
for sel in selections:
if isinstance(sel, int):
sels.append(self.schematic.components[sel].composed_name)
- elif isinstance(sel, (CircuitComponent, EmitComponent)):
+ elif isinstance(sel, CircuitComponent):
sels.append(sel.composed_name)
else:
for el in list(self.schematic.components.values()):
@@ -716,6 +745,24 @@ def __init__(self, app):
self.components = EmitComponents(app, self)
self.logger.info("ModelerEmit class has been initialized!")
+ @pyaedt_function_handler()
+ def _get_components_selections(self, selections, return_as_list=True): # pragma: no cover
+ sels = []
+ if not isinstance(selections, list):
+ selections = [selections]
+ for sel in selections:
+ if isinstance(sel, int):
+ sels.append(self.schematic.components[sel].composed_name)
+ elif isinstance(sel, (CircuitComponent, EmitComponent)):
+ sels.append(sel.composed_name)
+ else:
+ for el in list(self.schematic.components.values()):
+ if sel in [el.InstanceName, el.composed_name, el.name]:
+ sels.append(el.composed_name)
+ if not return_as_list:
+ return ", ".join(sels)
+ return sels
+
class ModelerMaxwellCircuit(ModelerCircuit):
"""ModelerMaxwellCircuit class.
diff --git a/pyaedt/modules/AdvancedPostProcessing.py b/pyaedt/modules/AdvancedPostProcessing.py
index f8db6690e76..1eeee364356 100644
--- a/pyaedt/modules/AdvancedPostProcessing.py
+++ b/pyaedt/modules/AdvancedPostProcessing.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
"""
This module contains the `PostProcessor` class.
@@ -12,14 +36,15 @@
import warnings
from pyaedt import generate_unique_name
-from pyaedt import settings
from pyaedt.generic.general_methods import is_ironpython
from pyaedt.generic.general_methods import open_file
from pyaedt.generic.general_methods import pyaedt_function_handler
from pyaedt.generic.plot import ModelPlotter
+from pyaedt.generic.settings import settings
from pyaedt.modules.PostProcessor import FieldSummary
from pyaedt.modules.PostProcessor import PostProcessor as Post
from pyaedt.modules.PostProcessor import TOTAL_QUANTITIES
+from pyaedt.modules.fields_calculator import FieldsCalculator
if not is_ironpython:
try:
@@ -57,6 +82,7 @@ class PostProcessor(Post):
def __init__(self, app):
Post.__init__(self, app)
+ self.fields_calculator = FieldsCalculator(app)
@pyaedt_function_handler()
def nb_display(self, show_axis=True, show_grid=True, show_ruler=True):
@@ -814,6 +840,7 @@ def create_3d_plot(
primary_sweep="Theta",
secondary_sweep="Phi",
snapshot_path=None,
+ show=True,
):
"""Create a 3D plot using Matplotlib.
@@ -832,6 +859,8 @@ def create_3d_plot(
snapshot_path : str, optional
Full path to image file if a snapshot is needed.
The default is ``None``.
+ show : bool, optional
+ Whether if show the plot or not. Default is set to `True`.
Returns
-------
@@ -842,7 +871,9 @@ def create_3d_plot(
solution_data.intrinsics[nominal_sweep] = nominal_value
if nominal_value:
solution_data.primary_sweep = primary_sweep
- return solution_data.plot_3d(x_axis=primary_sweep, y_axis=secondary_sweep, snapshot_path=snapshot_path)
+ return solution_data.plot_3d(
+ x_axis=primary_sweep, y_axis=secondary_sweep, snapshot_path=snapshot_path, show=show
+ )
@pyaedt_function_handler(frames_list="frames", output_gif_path="gif_path")
def plot_scene(
diff --git a/pyaedt/modules/Boundary.py b/pyaedt/modules/Boundary.py
index deb84c681ce..b369ec5ceb4 100644
--- a/pyaedt/modules/Boundary.py
+++ b/pyaedt/modules/Boundary.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
"""
This module contains these classes: ``BoundaryCommon`` and ``BoundaryObject``.
"""
@@ -7,7 +31,6 @@
import copy
import re
-from pyaedt import Hfss3dLayout
from pyaedt.application.Variables import decompose_variable_value
from pyaedt.generic.DataHandlers import _dict2arg
from pyaedt.generic.DataHandlers import random_string
@@ -373,6 +396,11 @@ def __init__(self, app, component_type, component_name, props):
@pyaedt_function_handler()
def footprint_filter(self):
"""Minimum component footprint for filtering."""
+ if self.props["NativeComponentDefinitionProvider"]["PartsChoice"] != 1:
+ self._app.logger.error(
+ "Device Parts modeling is not active, hence no filtering or override option is available."
+ )
+ return None
if self._app.settings.aedt_version < "2024.2":
return None
return self.filters.get("FootPrint", {}).get("Value", None)
@@ -388,8 +416,13 @@ def footprint_filter(self, minimum_footprint):
minimum_footprint : str
Value with unit of the minimum component footprint for filtering.
"""
- if self._app.settings.aedt_version < "2024.2":
- return False
+ if self.props["NativeComponentDefinitionProvider"]["PartsChoice"] != 1:
+ self._app.logger.error(
+ "Device Parts modeling is not active, hence no filtering or override option is available."
+ )
+ return
+ if self._app.settings.aedt_version < "2024.2": # pragma : no cover
+ return
new_filters = self.props["NativeComponentDefinitionProvider"].get("Filters", [])
if "FootPrint" in new_filters:
new_filters.remove("FootPrint")
@@ -402,6 +435,11 @@ def footprint_filter(self, minimum_footprint):
@pyaedt_function_handler()
def power_filter(self):
"""Minimum component power for filtering."""
+ if self.props["NativeComponentDefinitionProvider"]["PartsChoice"] != 1:
+ self._app.logger.error(
+ "Device Parts modeling is not active, hence no filtering or override option is available."
+ )
+ return None
return self.filters.get("Power", {}).get("Value")
@power_filter.setter
@@ -415,6 +453,11 @@ def power_filter(self, minimum_power):
minimum_power : str
Value with unit of the minimum component power for filtering.
"""
+ if self.props["NativeComponentDefinitionProvider"]["PartsChoice"] != 1:
+ self._app.logger.error(
+ "Device Parts modeling is not active, hence no filtering or override option is available."
+ )
+ return
new_filters = self.props["NativeComponentDefinitionProvider"].get("Filters", [])
if "Power" in new_filters:
new_filters.remove("Power")
@@ -427,6 +470,11 @@ def power_filter(self, minimum_power):
@pyaedt_function_handler()
def type_filters(self):
"""Types of component that are filtered."""
+ if self.props["NativeComponentDefinitionProvider"]["PartsChoice"] != 1:
+ self._app.logger.error(
+ "Device Parts modeling is not active, hence no filtering or override option is available."
+ )
+ return None
return self.filters.get("Types")
@type_filters.setter
@@ -440,6 +488,11 @@ def type_filters(self, object_type):
object_type : str or list
Types of object to filter. Accepted types are ``"Capacitors"``, ``"Inductors"``, ``"Resistors"``.
"""
+ if self.props["NativeComponentDefinitionProvider"]["PartsChoice"] != 1:
+ self._app.logger.error(
+ "Device Parts modeling is not active, hence no filtering or override option is available."
+ )
+ return
if not isinstance(object_type, list):
object_type = [object_type]
if not all(o in self._filter_map2name.values() for o in object_type):
@@ -459,6 +512,11 @@ def type_filters(self, object_type):
@pyaedt_function_handler()
def height_filter(self):
"""Minimum component height for filtering."""
+ if self.props["NativeComponentDefinitionProvider"]["PartsChoice"] != 1:
+ self._app.logger.error(
+ "Device Parts modeling is not active, hence no filtering or override option is available."
+ )
+ return None
return self.filters.get("Height", {}).get("Value", None)
@height_filter.setter
@@ -472,6 +530,11 @@ def height_filter(self, minimum_height):
minimum_height : str
Value with unit of the minimum component power for filtering.
"""
+ if self.props["NativeComponentDefinitionProvider"]["PartsChoice"] != 1:
+ self._app.logger.error(
+ "Device Parts modeling is not active, hence no filtering or override option is available."
+ )
+ return
new_filters = self.props["NativeComponentDefinitionProvider"].get("Filters", [])
if "Height" in new_filters:
new_filters.remove("Height")
@@ -484,6 +547,11 @@ def height_filter(self, minimum_height):
@pyaedt_function_handler()
def objects_2d_filter(self):
"""Whether 2d objects are filtered."""
+ if self.props["NativeComponentDefinitionProvider"]["PartsChoice"] != 1:
+ self._app.logger.error(
+ "Device Parts modeling is not active, hence no filtering or override option is available."
+ )
+ return None
return self.filters.get("Exclude2DObjects", False)
@objects_2d_filter.setter
@@ -497,6 +565,11 @@ def objects_2d_filter(self, filter):
filter : bool
Whether 2d objects are filtered
"""
+ if self.props["NativeComponentDefinitionProvider"]["PartsChoice"] != 1:
+ self._app.logger.error(
+ "Device Parts modeling is not active, hence no filtering or override option is available."
+ )
+ return
new_filters = self.props["NativeComponentDefinitionProvider"].get("Filters", [])
if "HeightExclude2D" in new_filters:
new_filters.remove("HeightExclude2D")
@@ -508,6 +581,11 @@ def objects_2d_filter(self, filter):
@pyaedt_function_handler()
def filters(self):
"""All active filters."""
+ if self.props["NativeComponentDefinitionProvider"].get("PartsChoice", None) != 1:
+ self._app.logger.error(
+ "Device Parts modeling is not active, hence no filtering or override option is available."
+ )
+ return None
out_filters = {"Type": {"Capacitors": False, "Inductors": False, "Resistors": False}}
filters = self.props["NativeComponentDefinitionProvider"].get("Filters", [])
filter_map2type = {
@@ -565,6 +643,11 @@ def override_component(
bool
``True`` if successful. ``False`` otherwise.
"""
+ if self.props["NativeComponentDefinitionProvider"]["PartsChoice"] != 1:
+ self._app.logger.error(
+ "Device Parts modeling is not active, hence no filtering or override option is available."
+ )
+ return False
override_component = (
self.props["NativeComponentDefinitionProvider"].get("instanceOverridesMap", {}).get("oneOverrideBlk", [])
)
@@ -596,13 +679,24 @@ def override_component(
@pyaedt_function_handler()
@disable_auto_update
- def set_parts(self, parts_choice, simplify_parts=False, surface_material="Steel-oxidised-surface"):
- """Set how to include PCB parts.
+ def disable_device_parts(self):
+ """Disable PCB parts.
+
+ Returns
+ -------
+ bool
+ ``True`` if successful. ``False`` otherwise.
+ """
+ self.props["NativeComponentDefinitionProvider"]["PartsChoice"] = 0
+ return True
+
+ @pyaedt_function_handler()
+ @disable_auto_update
+ def set_device_parts(self, simplify_parts=False, surface_material="Steel-oxidised-surface"):
+ """Set how to include PCB device parts.
Parameters
----------
- parts_choice : str
- Parts to include: ``"None"``, ``"Device Parts"`` or ``"Package Parts"``.
simplify_parts : bool, optional
Whether to simplify parts as cuboid. Default is ``False``.
surface_material : str, optional
@@ -613,27 +707,88 @@ def set_parts(self, parts_choice, simplify_parts=False, surface_material="Steel-
bool
``True`` if successful. ``False`` otherwise.
"""
- allowed_inputs = ["None", "Device Parts", "Package Parts"]
- try:
- parts_choice = allowed_inputs.index(parts_choice)
- except ValueError:
+ self.props["NativeComponentDefinitionProvider"]["PartsChoice"] = 1
+ self.props["NativeComponentDefinitionProvider"]["ModelDeviceAsRect"] = simplify_parts
+ self.props["NativeComponentDefinitionProvider"]["DeviceSurfaceMaterial"] = surface_material
+ return True
+
+ @pyaedt_function_handler()
+ @disable_auto_update
+ def set_package_parts(
+ self,
+ solderballs=None,
+ connector=None,
+ solderbumps_modeling="Boxes",
+ bondwire_material="Au-Typical",
+ bondwire_diameter="0.05mm",
+ ):
+ """Set how to include PCB device parts.
+
+ Parameters
+ ----------
+ solderballs : str, optional
+ Specifies whether the solderballs located below the stackup are modeled,
+ and if so whether they are modeled as ``"Boxes"``, ``"Cylinders"`` or ``"Lumped"``.
+ connector : str, optional
+ Specifies whether the connectors located above the stackup are modeled,
+ and if so whether they are modeled as ``"Solderbump"`` or ``"Bondwire"``.
+ Default is ``None`` in which case they are not modeled.
+ solderbumps_modeling : str, optional
+ Specifies how to model solderbumps if ``connector`` is set to ``"Solderbump"``.
+ Accepted options are: ``"Boxes"``, ``"Cylinders"`` and ``"Lumped"``.
+ Default is ``"Boxes"``.
+ bondwire_material : str, optional
+ Specifies bondwires material if ``connector`` is set to ``"Bondwire"``.
+ Default is ``"Au-Typical"``.
+
+ Returns
+ -------
+ bool
+ ``True`` if successful. ``False`` otherwise.
+ """
+ # sanity check
+ valid_connectors = ["Solderbump", "Bondwire"]
+ if connector is not None and connector not in valid_connectors:
self._app.logger.error(
- "{} is not a valid argument, only allowed input are {}.".format(parts_choice, ", ".join(allowed_inputs))
+ "{} option is not supported. Use one of the following: {}".format(
+ connector, ", ".join(valid_connectors)
+ )
)
return False
- self.props["NativeComponentDefinitionProvider"]["PartsChoice"] = parts_choice
- self.props["NativeComponentDefinitionProvider"]["ModelDeviceAsRect"] = simplify_parts
- self.props["NativeComponentDefinitionProvider"]["DeviceSurfaceMaterial"] = surface_material
+ solderbumps_map = {"Lumped": "SbLumped", "Cylinders": "SbCylinder", "Boxes": "SbBlock"}
+ for arg in [solderbumps_modeling, solderballs]:
+ if arg is not None and arg not in solderbumps_map:
+ self._app.logger.error(
+ "{} option is not supported. Use one of the following: "
+ "{}".format(arg, ", ".join(list(solderbumps_map.keys())))
+ )
+ return False
+ if bondwire_material not in self._app.materials.mat_names_aedt:
+ self._app.logger.error("{} material is not present in the library.".format(bondwire_material))
+ return False
+
+ update_properties = {
+ "PartsChoice": 2,
+ "CreateTopSolderballs": connector is not None,
+ "TopConnectorType": connector,
+ "TopSolderballsModelType": solderbumps_map[solderbumps_modeling],
+ "BondwireMaterial": bondwire_material,
+ "BondwireDiameter": bondwire_diameter,
+ "CreateBottomSolderballs": solderballs is not None,
+ "BottomSolderballsModelType": solderbumps_map[solderballs],
+ }
+
+ self.props["NativeComponentDefinitionProvider"].update(update_properties)
return True
@pyaedt_function_handler()
def identify_extent_poly(self):
+ from pyaedt import Hfss3dLayout
+
prj = self.props["NativeComponentDefinitionProvider"]["DefnLink"]["Project"]
if prj == "This Project*":
prj = self._app.project_name
- layout = Hfss3dLayout(
- projectname=prj, designname=self.props["NativeComponentDefinitionProvider"]["DefnLink"]["Design"]
- )
+ layout = Hfss3dLayout(project=prj, design=self.props["NativeComponentDefinitionProvider"]["DefnLink"]["Design"])
layer = [o for o in layout.modeler.stackup.drawing_layers if o.type == "outline"][0]
outlines = [p for p in layout.modeler.polygons.values() if p.placement_layer == layer.name]
if len(outlines) > 1:
@@ -4350,7 +4505,7 @@ def add_boundary_node(self, name, assignment_type, value):
>>> app = pyaedt.Icepak()
>>> network = pyaedt.modules.Boundary.Network(app)
>>> network.add_boundary_node("TestNode", "Temperature", 2)
- >>> ds = app.create_dataset1d_design("Test_DataSet", [1, 2, 3], [3, 4, 5])
+ >>> ds = app.create_dataset1d_design("Test_DataSet",[1, 2, 3],[3, 4, 5])
>>> network.add_boundary_node("TestNode", "Power", {"Type": "Temp Dep",
>>> "Function": "Piecewise Linear",
>>> "Values": "Test_DataSet"})
diff --git a/pyaedt/modules/CableModeling.py b/pyaedt/modules/CableModeling.py
index ed7fe2a10fd..59e1a0f1664 100644
--- a/pyaedt/modules/CableModeling.py
+++ b/pyaedt/modules/CableModeling.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import itertools
import json
import os
diff --git a/pyaedt/modules/CircuitTemplates.py b/pyaedt/modules/CircuitTemplates.py
index 57859343f3b..7560bd30952 100644
--- a/pyaedt/modules/CircuitTemplates.py
+++ b/pyaedt/modules/CircuitTemplates.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
# Power Sinusoidal
PowerSinusoidal = [
"NAME:Name",
diff --git a/pyaedt/modules/DesignXPloration.py b/pyaedt/modules/DesignXPloration.py
index 5472a4fd424..ad144d1fb6b 100644
--- a/pyaedt/modules/DesignXPloration.py
+++ b/pyaedt/modules/DesignXPloration.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
from collections import OrderedDict
import copy
import csv
diff --git a/pyaedt/modules/LayerStackup.py b/pyaedt/modules/LayerStackup.py
index 244caa484d4..646ef9c3b84 100644
--- a/pyaedt/modules/LayerStackup.py
+++ b/pyaedt/modules/LayerStackup.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
"""
This module contains these classes: `Layer` and `Layers`.
diff --git a/pyaedt/modules/Material.py b/pyaedt/modules/Material.py
index ccbc1d25bd5..7214ce71392 100644
--- a/pyaedt/modules/Material.py
+++ b/pyaedt/modules/Material.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
"""
This module contains these data classes for creating a material library:
@@ -603,7 +627,7 @@ def add_thermal_modifier_free_form(self, formula, index=0):
--------
>>> from pyaedt import Hfss
- >>> hfss = Hfss(specified_version="2021.2")
+ >>> hfss = Hfss(version="2021.2")
>>> mat1 = hfss.materials.add_material("new_copper2")
>>> mat1.add_thermal_modifier_free_form("if(Temp > 1000cel, 1, if(Temp < -273.15cel, 1, 1))")
"""
@@ -636,7 +660,7 @@ def add_thermal_modifier_dataset(self, dataset, index=0):
--------
>>> from pyaedt import Hfss
- >>> hfss = Hfss(specified_version="2021.2")
+ >>> hfss = Hfss(version="2021.2")
>>> mat1 = hfss.materials.add_material("new_copper2")
>>> mat1.add_thermal_modifier_dataset("$ds1")
"""
@@ -693,7 +717,7 @@ def add_thermal_modifier_closed_form(
--------
>>> from pyaedt import Hfss
- >>> hfss = Hfss(specified_version="2021.2")
+ >>> hfss = Hfss(version="2021.2")
>>> mat1 = hfss.materials.add_material("new_copper2")
>>> mat1.permittivity.add_thermal_modifier_closed_form(c1 = 1e-3)
"""
@@ -852,7 +876,7 @@ def _set_non_linear(self, x_unit=None, y_unit=None):
Examples
--------
>>> from pyaedt import Hfss
- >>> hfss = Hfss(specified_version="2023.2")
+ >>> hfss = Hfss(version="2023.2")
>>> B_value = [0.0, 0.1, 0.3, 0.4, 0.48, 0.55, 0.6, 0.61, 0.65]
>>> H_value = [0.0, 500.0, 1000.0, 1500.0, 2000.0, 2500.0, 3500.0, 5000.0, 10000.0]
>>> mat = hfss.materials.add_material("newMat")
@@ -1050,7 +1074,7 @@ def add_spatial_modifier_free_form(self, formula, index=0):
--------
>>> from pyaedt import Hfss
- >>> hfss = Hfss(specified_version="2021.2")
+ >>> hfss = Hfss(version="2021.2")
>>> mat1 = hfss.materials.add_material("new_copper2")
>>> mat1.add_spatial_modifier_free_form("if(X > 1mm, 1, if(X < 1mm, 2, 1))")
"""
@@ -1083,7 +1107,7 @@ def add_spatial_modifier_dataset(self, dataset, index=0):
--------
>>> from pyaedt import Hfss
- >>> hfss = Hfss(specified_version="2021.2")
+ >>> hfss = Hfss(version="2021.2")
>>> mat1 = hfss.materials.add_material("new_copper2")
>>> mat1.add_spatial_modifier_dataset("$ds1")
"""
@@ -1384,7 +1408,7 @@ def material_appearance(self):
Create a material with color ``[0, 153, 153]`` (darker cyan) and transparency ``0.5``.
>>> from pyaedt import Hfss
- >>> hfss = Hfss(specified_version="2021.2")
+ >>> hfss = Hfss(version="2021.2")
>>> mat1 = hfss.materials.add_material("new_material")
>>> appearance_props = mat1.material_appearance
>>> mat1.material_appearance = [0, 153, 153, 0.5]
diff --git a/pyaedt/modules/MaterialLib.py b/pyaedt/modules/MaterialLib.py
index 58438bb8b2d..8b17ba6140f 100644
--- a/pyaedt/modules/MaterialLib.py
+++ b/pyaedt/modules/MaterialLib.py
@@ -1,4 +1,27 @@
# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
"""
This module contains the `Materials` class.
"""
@@ -12,10 +35,10 @@
import sys
import warnings
-from pyaedt import is_ironpython
from pyaedt.generic.DataHandlers import _arg2dict
from pyaedt.generic.LoadAEDTFile import load_entire_aedt_file
from pyaedt.generic.general_methods import generate_unique_name
+from pyaedt.generic.general_methods import is_ironpython
from pyaedt.generic.general_methods import open_file
from pyaedt.generic.general_methods import pyaedt_function_handler
from pyaedt.generic.general_methods import read_json
@@ -829,9 +852,7 @@ def import_materials_from_file(self, input_file=None, **kwargs):
if numcol > 2:
zunit = val["Coordinates"]["DimUnits"][2]
zval = [sublist[2] for sublist in new_list]
- self._app.create_dataset(
- el[1:], xunit=xunit, yunit=yunit, zunit=zunit, xlist=xval, ylist=yval, zlist=zval
- )
+ self._app.create_dataset(el[1:], x=xval, y=yval, z=zval, x_unit=xunit, y_unit=yunit)
if json_flag:
for el, val in data["materials"].items():
if el.lower() in list(self.material_keys.keys()):
diff --git a/pyaedt/modules/Mesh.py b/pyaedt/modules/Mesh.py
index 588f7c015a2..006ca95d078 100644
--- a/pyaedt/modules/Mesh.py
+++ b/pyaedt/modules/Mesh.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
"""
This module contains the `Mesh` class.
"""
diff --git a/pyaedt/modules/Mesh3DLayout.py b/pyaedt/modules/Mesh3DLayout.py
index 67b845d223d..f006a3f1c07 100644
--- a/pyaedt/modules/Mesh3DLayout.py
+++ b/pyaedt/modules/Mesh3DLayout.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
"""
This module contains these classes: `Mesh` and `Mesh3DOperation`.
diff --git a/pyaedt/modules/MeshIcepak.py b/pyaedt/modules/MeshIcepak.py
index 6eab77ed091..db76e18a2b6 100644
--- a/pyaedt/modules/MeshIcepak.py
+++ b/pyaedt/modules/MeshIcepak.py
@@ -1,5 +1,29 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
from abc import abstractmethod
from collections import OrderedDict
+import os.path
import warnings
from pyaedt.generic.DataHandlers import _dict2arg
@@ -258,7 +282,7 @@ def object(self):
return {
"CreateRegion": oo
for o, oo in self._app.modeler.objects_by_name.items()
- if oo.history().command == "CreateRegion"
+ if oo.history() and oo.history().command == "CreateRegion"
}.get("CreateRegion", None)
else:
return self._app.modeler.objects_by_name.get(self._name, None)
@@ -633,10 +657,21 @@ def __getattr__(self, name):
return self.__dict__[name]
def __setattr__(self, name, value):
- if "settings" in self.__dict__ and name in self.settings:
+ if ("settings" in self.__dict__) and (name in self.settings):
self.settings[name] = value
elif name == "UserSpecifiedSettings":
self.__dict__["manual_settings"] = value
+ elif (
+ ("settings" in self.__dict__)
+ and not (name in self.settings)
+ and name
+ not in ["manual_settings", "settings", "_name", "_model_units", "_app", "_assignment", "enable", "name"]
+ ):
+ self._app.logger.error(
+ "Setting name {} is not available. Available parameters are: {}.".format(
+ name, ", ".join(self.settings.keys())
+ )
+ )
else:
super(MeshRegionCommon, self).__setattr__(name, value)
@@ -674,6 +709,8 @@ def update(self):
args = ["NAME:Settings"]
args += self.settings.parse_settings_as_args()
args += ["UserSpecifiedSettings:=", self.manual_settings]
+ if self.global_region.object:
+ args += ["Objects({})".format(str(self.global_region.object.id))]
try:
self._app.omeshmodule.EditGlobalMeshRegion(args)
return True
@@ -712,6 +749,7 @@ def __init__(self, app, objects=None, name=None, **kwargs):
app,
name,
)
+ self._assignment = None
self.enable = True
if settings.aedt_version > "2023.2" and objects is not None:
if not isinstance(objects, list):
@@ -1600,6 +1638,7 @@ def assign_mesh_level_to_group(
for el in self.meshoperations:
if el.name == name:
name = generate_unique_name(name)
+ break
else:
name = generate_unique_name("MeshLevel")
props = OrderedDict(
@@ -1615,3 +1654,45 @@ def assign_mesh_level_to_group(
mop.create()
self.meshoperations.append(mop)
return mop
+
+ def assign_mesh_reuse(self, assignment, mesh_file, name=None):
+ """Assign a mesh file to objects.
+
+ Parameters
+ ----------
+ assignment : str or list
+ Names of objects to which the mesh file is assignment.
+ mesh_file : str
+ Path to the mesh file.
+ name : str, optional
+ Name of the mesh operation. The default is ``None``, in which case it will be
+ generated automatically.
+
+ Returns
+ -------
+ :class:`pyaedt.modules.Mesh.MeshOperation`
+
+ References
+ ----------
+
+ >>> oModule.AssignMeshOperation
+ """
+ if not os.path.exists(mesh_file):
+ self._app.logger.error("Mesh file does not exist.")
+ return False
+ if name:
+ for el in self.meshoperations:
+ if el.name == name:
+ name = generate_unique_name(name)
+ break
+ else:
+ name = generate_unique_name("MeshReuse")
+ if not isinstance(assignment, list):
+ assignment = [assignment]
+ props = OrderedDict(
+ {"Enable": True, "Mesh Reuse Enabled": True, "Mesh Reuse File": mesh_file, "Objects": assignment}
+ )
+ mop = MeshOperation(self, name, props, "Icepak")
+ mop.create()
+ self.meshoperations.append(mop)
+ return mop
diff --git a/pyaedt/modules/OptimetricsTemplates.py b/pyaedt/modules/OptimetricsTemplates.py
index c9b976a16dc..efa3dc5d1a1 100644
--- a/pyaedt/modules/OptimetricsTemplates.py
+++ b/pyaedt/modules/OptimetricsTemplates.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
from collections import OrderedDict
defaultparametricSetup = OrderedDict(
diff --git a/pyaedt/modules/PostProcessor.py b/pyaedt/modules/PostProcessor.py
index 2f30d5cf8a2..3d9488924dd 100644
--- a/pyaedt/modules/PostProcessor.py
+++ b/pyaedt/modules/PostProcessor.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
"""
This module contains these classes: `FieldPlot`, `PostProcessor`, and `SolutionData`.
@@ -17,12 +41,12 @@
import string
import tempfile
-from pyaedt import is_ironpython
from pyaedt.application.Variables import decompose_variable_value
from pyaedt.generic.DataHandlers import _dict_items_to_list_items
from pyaedt.generic.constants import unit_converter
from pyaedt.generic.general_methods import check_and_download_file
from pyaedt.generic.general_methods import generate_unique_name
+from pyaedt.generic.general_methods import is_ironpython
from pyaedt.generic.general_methods import open_file
from pyaedt.generic.general_methods import pyaedt_function_handler
from pyaedt.generic.general_methods import read_configuration_file
@@ -921,23 +945,27 @@ def available_display_types(self, report_category=None):
@pyaedt_function_handler()
def available_quantities_categories(
- self, report_category=None, display_type=None, solution=None, context="", is_siwave_dc=False
+ self, report_category=None, display_type=None, solution=None, context=None, is_siwave_dc=False
):
"""Compute the list of all available report categories.
Parameters
----------
report_category : str, optional
- Report Category. Default is `None` which will take first default category.
+ Report category. The default is ``None``, in which case the first default category is used.
display_type : str, optional
- Report Display Type.
- Default is `None` which will take first default type which is in most of the case "Rectangular Plot".
+ Report display type. The default is ``None``, in which case the first default type
+ is used. In most cases, this default type is ``"Rectangular Plot"``.
solution : str, optional
- Report Setup. Default is `None` which will take first nominal_adaptive solution.
- context : str, optional
- Report Category. Default is `""` which will take first default context.
+ Report setup. The default is ``None``, in which case the first
+ nominal adaptive solution is used.
+ context : str, dict, optional
+ Report category. The default is ``None``, in which case the first default context
+ is used. For Maxwell 2D/3D eddy current solution types, the report category
+ can be provided as a dictionary, where the key is the matrix name and the value
+ the reduced matrix.
is_siwave_dc : bool, optional
- Whether if the setup is Siwave DCIR or not. Default is ``False``.
+ Whether the setup is Siwave DCIR. The default is ``False``.
Returns
-------
@@ -970,7 +998,14 @@ def available_quantities_categories(
"SimValueContext:=",
[37010, 0, 2, 0, False, False, -1, 1, 0, 1, 1, "", 0, 0, "DCIRID", False, id_, "IDIID", False, "1"],
]
-
+ elif self._app.design_type in ["Maxwell 2D", "Maxwell 3D"] and self._app.solution_type == "EddyCurrent":
+ if isinstance(context, dict):
+ for k, v in context.items():
+ context = ["Context:=", k, "Matrix:=", v]
+ elif context and isinstance(context, str):
+ context = ["Context:=", context]
+ elif not context:
+ context = ""
elif not context: # pragma: no cover
context = ""
@@ -985,7 +1020,7 @@ def available_report_quantities(
display_type=None,
solution=None,
quantities_category=None,
- context="",
+ context=None,
is_siwave_dc=False,
):
"""Compute the list of all available report quantities of a given report quantity category.
@@ -993,17 +1028,23 @@ def available_report_quantities(
Parameters
----------
report_category : str, optional
- Report Category. Default is ``None`` which will take first default category.
+ Report Category. The default is ``None``, in which case the default category is used.
display_type : str, optional
Report Display Type.
- Default is ``None`` which will take first default type which is in most of the case "Rectangular Plot".
+ The default is ``None``, in which case the default type is used.
+ In most of the cases the default type is "Rectangular Plot".
solution : str, optional
- Report Setup. Default is `None` which will take first nominal_adaptive solution.
+ Report Setup.
+ The default is ``None``, in which case the first nominal adaptive solution is used.
quantities_category : str, optional
- The category to which quantities belong. It has to be one of ``available_quantities_categories`` method.
- Default is ``None`` which will take first default quantity.".
- context : str, optional
- Report Context. Default is ``""`` which will take first default context.
+ The category that the quantities belong to.
+ It must be one of the ``available_quantities_categories`` method.
+ The default is ``None``, in which case the first default quantity is used.
+ context : str, dict, optional
+ Report Context.
+ The default is ``None``, in which case the default context is used.
+ For Maxwell 2D/3D Eddy Current solution types this can be provided as a dictionary
+ where the key is the matrix name and value the reduced matrix.
is_siwave_dc : bool, optional
Whether if the setup is Siwave DCIR or not. Default is ``False``.
@@ -1014,6 +1055,26 @@ def available_report_quantities(
References
----------
>>> oModule.GetAllQuantities
+
+ Examples
+ --------
+ The example shows how to get report expressions for a Maxwell design with Eddy current solution.
+ The context has to be provided as a dictionary where the key is the name of the original matrix
+ and the value is the name of the reduced matrix.
+ >>> from pyaedt import Maxwell3d
+ >>> m3d = Maxwell3d(solution_type="EddyCurrent")
+ >>> rectangle1 = m3d.modeler.create_rectangle(0, [0.5, 1.5, 0], [2.5, 5], name="Sheet1")
+ >>> rectangle2 = m3d.modeler.create_rectangle(0, [9, 1.5, 0], [2.5, 5], name="Sheet2")
+ >>> rectangle3 = m3d.modeler.create_rectangle(0, [16.5, 1.5, 0], [2.5, 5], name="Sheet3")
+ >>> m3d.assign_current(rectangle1.faces[0], amplitude=1, name="Cur1")
+ >>> m3d.assign_current(rectangle2.faces[0], amplitude=1, name="Cur2")
+ >>> m3d.assign_current(rectangle3.faces[0], amplitude=1, name="Cur3")
+ >>> L = m3d.assign_matrix(assignment=["Cur1", "Cur2", "Cur3"], matrix_name="Matrix1")
+ >>> out = L.join_series(sources=["Cur1", "Cur2"], matrix_name="ReducedMatrix1")
+ >>> expressions = m3d.post.available_report_quantities(report_category="EddyCurrent",
+ ... display_type="Data Table",
+ ... context={"Matrix1": "ReducedMatrix1"})
+ >>> m3d.release_desktop(False, False)
"""
if not report_category:
report_category = self.available_report_types[0]
@@ -1038,7 +1099,14 @@ def available_report_quantities(
"SimValueContext:=",
[37010, 0, 2, 0, False, False, -1, 1, 0, 1, 1, "", 0, 0, "DCIRID", False, id, "IDIID", False, "1"],
]
-
+ elif self._app.design_type in ["Maxwell 2D", "Maxwell 3D"] and self._app.solution_type == "EddyCurrent":
+ if isinstance(context, dict):
+ for k, v in context.items():
+ context = ["Context:=", k, "Matrix:=", v]
+ elif context and isinstance(context, str):
+ context = ["Context:=", context]
+ elif not context:
+ context = ""
elif not context:
context = ""
if not quantities_category:
@@ -1063,7 +1131,7 @@ def available_report_solutions(self, report_category=None):
Parameters
----------
report_category : str, optional
- Report Category. Default is ``None`` which will take first default category.
+ Report Category. Default is ``None`` which takes default category.
Returns
-------
@@ -1195,7 +1263,7 @@ def delete_report(self, plot_name=None):
Parameters
----------
plot_name : str, optional
- Name of the plot to delete. The default value is ``None`` and in this case, all reports will be deleted.
+ Name of the plot to delete. The default value is ``None`` and in this case, all reports are deleted.
Returns
-------
@@ -1434,7 +1502,7 @@ def export_report_to_csv(
Parameters
----------
project_dir : str
- Path to the project directory. The csv file will be plot_name.csv.
+ Path to the project directory. The CSV file is plot_name.csv.
plot_name : str
Name of the plot to export.
uniform : bool, optional
@@ -1703,20 +1771,22 @@ def create_report(
secondary_sweep_variable : str, optional
Name of the secondary sweep variable in 3D Plots.
report_category : str, optional
- Category of the Report to be created. If `None` default data Report will be used.
+ Category of the Report to be created. If `None` default data Report is used.
The Report Category can be one of the types available for creating a report depend on the simulation setup.
For example for a Far Field Plot in HFSS the UI shows the report category as "Create Far Fields Report".
- The report category will be in this case "Far Fields".
+ The report category is "Far Fields" in this case.
Depending on the setup different categories are available.
- If `None` default category will be used (the first item in the Results drop down menu in AEDT).
+ If ``None`` default category is used (the first item in the Results drop down menu in AEDT).
plot_type : str, optional
The format of Data Visualization. Default is ``Rectangular Plot``.
- context : str, optional
+ context : str, dict, optional
The default is ``None``.
- For HFSS 3D Layout, options are ``"Bondwires"``, ``"Differential Pairs"``,
``None``, ``"Probes"``, ``"RL"``, ``"Sources"``, and ``"Vias"``.
- For Q2D or Q3D, specify the name of a reduced matrix.
- For a far fields plot, specify the name of an infinite sphere.
+ - For Maxwell 2D/3D Eddy Current solution types this can be provided as a dictionary
+ where the key is the matrix name and value the reduced matrix.
plot_name : str, optional
Name of the plot. The default is ``None``.
polyline_points : int, optional,
@@ -1724,7 +1794,6 @@ def create_report(
subdesign_id : int, optional
Specify a subdesign ID to export a Touchstone file of this subdesign. Valid for Circuit Only.
The default value is ``None``.
- context : str, optional
Returns
-------
@@ -1754,8 +1823,8 @@ def create_report(
... report_category="Far Fields",
... plot_type="3D Polar Plot",
... context="3D")
-
>>> hfss.post.create_report("S(1,1)",hfss.nominal_sweep,variations=variations,plot_type="Smith Chart")
+ >>> hfss.release_desktop(False, False)
>>> from pyaedt import Maxwell2d
>>> m2d = Maxwell2d()
@@ -1763,6 +1832,27 @@ def create_report(
... domain="Time",
... primary_sweep_variable="Time",
... plot_name="Winding Plot 1")
+ >>> m2d.release_desktop(False, False)
+
+ >>> from pyaedt import Maxwell3d
+ >>> m3d = Maxwell3d(solution_type="EddyCurrent")
+ >>> rectangle1 = m3d.modeler.create_rectangle(0, [0.5, 1.5, 0], [2.5, 5], name="Sheet1")
+ >>> rectangle2 = m3d.modeler.create_rectangle(0, [9, 1.5, 0], [2.5, 5], name="Sheet2")
+ >>> rectangle3 = m3d.modeler.create_rectangle(0, [16.5, 1.5, 0], [2.5, 5], name="Sheet3")
+ >>> m3d.assign_current(rectangle1.faces[0], amplitude=1, name="Cur1")
+ >>> m3d.assign_current(rectangle2.faces[0], amplitude=1, name="Cur2")
+ >>> m3d.assign_current(rectangle3.faces[0], amplitude=1, name="Cur3")
+ >>> L = m3d.assign_matrix(assignment=["Cur1", "Cur2", "Cur3"], matrix_name="Matrix1")
+ >>> out = L.join_series(sources=["Cur1", "Cur2"], matrix_name="ReducedMatrix1")
+ >>> expressions = m3d.post.available_report_quantities(report_category="EddyCurrent",
+ ... display_type="Data Table",
+ ... context={"Matrix1": "ReducedMatrix1"})
+ >>> report = m3d.post.create_report(
+ ... expressions=expressions,
+ ... context={"Matrix1": "ReducedMatrix1"},
+ ... plot_type="Data Table",
+ ... plot_name="reduced_matrix")
+ >>> m3d.release_desktop(False, False)
"""
if not setup_sweep_name:
setup_sweep_name = self._app.nominal_sweep
@@ -1836,6 +1926,19 @@ def create_report(
].index(context)
elif self._app.design_type in ["Q3D Extractor", "2D Extractor"] and context:
report.matrix = context
+ elif (
+ self._app.design_type in ["Maxwell 2D", "Maxwell 3D"]
+ and self._app.solution_type == "EddyCurrent"
+ and context
+ ):
+ if isinstance(context, dict):
+ for k, v in context.items():
+ report.matrix = k
+ report.reduced_matrix = v
+ elif context in self.modeler.line_names or context in self.modeler.point_names:
+ report.polyline = context
+ else:
+ report.matrix = context
elif report_category == "Far Fields":
if not context and self._app._field_setups:
report.far_field_sphere = self._app.field_setups[0].name
@@ -1883,7 +1986,7 @@ def get_solution_data(
----------
expressions : str or list, optional
One or more formulas to add to the report. Example is value ``"dB(S(1,1))"`` or a list of values.
- Default is `None` which will return all traces.
+ Default is ``None`` which returns all traces.
setup_sweep_name : str, optional
Name of the setup. The default is ``None``, in which case the ``nominal_adaptive``
setup is used. Be sure to build a setup string in the form of
@@ -1893,21 +1996,21 @@ def get_solution_data(
Plot Domain. Options are "Sweep" for frequency domain related results and "Time" for transient related data.
variations : dict, optional
Dictionary of all families including the primary sweep.
- The default is ``None`` which will use the nominal variations of the setup.
+ The default is ``None`` which uses the nominal variations of the setup.
primary_sweep_variable : str, optional
Name of the primary sweep. The default is ``"None"`` which, depending on the context,
- will internally assign the primary sweep to:
+ internally assigns the primary sweep to:
1. ``Freq`` for frequency domain results,
2. ``Time`` for transient results,
3. ``Theta`` for radiation patterns,
4. ``distance`` for field plot over a polyline.
report_category : str, optional
- Category of the Report to be created. If `None` default data Report will be used.
+ Category of the Report to be created. If ``None`` default data Report is used.
The Report Category can be one of the types available for creating a report depend on the simulation setup.
For example for a Far Field Plot in HFSS the UI shows the report category as "Create Far Fields Report".
- The report category will be in this case "Far Fields".
+ The report category is "Far Fields" in this case.
Depending on the setup different categories are available.
- If `None` default category will be used (the first item in the Results drop down menu in AEDT).
+ If ``None`` default category is used (the first item in the Results drop down menu in AEDT).
To get the list of available categories user can use method ``available_report_types``.
context : str, dict, optional
This is the context of the report.
@@ -1917,6 +2020,8 @@ def get_solution_data(
3. Reduce Matrix Name for Q2d/Q3d solution
4. Infinite Sphere name for Far Fields Plot.
5. Dictionary. If dictionary is passed, key is the report property name and value is property value.
+ 6. For Maxwell 2D/3D eddy current solution types, this can be provided as a dictionary,
+ where the key is the matrix name and value the reduced matrix.
subdesign_id : int, optional
Subdesign ID for exporting a Touchstone file of this subdesign.
This parameter is valid for ``Circuit`` only.
@@ -1963,6 +2068,7 @@ def get_solution_data(
... variations=variations,
...)
>>> data2.plot()
+ >>> hfss.release_desktop(False, False)
>>> from pyaedt import Maxwell2d
>>> m2d = Maxwell2d()
@@ -1970,12 +2076,30 @@ def get_solution_data(
... "InputCurrent(PHA)", domain="Time", primary_sweep_variable="Time",
... )
>>> data3.plot("InputCurrent(PHA)")
+ >>> m2d.release_desktop(False, False)
>>> from pyaedt import Circuit
>>> circuit = Circuit()
>>> context = {"algorithm": "FFT", "max_frequency": "100MHz", "time_stop": "2.5us", "time_start": "0ps"}
>>> spectralPlotData = circuit.post.get_solution_data(expressions="V(Vprobe1)", domain="Spectral",
... primary_sweep_variable="Spectrum", context=context)
+ >>> circuit.release_desktop(False, False)
+
+ >>> from pyaedt import Maxwell3d
+ >>> m3d = Maxwell3d(solution_type="EddyCurrent")
+ >>> rectangle1 = m3d.modeler.create_rectangle(0, [0.5, 1.5, 0], [2.5, 5], name="Sheet1")
+ >>> rectangle2 = m3d.modeler.create_rectangle(0, [9, 1.5, 0], [2.5, 5], name="Sheet2")
+ >>> rectangle3 = m3d.modeler.create_rectangle(0, [16.5, 1.5, 0], [2.5, 5], name="Sheet3")
+ >>> m3d.assign_current(rectangle1.faces[0], amplitude=1, name="Cur1")
+ >>> m3d.assign_current(rectangle2.faces[0], amplitude=1, name="Cur2")
+ >>> m3d.assign_current(rectangle3.faces[0], amplitude=1, name="Cur3")
+ >>> L = m3d.assign_matrix(assignment=["Cur1", "Cur2", "Cur3"], matrix_name="Matrix1")
+ >>> out = L.join_series(sources=["Cur1", "Cur2"], matrix_name="ReducedMatrix1")
+ >>> expressions = m3d.post.available_report_quantities(report_category="EddyCurrent",
+ ... display_type="Data Table",
+ ... context={"Matrix1": "ReducedMatrix1"})
+ >>> data = m2d.post.get_solution_data(expressions=expressions, context={"Matrix1": "ReducedMatrix1"})
+ >>> m3d.release_desktop(False, False)
"""
expressions = [expressions] if isinstance(expressions, str) else expressions
if not setup_sweep_name:
@@ -2027,6 +2151,23 @@ def get_solution_data(
report.differential_pairs = True
elif self._app.design_type in ["Q3D Extractor", "2D Extractor"] and context:
report.matrix = context
+ elif (
+ self._app.design_type in ["Maxwell 2D", "Maxwell 3D"]
+ and self._app.solution_type == "EddyCurrent"
+ and context
+ ):
+ if isinstance(context, dict):
+ for k, v in context.items():
+ report.matrix = k
+ report.reduced_matrix = v
+ elif (
+ hasattr(self.modeler, "line_names")
+ and hasattr(self.modeler, "point_names")
+ and context in self.modeler.point_names + self.modeler.line_names
+ ):
+ report.polyline = context
+ else:
+ report.matrix = context
elif report_category == "Far Fields":
if not context and self._app.field_setups:
report.far_field_sphere = self._app.field_setups[0].name
@@ -3354,7 +3495,7 @@ def create_fieldplot_layers(
# type: (list, str, str, list, bool, dict, str) -> FieldPlot
"""Create a field plot of stacked layer plot.
This plot is valid from AEDT 2023 R2 and later in HFSS 3D Layout.
- It will also work when a layout components in 3d modeler is used.
+ It works when a layout components in 3d modeler is used.
In order to plot on signal layers use the method ``create_fieldplot_layers_nets``.
Parameters
@@ -3362,7 +3503,7 @@ def create_fieldplot_layers(
layers : list
List of layers to plot. For example:
``["Layer1","Layer2"]``. If empty list is provided
- all layers will be considered.
+ all layers are considered.
quantity : str
Name of the quantity to plot.
setup : str, optional
@@ -3449,8 +3590,8 @@ def create_fieldplot_layers_nets(
layers_nets : list
List of layers and nets to plot. For example:
``[["Layer1", "GND", "PWR"], ["Layer2", "VCC"], ...]``. If ``"no-layer"`` is provided as first argument,
- all layers will be considered. If ``"no-net"`` is provided or the list contains only layer name, all the
- nets will be automatically considered.
+ all layers are considered. If ``"no-net"`` is provided or the list contains only layer name, all the
+ nets are automatically considered.
quantity : str
Name of the quantity to plot.
setup : str, optional
@@ -3828,7 +3969,7 @@ def export_model_picture(
Parameters
----------
full_name : str, optional
- Full Path for exporting the image file. The default is ``None``, in which case working_dir will be used.
+ Full Path for exporting the image file. The default is ``None``, in which case working_dir is used.
show_axis : bool, optional
Whether to show the axes. The default is ``True``.
show_grid : bool, optional
@@ -4118,8 +4259,8 @@ def power_budget(self, units="W", temperature=22, output_type="component"):
output_type : str, optional
Output data presentation. The default is ``"component"``.
The options are ``"component"``, or ``"boundary"``.
- ``"component"`` will return the power based on each component.
- ``"boundary"`` will return the power based on each boundary.
+ ``"component"`` returns the power based on each component.
+ ``"boundary"`` returns the power based on each boundary.
Returns
-------
@@ -4454,23 +4595,27 @@ def extract_dataset_info(boundary_obj, units_input="W", boundary="Power"):
power_dict_obj[group] += power_dict_obj[power_comp]
if output_type == "boundary":
- for comp in power_dict.keys():
- self.logger.info("The power of {} is {} {}".format(comp, str(round(power_dict[comp], 3)), units))
+ for comp, value in power_dict.items():
+ if round(value, 3) != 0.0:
+ self.logger.info("The power of {} is {} {}".format(comp, str(round(value, 3)), units))
self.logger.info("The total power is {} {}".format(str(round(sum(power_dict.values()), 3)), units))
return power_dict, sum(power_dict.values())
elif output_type == "component": # pragma: no cover
- for comp in power_dict_obj.keys():
- self.logger.info("The power of {} is {} {}".format(comp, str(round(power_dict_obj[comp], 3)), units))
+ for comp, value in power_dict_obj.items():
+ if round(value, 3) != 0.0:
+ self.logger.info("The power of {} is {} {}".format(comp, str(round(value, 3)), units))
self.logger.info("The total power is {} {}".format(str(round(sum(power_dict_obj.values()), 3)), units))
return power_dict_obj, sum(power_dict_obj.values())
else: # pragma: no cover
- for comp in power_dict.keys():
- self.logger.info("The power of {} is {} {}".format(comp, str(round(power_dict[comp], 3)), units))
+ for comp, value in power_dict.items():
+ if round(value, 3) != 0.0:
+ self.logger.info("The power of {} is {} {}".format(comp, str(round(value, 3)), units))
self.logger.info("The total power is {} {}".format(str(round(sum(power_dict.values()), 3)), units))
- for comp in power_dict_obj.keys():
- self.logger.info("The power of {} is {} {}".format(comp, str(round(power_dict_obj[comp], 3)), units))
+ for comp, value in power_dict_obj.items():
+ if round(value, 3) != 0.0:
+ self.logger.info("The power of {} is {} {}".format(comp, str(round(value, 3)), units))
self.logger.info("The total power is {} {}".format(str(round(sum(power_dict_obj.values()), 3)), units))
return power_dict_obj, sum(power_dict_obj.values()), power_dict, sum(power_dict.values())
diff --git a/pyaedt/modules/SetupTemplates.py b/pyaedt/modules/SetupTemplates.py
index b55424bb77f..7142009842c 100644
--- a/pyaedt/modules/SetupTemplates.py
+++ b/pyaedt/modules/SetupTemplates.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
from __future__ import absolute_import
from collections import OrderedDict
diff --git a/pyaedt/modules/SolveSetup.py b/pyaedt/modules/SolveSetup.py
index fe6491c725b..c153da6b08a 100644
--- a/pyaedt/modules/SolveSetup.py
+++ b/pyaedt/modules/SolveSetup.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
"""
This module contains these classes: `Setup`, `Setup3DLayout`, and `SetupCircuit`.
@@ -101,7 +125,7 @@ def analyze(
that support automatic settings.
solve_in_batch : bool, optional
Whether to solve the project in batch or not.
- If ``True`` the project will be saved, closed, solved and repened.
+ If ``True`` the project will be saved, closed, and solved.
machine : str, optional
Name of the machine if remote. The default is ``"localhost"``.
run_in_thread : bool, optional
@@ -221,6 +245,20 @@ def name(self, name):
self._name = name
self.props["Name"] = name
+ @pyaedt_function_handler()
+ def get_profile(self):
+ """Solution profile.
+
+ Returns
+ -------
+ dict of :class:pyaedt.modeler.cad.elements3d.BinaryTree when solved setups exist,
+ ``None`` when no solved setups or no compatible application exists.
+ """
+ profile = self._app.get_profile(self.name)
+ if not isinstance(profile, dict) or not profile:
+ profile = None
+ return profile
+
@pyaedt_function_handler(sweep_name="sweep")
def get_solution_data(
self,
@@ -865,6 +903,54 @@ def add_mesh_link(
self.auto_update = auto_update
return False
+ def _parse_link_parameters(self, map_variables_by_name, parameters):
+ # parameters
+ params = OrderedDict({})
+ if map_variables_by_name:
+ parameters = self.p_app.available_variations.nominal_w_values_dict
+ for k, v in parameters.items():
+ params[k] = k
+ elif parameters is None:
+ parameters = self.p_app.available_variations.nominal_w_values_dict
+ for k, v in parameters.items():
+ params[k] = v
+ else:
+ for k, v in parameters.items():
+ if k in list(self._app.available_variations.nominal_w_values_dict.keys()):
+ params[k] = v
+ else:
+ params[k] = parameters[v]
+ return params
+
+ def _parse_link_solution(self, project, design, solution):
+ prev_solution = OrderedDict({})
+
+ # project name
+ if project != "This Project*":
+ if os.path.exists(project):
+ prev_solution["Project"] = project
+ self.props["PathRelativeTo"] = "SourceProduct"
+ else:
+ raise ValueError("Project file path provided does not exist.")
+ else:
+ prev_solution["Project"] = project
+ self.props["PathRelativeTo"] = "TargetProject"
+
+ # design name
+ if not design or design is None:
+ raise ValueError("Provide design name to add mesh link to.")
+ elif design not in self.p_app.design_list:
+ raise ValueError("Design does not exist in current project.")
+ else:
+ prev_solution["Design"] = design
+
+ # solution name
+ if solution:
+ prev_solution["Soln"] = solution
+ else:
+ raise ValueError("Provide a valid solution name.")
+ return prev_solution
+
@pyaedt_function_handler(
design_name="design", solution_name="solution", parameters_dict="parameters", project_name="project"
)
@@ -884,7 +970,7 @@ def start_continue_from_previous_setup(
----------
design : str
Name of the design.
- solution : str, optional
+ solution : str
Name of the solution in the format ``"name : solution_name"``.
For example, ``"Setup1 : Transient", "MySetup : LastAdaptive"``.
map_variables_by_name : bool, optional
@@ -924,49 +1010,9 @@ def start_continue_from_previous_setup(
try:
self.auto_update = False
- # parameters
- params = OrderedDict({})
- if map_variables_by_name:
- parameters = self.p_app.available_variations.nominal_w_values_dict
- for k, v in parameters.items():
- params[k] = k
- elif parameters is None:
- parameters = self.p_app.available_variations.nominal_w_values_dict
- for k, v in parameters.items():
- params[k] = v
- else:
- for k, v in parameters.items():
- if k in list(self._app.available_variations.nominal_w_values_dict.keys()):
- params[k] = v
- else:
- params[k] = parameters[v]
-
- prev_solution = OrderedDict({})
+ params = self._parse_link_parameters(map_variables_by_name, parameters)
- # project name
- if project != "This Project*":
- if os.path.exists(project):
- prev_solution["Project"] = project
- self.props["PathRelativeTo"] = "SourceProduct"
- else:
- raise ValueError("Project file path provided does not exist.")
- else:
- prev_solution["Project"] = project
- self.props["PathRelativeTo"] = "TargetProject"
-
- # design name
- if not design or design is None:
- raise ValueError("Provide design name to add mesh link to.")
- elif design not in self.p_app.design_list:
- raise ValueError("Design does not exist in current project.")
- else:
- prev_solution["Design"] = design
-
- # solution name
- if solution:
- prev_solution["Soln"] = solution
- else:
- raise ValueError("Provide a valid solution name.")
+ prev_solution = self._parse_link_solution(project, design, solution)
self.props["PrevSoln"] = prev_solution
@@ -1907,7 +1953,7 @@ def _get_net_names(self, app, file_fullname):
lay.name: lay.lower_elevation + lay.thickness / 2
for lay in list(self.p_app.modeler.edb.stackup.signal_layers.values())
}
- aedtapp = app(projectname=file_fullname)
+ aedtapp = app(project=file_fullname)
units = aedtapp.modeler.model_units
aedt_units = AEDT_UNITS["Length"][units]
self._convert_edb_to_aedt_units(input_dict=primitives_3d_pts_per_nets, output_unit=aedt_units)
@@ -1964,7 +2010,7 @@ def _get_net_names(self, app, file_fullname):
if aedtapp.design_type == "Q3D Extractor":
aedtapp.auto_identify_nets()
- aedtapp.close_project(save_project=True)
+ aedtapp.close_project(save=True)
@pyaedt_function_handler()
def _get_primitives_points_per_net(self):
@@ -3845,3 +3891,85 @@ def update(self, properties=None):
self.omodule.EditSetup(self.name, arg)
return True
+
+
+class SetupIcepak(Setup, object):
+ def __init__(self, app, solution_type, setup_name, is_new_setup=True):
+ Setup.__init__(self, app, solution_type, setup_name, is_new_setup)
+
+ def start_continue_from_previous_setup(
+ self,
+ design,
+ solution,
+ map_variables_by_name=True,
+ parameters=None,
+ project="This Project*",
+ force_source_to_solve=True,
+ preserve_partner_solution=True,
+ frozen_flow=False,
+ ):
+ """Start or continue from a previously solved setup.
+
+ Parameters
+ ----------
+ design : str
+ Name of the design.
+ solution : str
+ Name of the solution in the format ``"name : solution_name"``.
+ For example, ``"Setup1 : Transient"``, ``"Setup1 : SteadyState"``.
+ map_variables_by_name : bool, optional
+ Whether variables are mapped by name from the source design. The default is
+ ``True``.
+ parameters : dict, optional
+ Dictionary of the parameters. This argument is not considered if
+ ``map_variables_by_name=True``. If ``None``, the default is
+ ``appname.available_variations.nominal_w_values_dict``.
+ project : str, optional
+ Name of the project with the design. The default is ``"This Project*"``.
+ However, you can supply the full path and name to another project.
+ force_source_to_solve : bool, optional
+ The default is ``True``.
+ preserve_partner_solution : bool, optional
+ The default is ``True``.
+ frozen_flow : bool, optional
+ Whether to freeze the flow to the previous solution. The default is ``False``.
+
+ Returns
+ -------
+ bool
+ ``True`` when successful, ``False`` when failed.
+
+ References
+ ----------
+
+ >>> oModule.EditSetup
+
+ Examples
+ --------
+ >>> ipk = pyaedt.Icepak()
+ >>> setup = ipk.get_setup("Setup1")
+ >>> setup.start_continue_from_previous_setup(design="IcepakDesign1",solution="Setup1 : SteadyState")
+
+ """
+
+ auto_update = self.auto_update
+ try:
+ self.auto_update = False
+
+ params = self._parse_link_parameters(map_variables_by_name, parameters)
+
+ prev_solution = self._parse_link_solution(project, design, solution)
+
+ self.props["RestartSoln"] = prev_solution
+
+ self.props["RestartSoln"]["Params"] = params
+ self.props["RestartSoln"]["ForceSourceToSolve"] = force_source_to_solve
+ self.props["RestartSoln"]["PreservePartnerSoln"] = preserve_partner_solution
+ self.props["Frozen Flow Simulation"] = frozen_flow
+
+ self.update()
+ self.auto_update = auto_update
+ return True
+ except Exception:
+ self.auto_update = auto_update
+ return False
diff --git a/pyaedt/modules/SolveSweeps.py b/pyaedt/modules/SolveSweeps.py
index 6d1e1f0e60e..358fd340a0e 100644
--- a/pyaedt/modules/SolveSweeps.py
+++ b/pyaedt/modules/SolveSweeps.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
from collections import OrderedDict
import copy
from difflib import SequenceMatcher
@@ -6,10 +30,10 @@
import sys
import warnings
-from pyaedt import pyaedt_function_handler
from pyaedt.generic.DataHandlers import _dict2arg
from pyaedt.generic.LoadAEDTFile import load_entire_aedt_file
from pyaedt.generic.constants import unit_converter
+from pyaedt.generic.general_methods import pyaedt_function_handler
from pyaedt.generic.settings import settings
from pyaedt.modules.SetupTemplates import Sweep3DLayout
from pyaedt.modules.SetupTemplates import SweepHfss3D
@@ -75,8 +99,8 @@ class SweepHFSS(object):
Examples
--------
- >>> hfss = Hfss(specified_version=version, projectname=proj, designname=gtemDesign, solution_type=solutiontype,
- name=name, new_desktop_session=False, close_on_exit=False)
+ >>> hfss = Hfss(version=version, project=proj, design=gtemDesign, solution_type=solutiontype,
+ name=name, new_desktop=False, close_on_exit=False)
>>> hfss_setup = hfss.setups[0]
>>> hfss_sweep = SweepHFSS(hfss_setup, 'Sweep', sweep_type ='Interpolating', props=None)
diff --git a/pyaedt/modules/__init__.py b/pyaedt/modules/__init__.py
index e69de29bb2d..9c4476773da 100644
--- a/pyaedt/modules/__init__.py
+++ b/pyaedt/modules/__init__.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
diff --git a/pyaedt/modules/fields_calculator.py b/pyaedt/modules/fields_calculator.py
new file mode 100644
index 00000000000..f3cff929aa9
--- /dev/null
+++ b/pyaedt/modules/fields_calculator.py
@@ -0,0 +1,365 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+import copy
+import os
+
+import pyaedt
+from pyaedt.generic.general_methods import generate_unique_project_name
+from pyaedt.generic.general_methods import open_file
+from pyaedt.generic.general_methods import pyaedt_function_handler
+from pyaedt.generic.general_methods import read_toml
+
+
+class FieldsCalculator:
+ def __init__(self, app):
+ self.expression_catalog = read_toml(os.path.join(pyaedt.__path__[0], "misc", "expression_catalog.toml"))
+ self.__app = app
+ self.design_type = app.design_type
+ self.ofieldsreporter = app.ofieldsreporter
+
+ @property
+ def expression_names(self):
+ """List of available expressions.
+
+ Returns
+ -------
+ list
+ """
+ return list(self.expression_catalog.keys())
+
+ @pyaedt_function_handler()
+ def add_expression(self, calculation, assignment, name=None):
+ """Add named expression.
+
+ Parameters
+ ----------
+ calculation :
+ Calculation type.
+ assignment : int or :class:`pyaedt.modeler.cad.object3d.Object3d` or
+ :class:`pyaedt.modeler.cad.FacePrimitive
+ Name of the object to add the named expression from.
+ name : str, optional
+ Name of the named expression. The default is ``None``.
+
+ Returns
+ -------
+ str, bool
+ Named expression when successful, ``False`` when failed.
+ """
+ if assignment is not None:
+ assignment = self.__app.modeler.convert_to_selections(assignment, return_list=True)[0]
+
+ if calculation not in self.expression_names:
+ self.__app.logger.error("Calculation is not available.")
+ return False
+
+ expression_info = copy.deepcopy(self.expression_catalog[calculation])
+
+ if not name:
+ name = expression_info["name"]
+
+ expression_info["name"] = name
+
+ if self.is_expression_defined(expression_info["name"]):
+ self.__app.logger.debug("Named expression already exists.")
+ return expression_info["name"]
+
+ # Check design type
+ design_type = self.__app.design_type
+ if design_type not in expression_info["design_type"]:
+ self.__app.logger.error("Design type is not compatible.")
+ return False
+ design_type_index = expression_info["design_type"].index(design_type)
+
+ # Check assignment type
+ if assignment and isinstance(assignment, str) and assignment not in self.__app.modeler.object_names:
+ self.__app.logger.error("Assignment type is not correct.")
+ return False
+
+ # Check assignment type
+ if assignment and isinstance(assignment, str):
+ assignment_type = self.__app.modeler.objects_by_name[assignment].object_type
+ if assignment_type not in expression_info["assignment_type"]:
+ self.__app.logger.error("Wrong assignment type.")
+ return False
+ elif assignment and isinstance(assignment, int):
+ if "Face" not in expression_info["assignment_type"]:
+ self.__app.logger.error("Wrong assignment type.")
+ return False
+ else:
+ assignment = "Face" + str(assignment)
+
+ # Check constants
+ if "constants" in expression_info:
+ constants = expression_info["constants"]
+ if constants:
+ for k, v in constants.items():
+ self.__app.variable_manager.set_variable(k, v, postprocessing=True)
+
+ # Check for dependent expressions
+ if expression_info["dependent_expressions"]:
+ for expression in expression_info["dependent_expressions"]:
+ expression_name = self.add_expression(calculation=expression, assignment=None)
+ expression_info["operations"] = [
+ operation.replace(expression, expression_name) for operation in expression_info["operations"]
+ ]
+
+ if assignment is not None:
+ expression_info["assignment"] = assignment
+
+ expression_info["operations"] = [
+ operation.replace("assignment", expression_info["assignment"])
+ for operation in expression_info["operations"]
+ ]
+
+ # Create clc file
+ file_name = self.create_expression_file(expression_info["name"], expression_info["operations"])
+
+ # Import clc
+ self.ofieldsreporter.LoadNamedExpressions(
+ os.path.abspath(file_name), expression_info["fields_type"][design_type_index], [name]
+ )
+
+ return expression_info["name"]
+
+ @pyaedt_function_handler()
+ def create_expression_file(self, name, operations):
+ """Create a calculator expression file.
+
+ Parameters
+ ----------
+ name : str
+ Name of the expression.
+ operations : list
+ List of operations in the calculator.
+
+ Returns
+ -------
+ str, bool
+ Path of the calculator expression file when successful, ``False`` when failed.
+ """
+ file_name = generate_unique_project_name(
+ root_name=self.__app.toolkit_directory,
+ folder_name=self.__app.design_name,
+ project_name=name,
+ project_format="clc",
+ )
+ try:
+ with open_file(file_name, "w") as file:
+ file.write("$begin 'Named_Expression'\n")
+ file.write(f" Name('{name}')\n")
+ for operation in operations:
+ file.write(f" {operation}\n")
+ file.write("$end 'Named_Expression'\n")
+ except Exception: # pragma: no cover
+ return False
+ return os.path.abspath(file_name)
+
+ @pyaedt_function_handler()
+ def expression_plot(self, calculation, assignment, names, setup=None):
+ """Add a named expression.
+
+ Parameters
+ ----------
+ calculation : str
+ Calculation type.
+ assignment : list
+ List of assignments to apply the expression to. If the expression is not general, assignment is not needed.
+ names : list
+ Name of the expressions to plot.
+ setup : str
+ Analysis setup.
+
+ Returns
+ -------
+ list
+ List of created reports.
+ """
+ if assignment is not None:
+ assignment = self.__app.modeler.convert_to_selections(assignment, return_list=True)
+
+ for name in names:
+ if not self.is_expression_defined(name):
+ self.__app.logger.error("Named expression not available.")
+ return False
+
+ if calculation not in self.expression_names:
+ self.__app.logger.error("Calculation is not available.")
+ return False
+
+ if not setup:
+ setup = self.__app.existing_analysis_sweeps[0]
+
+ expression_info = self.expression_catalog[calculation]
+ fields_type = expression_info["fields_type"]
+ primary_sweep = expression_info["primary_sweep"]
+
+ reports = []
+
+ for report_type in expression_info["report"]: # pragma: no cover
+ if report_type in ["Data Table", "Rectangular Plot"]:
+ assignment_report = assignment
+ primary_sweep_report = primary_sweep
+ if self.is_general_expression(calculation):
+ # General expression to calculate the field over the polyline distance
+ primary_sweep_report = "Distance"
+ else:
+ # Non-general expression does not need assignment
+ assignment_report = [None]
+
+ if None in assignment_report or (
+ not self.__has_integer(assignment_report) and self.__has_lines(assignment_report)
+ ):
+ for assign in assignment_report:
+ if "CG Fields" in fields_type and self.design_type == "Q3D Extractor":
+ report = self.__app.post.reports_by_category.cg_fields(names, setup, polyline=assign)
+ elif "DC R/L Fields" in fields_type and self.design_type == "Q3D Extractor":
+ report = self.__app.post.reports_by_category.dc_fields(names, setup, polyline=assign)
+ else:
+ report = self.__app.post.reports_by_category.fields(names, setup, polyline=assign)
+ report.report_type = report_type
+ report.primary_sweep = primary_sweep_report
+ report.create()
+ reports.append(report)
+ elif report_type in ["Field_3D"]:
+ intrinsic = {}
+ if self.design_type == "Q3D Extractor":
+ intrinsic = {"Freq": self.__app.setups[0].props["AdaptiveFreq"]}
+ for assign in assignment:
+ if isinstance(assign, int) or assign in self.__app.modeler.sheet_names:
+ report = self.__app.post.create_fieldplot_surface(
+ quantity=names[0], assignment=assign, field_type=fields_type, intrinsics=intrinsic
+ )
+ reports.append(report)
+ else:
+ if assign not in self.__app.modeler.point_names and assign not in self.__app.modeler.line_names:
+ report = self.__app.post.create_fieldplot_volume(
+ quantity=names[0], assignment=assign, field_type=fields_type, intrinsics=intrinsic
+ )
+ reports.append(report)
+ return reports
+
+ @pyaedt_function_handler()
+ def delete_expression(self, name=None):
+ """Delete a named expression.
+
+ Parameters
+ ----------
+ name : str, optional
+ Name of the named expression. The default is ``None``, in which case all named expressions are deleted.
+
+ Returns
+ -------
+ bool
+ ``True`` when successful, ``False`` when failed.
+ """
+ if not name:
+ self.ofieldsreporter.ClearAllNamedExpr()
+ return True
+ if self.is_expression_defined(name):
+ self.ofieldsreporter.DeleteNamedExpr(name)
+ return True
+
+ @pyaedt_function_handler()
+ def is_expression_defined(self, name):
+ """Check if a named expression exists.
+
+ Parameters
+ ----------
+ name : str,
+ Named expression.
+
+ Returns
+ -------
+ bool
+ ``True`` when exists.
+ """
+ is_defined = self.ofieldsreporter.DoesNamedExpressionExists(name)
+ if is_defined == 1:
+ return True
+ return False
+
+ @pyaedt_function_handler()
+ def is_general_expression(self, name):
+ """Check if a named expression is general.
+
+ Parameters
+ ----------
+ name : str,
+ Named expression.
+
+ Returns
+ -------
+ bool
+ ``True`` if the named expression is general.
+ """
+ if name not in self.expression_names:
+ self.__app.logger.error("Named expression not available.")
+ return False
+ is_general = True
+ for operation in self.expression_catalog[name]["operations"]:
+ if "assignment" in operation:
+ is_general = False
+ break
+ return is_general
+
+ @pyaedt_function_handler()
+ def load_expression_file(self, input_file):
+ """Load expressions from a TOML file.
+
+ Parameters
+ ----------
+ input_file : str
+ Full path to the file.
+
+ Returns
+ -------
+ dict
+ Dictionary of available expressions.
+ """
+ if not os.path.isfile(input_file):
+ self.__app.logger.error("File does not exist.")
+ return False
+
+ new_expression_catalog = read_toml(input_file)
+
+ if new_expression_catalog:
+ self.expression_catalog.update(new_expression_catalog)
+
+ return self.expression_catalog
+
+ @staticmethod
+ def __has_integer(lst): # pragma: no cover
+ """Check if a list has integers."""
+ for item in lst:
+ if isinstance(item, int):
+ return True
+ return False
+
+ def __has_lines(self, lst): # pragma: no cover
+ """Check if a list has lines."""
+ for item in lst:
+ if item not in self.__app.modeler.line_names:
+ return False
+ return True
diff --git a/pyaedt/modules/monitor_icepak.py b/pyaedt/modules/monitor_icepak.py
index 4e3438d5b0d..aa6b933696b 100644
--- a/pyaedt/modules/monitor_icepak.py
+++ b/pyaedt/modules/monitor_icepak.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
import re
from pyaedt.generic.DataHandlers import _dict2arg
diff --git a/pyaedt/modules/report_templates.py b/pyaedt/modules/report_templates.py
index 17d20478ab6..52431ad2114 100644
--- a/pyaedt/modules/report_templates.py
+++ b/pyaedt/modules/report_templates.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
from collections import OrderedDict
import copy
import os
@@ -378,7 +402,7 @@ def differential_pairs(self, value):
@property
def matrix(self):
- """2D or Q3D matrix name.
+ """Maxwell 2D/3D or Q2D/Q3D matrix name.
Returns
-------
@@ -391,6 +415,21 @@ def matrix(self):
def matrix(self, value):
self.props["context"]["matrix"] = value
+ @property
+ def reduced_matrix(self):
+ """Maxwell 2D/3D reduced matrix name for eddy current solvers.
+
+ Returns
+ -------
+ str
+ Reduced matrix name.
+ """
+ return self.props["context"].get("reduced_matrix", None)
+
+ @reduced_matrix.setter
+ def reduced_matrix(self, value):
+ self.props["context"]["reduced_matrix"] = value
+
@property
def polyline(self):
"""Polyline name for the field report.
@@ -2152,6 +2191,16 @@ def _context(self):
ctxt = ["Context:=", "Original"]
else:
ctxt = ["Context:=", self.matrix]
+ elif (
+ self._post._app.design_type in ["Maxwell 2D", "Maxwell 3D"]
+ and self._post._app.solution_type == "EddyCurrent"
+ ):
+ if not self.matrix:
+ ctxt = ["Context:=", "Original"]
+ elif not self.reduced_matrix:
+ ctxt = ["Context:=", self.matrix]
+ elif self.reduced_matrix:
+ ctxt = ["Context:=", self.matrix, "Matrix:=", self.reduced_matrix]
elif self._post.post_solution_type in ["HFSS3DLayout"]:
if self.domain == "DCIR":
ctxt = [
@@ -2587,6 +2636,9 @@ def _context(self):
"USE_PRI_DIST",
False,
"0" if not self.enable_jitter_distribution else "1",
+ "SID",
+ False,
+ "0",
]
if self.enable_jitter_distribution and str(self.quantity_type) == "3":
sim_context = [
@@ -2631,6 +2683,9 @@ def _context(self):
"PID",
False,
"0",
+ "SID",
+ False,
+ "0",
"PRIDIST",
False,
"0",
@@ -2656,6 +2711,31 @@ def _context(self):
"SimValueContext:=",
sim_context,
]
+ if len(self.expressions) == 1:
+ sid = 0
+ pid = 0
+ expr = self.expressions[0]
+ category = "Eye"
+ found = False
+ while not found:
+ available_quantities = self._post.available_report_quantities(
+ self.report_category, self.report_type, self.setup, category, arg
+ )
+ if len(available_quantities) == 1 and available_quantities[0].lower() == expr.lower():
+ found = True
+ else:
+ sid += 1
+ pid += 1
+ arg[2][arg[2].index("SID") + 2] = str(sid)
+ arg[2][arg[2].index("PID") + 2] = str(pid)
+ # Limited maximum iterations to 1000 in While loop (Too many probes to analyze even in a single design)
+ if sid > 1000:
+ self._post.logger.error(
+ "Failed to find right context for expression : {}".format(",".join(self.expressions))
+ )
+ # arg[2][arg[2].index("SID") + 2] = "0"
+ # arg[2][arg[2].index("PID") + 2] = "0"
+ break
return arg
@property
@@ -3178,8 +3258,43 @@ def _context(self):
"QTID",
False,
str(self.quantity_type),
+ "SCID",
+ False,
+ "-1",
+ "SID",
+ False,
+ "0",
],
]
+ if len(self.expressions) == 1:
+ sid = 0
+ pid = 0
+ expr = self.expressions[0]
+ category = "Wave"
+ if self.report_category == "Statistical Eye":
+ category = "Eye"
+ if self.report_category == "Eye Diagram" and self.report_type == "Rectangular Plot":
+ category = "Voltage"
+ found = False
+ while not found:
+ available_quantities = self._post.available_report_quantities(
+ self.report_category, self.report_type, self.setup, category, arg
+ )
+ if len(available_quantities) == 1 and available_quantities[0].lower() == expr.lower():
+ found = True
+ else:
+ sid += 1
+ pid += 1
+ arg[2][arg[2].index("SID") + 2] = str(sid)
+ arg[2][arg[2].index("PID") + 2] = str(pid)
+ # Limited maximum iterations to 1000 in While loop (Too many probes to analyze even in a single design)
+ if sid > 1000:
+ self._post.logger.error(
+ "Failed to find right context for expression : {}".format(",".join(self.expressions))
+ )
+ # arg[2][arg[2].index("SID") + 2] = "0"
+ # arg[2][arg[2].index("PID") + 2] = "0"
+ break
return arg
@property
diff --git a/pyaedt/modules/solutions.py b/pyaedt/modules/solutions.py
index 7a41f7a6b18..76bcea79203 100644
--- a/pyaedt/modules/solutions.py
+++ b/pyaedt/modules/solutions.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
from collections import OrderedDict
import itertools
import json
@@ -8,17 +32,18 @@
import sys
import time
-from pyaedt import is_ironpython
-from pyaedt import pyaedt_function_handler
from pyaedt.application.Variables import decompose_variable_value
from pyaedt.generic.constants import AEDT_UNITS
+from pyaedt.generic.constants import CSS4_COLORS
from pyaedt.generic.constants import db10
from pyaedt.generic.constants import db20
from pyaedt.generic.constants import unit_converter
from pyaedt.generic.general_methods import check_and_download_file
from pyaedt.generic.general_methods import check_and_download_folder
from pyaedt.generic.general_methods import conversion_function
+from pyaedt.generic.general_methods import is_ironpython
from pyaedt.generic.general_methods import open_file
+from pyaedt.generic.general_methods import pyaedt_function_handler
from pyaedt.generic.general_methods import write_csv
from pyaedt.generic.plot import get_structured_mesh
from pyaedt.generic.plot import is_notebook
@@ -27,6 +52,7 @@
from pyaedt.generic.plot import plot_polar_chart
from pyaedt.generic.settings import settings
from pyaedt.modeler.cad.elements3d import FacePrimitive
+from pyaedt.modeler.geometry_operators import GeometryOperators
np = None
pd = None
@@ -50,6 +76,368 @@
plt = None
+@pyaedt_function_handler()
+def _parse_nastran(file_path):
+ logger = logging.getLogger("Global")
+ nas_to_dict = {"Points": [], "PointsId": {}, "Assemblies": {}}
+ includes = []
+
+ def parse_lines(input_lines, input_pid=0, in_assembly="Main"):
+ if in_assembly not in nas_to_dict["Assemblies"]:
+ nas_to_dict["Assemblies"][in_assembly] = {"Triangles": {}, "Solids": {}, "Lines": {}}
+
+ def get_point(ll, start, length):
+ n = ll[start : start + length].strip()
+ if "-" in n[1:] and "e" not in n[1:].lower():
+ n = n[0] + n[1:].replace("-", "e-")
+ return n
+
+ for lk in range(len(input_lines)):
+ line = input_lines[lk]
+ line_type = line[:8].strip()
+ obj_type = "Triangles"
+ if line.startswith("$") or line.startswith("*"):
+ continue
+ elif line_type in ["GRID", "GRID*"]:
+ num_points = 3
+ obj_type = "Grid"
+ elif line_type in [
+ "CTRIA3",
+ "CTRIA3*",
+ ]:
+ num_points = 3
+ obj_type = "Triangles"
+ elif line_type in ["CROD", "CBEAM", "CBAR", "CROD*", "CBEAM*", "CBAR*"]:
+ num_points = 2
+ obj_type = "Lines"
+ elif line_type in [
+ "CQUAD4",
+ "CQUAD4*",
+ ]:
+ num_points = 4
+ obj_type = "Triangles"
+ elif line_type in ["CTETRA", "CTETRA*"]:
+ num_points = 4
+ obj_type = "Solids"
+ elif line_type in ["CPYRA", "CPYRAM", "CPYRA*", "CPYRAM*"]:
+ num_points = 5
+ obj_type = "Solids"
+ else:
+ continue
+
+ points = []
+ start_pointer = 8
+ word_length = 8
+ if line_type.endswith("*"):
+ word_length = 16
+ grid_id = int(line[start_pointer : start_pointer + word_length])
+ pp = 0
+ start_pointer = start_pointer + word_length
+ object_id = line[start_pointer : start_pointer + word_length]
+ if obj_type != "Grid":
+ object_id = int(object_id)
+ if object_id not in nas_to_dict["Assemblies"][in_assembly][obj_type]:
+ nas_to_dict["Assemblies"][in_assembly][obj_type][object_id] = []
+ while pp < num_points:
+ start_pointer = start_pointer + word_length
+ if start_pointer >= 72:
+ lk += 1
+ line = input_lines[lk]
+ start_pointer = 8
+ points.append(get_point(line, start_pointer, word_length))
+ pp += 1
+
+ if line_type in ["GRID", "GRID*"]:
+ nas_to_dict["PointsId"][grid_id] = input_pid
+ nas_to_dict["Points"].append([float(i) for i in points])
+ input_pid += 1
+ elif line_type in [
+ "CTRIA3",
+ "CTRIA3*",
+ ]:
+ tri = [nas_to_dict["PointsId"][int(i)] for i in points]
+ nas_to_dict["Assemblies"][in_assembly]["Triangles"][object_id].append(tri)
+ elif line_type in ["CROD", "CBEAM", "CBAR", "CROD*", "CBEAM*", "CBAR*"]:
+ tri = [nas_to_dict["PointsId"][int(i)] for i in points]
+ nas_to_dict["Assemblies"][in_assembly]["Lines"][object_id].append(tri)
+ elif line_type in ["CQUAD4", "CQUAD4*"]:
+ tri = [
+ nas_to_dict["PointsId"][int(points[0])],
+ nas_to_dict["PointsId"][int(points[1])],
+ nas_to_dict["PointsId"][int(points[2])],
+ ]
+ nas_to_dict["Assemblies"][in_assembly]["Triangles"][object_id].append(tri)
+ tri = [
+ nas_to_dict["PointsId"][int(points[0])],
+ nas_to_dict["PointsId"][int(points[2])],
+ nas_to_dict["PointsId"][int(points[3])],
+ ]
+ nas_to_dict["Assemblies"][in_assembly]["Triangles"][object_id].append(tri)
+ else:
+ from itertools import combinations
+
+ for k in list(combinations(points, 3)):
+ tri = [
+ nas_to_dict["PointsId"][int(k[0])],
+ nas_to_dict["PointsId"][int(k[1])],
+ nas_to_dict["PointsId"][int(k[2])],
+ ]
+ tri.sort()
+ tri = tuple(tri)
+ nas_to_dict["Assemblies"][in_assembly]["Solids"][object_id].append(tri)
+
+ return input_pid
+
+ logger.info("Loading file")
+ with open_file(file_path, "r") as f:
+ lines = f.read().splitlines()
+ for line in lines:
+ if line.startswith("INCLUDE"):
+ includes.append(line.split(" ")[1].replace("'", "").strip())
+ pid = parse_lines(lines)
+ for include in includes:
+ with open_file(os.path.join(os.path.dirname(file_path), include), "r") as f:
+ lines = f.read().splitlines()
+ name = include.split(".")[0]
+ pid = parse_lines(lines, pid, name)
+ logger.info("File loaded")
+ for assembly in list(nas_to_dict["Assemblies"].keys())[::]:
+ if (
+ nas_to_dict["Assemblies"][assembly]["Triangles"]
+ == nas_to_dict["Assemblies"][assembly]["Solids"]
+ == nas_to_dict["Assemblies"][assembly]["Lines"]
+ == {}
+ ):
+ del nas_to_dict["Assemblies"][assembly]
+ for _, assembly_object in nas_to_dict["Assemblies"].items():
+
+ def domino(segments):
+
+ def check_new_connection(s, polylines, exclude_index=-1):
+ s = s[:]
+ polylines = [poly[:] for poly in polylines]
+ attached = False
+ p_index = None
+ for i, p in enumerate(polylines):
+ if i == exclude_index:
+ continue
+ if s[0] == p[-1]:
+ p.extend(s[1:]) # the new segment attaches to the end
+ attached = True
+ elif s[-1] == p[0]:
+ for item in reversed(s[:-1]):
+ p.insert(0, item) # the new segment attaches to the beginning
+ attached = True
+ elif s[0] == p[0]:
+ for item in s[1:]:
+ p.insert(0, item) # the new segment attaches to the beginning in reverse order
+ attached = True
+ elif s[-1] == p[-1]:
+ p.extend(s[-2::-1]) # the new segment attaches to the end in reverse order
+ attached = True
+ if attached:
+ p_index = i
+ break
+ if not attached:
+ polylines.append(s)
+ return polylines, attached, p_index
+
+ polylines = []
+ for segment in segments:
+ polylines, attached_flag, attached_p_index = check_new_connection(segment, polylines)
+ if attached_flag:
+ other_polylines = polylines[:attached_p_index] + polylines[attached_p_index + 1 :]
+ polylines, _, _ = check_new_connection(
+ polylines[attached_p_index], other_polylines, attached_p_index
+ )
+
+ return polylines
+
+ def remove_self_intersections(polylines):
+ polylines = [poly[:] for poly in polylines]
+ new_polylines = []
+ for p in polylines:
+ if p[0] in p[1:]:
+ new_polylines.append([p[0], p[1]])
+ p.pop(0)
+ if p[-1] in p[:-1]:
+ new_polylines.append([p[-2], p[-1]])
+ p.pop(-1)
+ new_polylines.append(p)
+ return new_polylines
+
+ if assembly_object["Lines"]:
+ for lname, lines in assembly_object["Lines"].items():
+ new_lines = lines[::]
+ new_lines = remove_self_intersections(domino(new_lines))
+ assembly_object["Lines"][lname] = new_lines
+
+ return nas_to_dict
+
+
+@pyaedt_function_handler()
+def _write_stl(nas_to_dict, decimation, working_directory, enable_planar_merge=True):
+ logger = logging.getLogger("Global")
+
+ def _write_solid_stl(triangle, pp):
+ try:
+ # points = [nas_to_dict["Points"][id] for id in triangle]
+ points = [pp[i] for i in triangle]
+ except KeyError: # pragma: no cover
+ return
+ fc = GeometryOperators.get_polygon_centroid(points)
+ v1 = points[0]
+ v2 = points[1]
+ cv1 = GeometryOperators.v_points(fc, v1)
+ cv2 = GeometryOperators.v_points(fc, v2)
+ if cv2[0] == cv1[0] == 0.0 and cv2[1] == cv1[1] == 0.0:
+ n = [0, 0, 1] # pragma: no cover
+ elif cv2[0] == cv1[0] == 0.0 and cv2[2] == cv1[2] == 0.0:
+ n = [0, 1, 0] # pragma: no cover
+ elif cv2[1] == cv1[1] == 0.0 and cv2[2] == cv1[2] == 0.0:
+ n = [1, 0, 0] # pragma: no cover
+ else:
+ n = GeometryOperators.v_cross(cv1, cv2)
+
+ normal = GeometryOperators.normalize_vector(n)
+ if normal:
+ f.write(" facet normal {} {} {}\n".format(normal[0], normal[1], normal[2]))
+ f.write(" outer loop\n")
+ f.write(" vertex {} {} {}\n".format(points[0][0], points[0][1], points[0][2]))
+ f.write(" vertex {} {} {}\n".format(points[1][0], points[1][1], points[1][2]))
+ f.write(" vertex {} {} {}\n".format(points[2][0], points[2][1], points[2][2]))
+ f.write(" endloop\n")
+ f.write(" endfacet\n")
+
+ logger.info("Creating STL file with detected faces")
+ enable_stl_merge = False if enable_planar_merge == "False" or enable_planar_merge is False else True
+
+ def decimate(points_in, faces_in):
+ fin = [[3] + list(i) for i in faces_in]
+ mesh = pv.PolyData(points_in, faces=fin)
+ new_mesh = mesh.decimate_pro(decimation, preserve_topology=True, boundary_vertex_deletion=False)
+ points_out = list(new_mesh.points)
+ faces_out = [i[1:] for i in new_mesh.faces.reshape(-1, 4) if i[0] == 3]
+ return points_out, faces_out
+
+ output_stls = []
+ for assembly_name, assembly in nas_to_dict["Assemblies"].items():
+ output_stl = os.path.join(working_directory, assembly_name + ".stl")
+ f = open(output_stl, "w")
+ for tri_id, triangles in assembly["Triangles"].items():
+ tri_out = triangles
+ p_out = nas_to_dict["Points"][::]
+ if decimation > 0 and len(triangles) > 20:
+ p_out, tri_out = decimate(nas_to_dict["Points"], tri_out)
+ f.write("solid Sheet_{}\n".format(tri_id))
+ if enable_planar_merge == "Auto" and len(tri_out) > 50000:
+ enable_stl_merge = False # pragma: no cover
+ for triangle in tri_out:
+ _write_solid_stl(triangle, p_out)
+ f.write("endsolid\n")
+ for solidid, solid_triangles in assembly["Solids"].items():
+ f.write("solid Solid_{}\n".format(solidid))
+ import pandas as pd
+
+ df = pd.Series(solid_triangles)
+ tri_out = df.drop_duplicates(keep=False).to_list()
+ p_out = nas_to_dict["Points"][::]
+ if decimation > 0 and len(solid_triangles) > 20:
+ p_out, tri_out = decimate(nas_to_dict["Points"], tri_out)
+ if enable_planar_merge == "Auto" and len(tri_out) > 50000:
+ enable_stl_merge = False # pragma: no cover
+ for triangle in tri_out:
+ _write_solid_stl(triangle, p_out)
+ f.write("endsolid\n")
+ f.close()
+ output_stls.append(output_stl)
+ logger.info("STL file created")
+ return output_stls, enable_stl_merge
+
+
+def nastran_to_stl(input_file, output_folder=None, decimation=0, enable_planar_merge="True", preview=False):
+ logger = logging.getLogger("Global")
+ nas_to_dict = _parse_nastran(input_file)
+
+ empty = True
+ for assembly in nas_to_dict["Assemblies"].values():
+ if assembly["Triangles"] or assembly["Solids"] or assembly["Lines"]:
+ empty = False
+ break
+ if empty: # pragma: no cover
+ logger.error("Failed to import file. Check the model and retry")
+ return False
+ if output_folder is None:
+ output_folder = os.path.dirname(input_file)
+ output_stls, enable_stl_merge = _write_stl(nas_to_dict, decimation, output_folder, enable_planar_merge)
+ if preview:
+ logger.info("Generating preview...")
+ if decimation > 0:
+ pl = pv.Plotter(shape=(1, 2))
+ else: # pragma: no cover
+ pl = pv.Plotter()
+ dargs = dict(show_edges=True)
+ colors = []
+ color_by_assembly = True
+ if len(nas_to_dict["Assemblies"]) == 1:
+ color_by_assembly = False
+
+ def preview_pyvista(dict_in):
+ css4_colors = list(CSS4_COLORS.values())
+ k = 0
+ p_out = nas_to_dict["Points"][::]
+ for assembly in dict_in["Assemblies"].values():
+ if color_by_assembly:
+ h = css4_colors[k].lstrip("#")
+ colors.append(tuple(int(h[i : i + 2], 16) for i in (0, 2, 4)))
+ k += 1
+
+ for triangles in assembly["Triangles"].values():
+ tri_out = triangles
+ fin = [[3] + list(i) for i in tri_out]
+ if not color_by_assembly:
+ h = css4_colors[k].lstrip("#")
+ colors.append(tuple(int(h[i : i + 2], 16) for i in (0, 2, 4)))
+ k = k + 1 if k < len(css4_colors) - 1 else 0
+ pl.add_mesh(pv.PolyData(p_out, faces=fin), color=colors[-1], **dargs)
+
+ for triangles in assembly["Solids"].values():
+ import pandas as pd
+
+ df = pd.Series(triangles)
+ tri_out = df.drop_duplicates(keep=False).to_list()
+ p_out = nas_to_dict["Points"][::]
+ fin = [[3] + list(i) for i in tri_out]
+ if not color_by_assembly:
+ h = css4_colors[k].lstrip("#")
+ colors.append(tuple(int(h[i : i + 2], 16) for i in (0, 2, 4)))
+ k = k + 1 if k < len(css4_colors) - 1 else 0
+
+ pl.add_mesh(pv.PolyData(p_out, faces=fin), color=colors[-1], **dargs)
+
+ preview_pyvista(nas_to_dict)
+ pl.add_text("Input mesh", font_size=24)
+ pl.reset_camera()
+ if decimation > 0 and output_stls:
+ k = 0
+ pl.reset_camera()
+ pl.subplot(0, 1)
+ css4_colors = list(CSS4_COLORS.values())
+ for output_stl in output_stls:
+ mesh = pv.read(output_stl)
+ h = css4_colors[k].lstrip("#")
+ colors.append(tuple(int(h[i : i + 2], 16) for i in (0, 2, 4)))
+ pl.add_mesh(mesh, color=colors[-1], **dargs)
+ k = k + 1 if k < len(css4_colors) - 1 else 0
+ pl.add_text("Decimated mesh", font_size=24)
+ pl.reset_camera()
+ pl.link_views()
+ if "PYTEST_CURRENT_TEST" not in os.environ:
+ pl.show() # pragma: no cover
+ logger.info("STL files created")
+ return output_stls, nas_to_dict, enable_stl_merge
+
+
def simplify_stl(input_file, output_file=None, decimation=0.5, preview=False):
"""Import and simplify a stl file using pyvista and fast-simplification.
@@ -63,7 +451,8 @@ def simplify_stl(input_file, output_file=None, decimation=0.5, preview=False):
Fraction of the original mesh to remove before creating the stl file. If set to ``0.9``,
this function will try to reduce the data set to 10% of its
original size and will remove 90% of the input triangles.
-
+ preview : bool, optional
+ Whether to preview the model in pyvista or skip it.
Returns
-------
str
@@ -843,6 +1232,8 @@ def plot(
Full path to image file if a snapshot is needed.
is_polar : bool, optional
Set to `True` if this is a polar plot.
+ show : bool, optional
+ Whether if show the plot or not. Default is set to `True`.
Returns
-------
@@ -930,6 +1321,8 @@ def plot_3d(
snapshot_path : str, optional
Full path to image file if a snapshot is needed.
The default is ``None``.
+ show : bool, optional
+ Whether if show the plot or not. Default is set to `True`.
Returns
-------
@@ -1165,7 +1558,7 @@ class FfdSolutionData(object):
>>> import pyaedt
>>> from pyaedt.modules.solutions import FfdSolutionData
- >>> app = pyaedt.Hfss(specified_version="2023.2", designname="Antenna")
+ >>> app = pyaedt.Hfss(version="2023.2", design="Antenna")
>>> setup_name = "Setup1 : LastAdaptive"
>>> frequencies = [77e9]
>>> sphere = "3D"
@@ -1182,7 +1575,7 @@ def __init__(
eep_files,
frequencies,
):
- self.logger = logging.getLogger(__name__)
+ self.logger = logging.getLogger("Global")
self._raw_data = {}
self.farfield_data = {}
@@ -1640,7 +2033,7 @@ def plot_farfield_contour(
Examples
--------
>>> import pyaedt
- >>> app = pyaedt.Hfss(specified_version="2024.1", designname="Antenna")
+ >>> app = pyaedt.Hfss(version="2024.1", design="Antenna")
>>> setup_name = "Setup1 : LastAdaptive"
>>> frequencies = [77e9]
>>> sphere = "3D"
@@ -1779,7 +2172,7 @@ def plot_2d_cut(
Examples
--------
>>> import pyaedt
- >>> app = pyaedt.Hfss(specified_version="2023.2", designname="Antenna")
+ >>> app = pyaedt.Hfss(version="2023.2", design="Antenna")
>>> setup_name = "Setup1 : LastAdaptive"
>>> frequencies = [77e9]
>>> sphere = "3D"
@@ -1920,7 +2313,7 @@ def polar_plot_3d(
Examples
--------
>>> import pyaedt
- >>> app = pyaedt.Hfss(specified_version="2023.2", designname="Antenna")
+ >>> app = pyaedt.Hfss(version="2023.2", design="Antenna")
>>> setup_name = "Setup1 : LastAdaptive"
>>> frequencies = [77e9]
>>> sphere = "3D"
@@ -2025,7 +2418,7 @@ def polar_plot_3d_pyvista(
Examples
--------
>>> import pyaedt
- >>> app = pyaedt.Hfss(specified_version="2023.2", designname="Antenna")
+ >>> app = pyaedt.Hfss(version="2023.2", design="Antenna")
>>> setup_name = "Setup1 : LastAdaptive"
>>> frequencies = [77e9]
>>> sphere = "3D"
@@ -2543,7 +2936,7 @@ class FfdSolutionDataExporter(FfdSolutionData):
Examples
--------
>>> import pyaedt
- >>> app = pyaedt.Hfss(specified_version="2023.2", designname="Antenna")
+ >>> app = pyaedt.Hfss(version="2023.2", design="Antenna")
>>> setup_name = "Setup1 : LastAdaptive"
>>> frequencies = [77e9]
>>> sphere = "3D"
@@ -2770,29 +3163,29 @@ class FieldPlot:
def __init__(
self,
postprocessor,
- objects=[],
- surfaces=[],
- lines=[],
- cutplanes=[],
+ objects=None,
+ surfaces=None,
+ lines=None,
+ cutplanes=None,
solution="",
quantity="",
- intrinsics={},
- seeding_faces=[],
- layer_nets=[],
+ intrinsics=None,
+ seeding_faces=None,
+ layer_nets=None,
layer_plot_type="LayerNetsExtFace",
):
self._postprocessor = postprocessor
self.oField = postprocessor.ofieldsreporter
- self.volumes = objects
- self.surfaces = surfaces
- self.lines = lines
- self.cutplanes = cutplanes
- self.layer_nets = layer_nets
+ self.volumes = [] if objects is None else objects
+ self.surfaces = [] if surfaces is None else surfaces
+ self.lines = [] if lines is None else lines
+ self.cutplanes = [] if cutplanes is None else cutplanes
+ self.layer_nets = [] if layer_nets is None else layer_nets
self.layer_plot_type = layer_plot_type
- self.seeding_faces = seeding_faces
+ self.seeding_faces = [] if seeding_faces is None else seeding_faces
self.solution = solution
self.quantity = quantity
- self.intrinsics = intrinsics
+ self.intrinsics = {} if intrinsics is None else intrinsics
self.name = "Field_Plot"
self.plot_folder = "Field_Plot"
self.Filled = False
@@ -2919,21 +3312,11 @@ def intrinsicVar(self):
Returns
-------
list or dict
- List or dictionary of the variables for the field plot.
+ Variables for the field plot.
"""
var = ""
- if isinstance(self.intrinsics, list):
- l = 0
- while l < len(self.intrinsics):
- val = self.intrinsics[l + 1]
- if ":=" in self.intrinsics[l] and isinstance(self.intrinsics[l + 1], list):
- val = self.intrinsics[l + 1][0]
- ll = self.intrinsics[l].split(":=")
- var += ll[0] + "='" + str(val) + "' "
- l += 2
- else:
- for a in self.intrinsics:
- var += a + "='" + str(self.intrinsics[a]) + "' "
+ for a in self.intrinsics:
+ var += a + "='" + str(self.intrinsics[a]) + "' "
return var
@property
@@ -3522,13 +3905,13 @@ def __init__(
max_frequency="1GHz",
ray_density=2,
bounces=5,
- intrinsics={},
+ intrinsics=None,
):
self.is_creeping_wave = is_creeping_wave
self._postprocessor = postprocessor
self._ofield = postprocessor.ofieldsreporter
self.quantity = quantity
- self.intrinsics = intrinsics
+ self.intrinsics = {} if intrinsics is None else intrinsics
self.name = "Field_Plot"
self.plot_folder = "Field_Plot"
self.max_frequency = max_frequency
@@ -3560,22 +3943,12 @@ def intrinsicVar(self):
Returns
-------
- list or dict
- List or dictionary of the variables for the field plot.
+ str
+ Variables for the field plot.
"""
var = ""
- if isinstance(self.intrinsics, list):
- l = 0
- while l < len(self.intrinsics):
- val = self.intrinsics[l + 1]
- if ":=" in self.intrinsics[l] and isinstance(self.intrinsics[l + 1], list):
- val = self.intrinsics[l + 1][0]
- ll = self.intrinsics[l].split(":=")
- var += ll[0] + "='" + str(val) + "' "
- l += 2
- else:
- for a in self.intrinsics:
- var += a + "='" + str(self.intrinsics[a]) + "' "
+ for a in self.intrinsics:
+ var += a + "='" + str(self.intrinsics[a]) + "' "
return var
@pyaedt_function_handler()
diff --git a/pyaedt/q3d.py b/pyaedt/q3d.py
index 633c54e0b0f..7189af0c7e8 100644
--- a/pyaedt/q3d.py
+++ b/pyaedt/q3d.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
"""This module contains these classes: ``Q2d``, ``Q3d``, and ``QExtractor`."""
from __future__ import absolute_import # noreorder
@@ -7,12 +31,12 @@
import re
import warnings
-from pyaedt import is_ironpython
from pyaedt.application.Analysis3D import FieldAnalysis3D
from pyaedt.application.Variables import decompose_variable_value
from pyaedt.generic.constants import MATRIXOPERATIONSQ2D
from pyaedt.generic.constants import MATRIXOPERATIONSQ3D
from pyaedt.generic.general_methods import generate_unique_name
+from pyaedt.generic.general_methods import is_ironpython
from pyaedt.generic.general_methods import pyaedt_function_handler
from pyaedt.generic.settings import settings
from pyaedt.modeler.geometry_operators import GeometryOperators as go
@@ -50,34 +74,36 @@ def design_file(self):
def __init__(
self,
Q3DType,
- projectname=None,
- designname=None,
+ project=None,
+ design=None,
solution_type=None,
setup_name=None,
- specified_version=None,
+ version=None,
non_graphical=False,
- new_desktop_session=False,
+ new_desktop=False,
close_on_exit=False,
student_version=False,
machine="",
port=0,
aedt_process_id=None,
+ remove_lock=False,
):
FieldAnalysis3D.__init__(
self,
Q3DType,
- projectname,
- designname,
+ project,
+ design,
solution_type,
setup_name,
- specified_version,
+ version,
non_graphical,
- new_desktop_session,
+ new_desktop,
close_on_exit,
student_version,
machine,
port,
aedt_process_id,
+ remove_lock=remove_lock,
)
self.matrices = []
for el in list(self.omatrix.ListReduceMatrixes()):
@@ -1204,23 +1230,23 @@ class Q3d(QExtractor, object):
Parameters
----------
- projectname : str, optional
+ project : str, optional
Name of the project to select or the full path to the project
or AEDTZ archive to open. The default is ``None``, in which
case an attempt is made to get an active project. If no
projects are present, an empty project is created.
- designname : str, optional
+ design : str, optional
Name of the design to select. The default is ``None``, in
which case an attempt is made to get an active design. If no
designs are present, an empty design is created.
solution_type : str, optional
Solution type to apply to the design. The default is
``None``, in which case the default type is applied.
- setup_name : str, optional
+ setup : str, optional
Name of the setup to use as the nominal. The default is
``None``, in which case the active setup is used or nothing
is used.
- specified_version : str, int, float, optional
+ version : str, int, float, optional
Version of AEDT to use. The default is ``None``, in which case
the active version or latest installed version is used.
This parameter is ignored when Script is launched within AEDT.
@@ -1229,7 +1255,7 @@ class Q3d(QExtractor, object):
Whether to launch AEDT in non-graphical mode. The default
is ``False``, in which case AEDT is launched in graphical mode.
This parameter is ignored when a script is launched within AEDT.
- new_desktop_session : bool, optional
+ new_desktop : bool, optional
Whether to launch an instance of AEDT in a new thread, even if
another instance of the ``specified_version`` is active on the
machine. The default is ``False``. This parameter is ignored when
@@ -1251,7 +1277,11 @@ class Q3d(QExtractor, object):
running with the command `"ansysedt.exe -grpcsrv portnum"`.
aedt_process_id : int, optional
Process ID for the instance of AEDT to point PyAEDT at. The default is
- ``None``. This parameter is only used when ``new_desktop_session = False``.
+ ``None``. This parameter is only used when ``new_desktop = False``.
+ remove_lock : bool, optional
+ Whether to remove lock to project before opening it or not.
+ The default is ``False``, which means to not unlock
+ the existing project if needed and raise an exception.
Examples
--------
@@ -1263,36 +1293,45 @@ class Q3d(QExtractor, object):
"""
+ @pyaedt_function_handler(
+ designname="design",
+ projectname="project",
+ specified_version="version",
+ setup_name="setup",
+ new_desktop_session="new_desktop",
+ )
def __init__(
self,
- projectname=None,
- designname=None,
+ project=None,
+ design=None,
solution_type=None,
- setup_name=None,
- specified_version=None,
+ setup=None,
+ version=None,
non_graphical=False,
- new_desktop_session=False,
+ new_desktop=False,
close_on_exit=False,
student_version=False,
machine="",
port=0,
aedt_process_id=None,
+ remove_lock=False,
):
QExtractor.__init__(
self,
"Q3D Extractor",
- projectname,
- designname,
+ project,
+ design,
solution_type,
- setup_name,
- specified_version,
+ setup,
+ version,
non_graphical,
- new_desktop_session,
+ new_desktop,
close_on_exit,
student_version,
machine,
port,
aedt_process_id,
+ remove_lock=remove_lock,
)
self.MATRIXOPERATIONS = MATRIXOPERATIONSQ3D()
@@ -2041,23 +2080,23 @@ class Q2d(QExtractor, object):
Parameters
----------
- projectname : str, optional
+ project : str, optional
Name of the project to select or the full path to the project
or AEDTZ archive to open. The default is ``None``, in which
case an attempt is made to get an active project. If no
projects are present, an empty project is created.
- designname : str, optional
+ design : str, optional
Name of the design to select. The default is ``None``, in
which case an attempt is made to get an active design. If no
designs are present, an empty design is created.
solution_type : str, optional
Solution type to apply to the design. The default is
``None``, in which case the default type is applied.
- setup_name : str, optional
+ setup : str, optional
Name of the setup to use as the nominal. The default is
``None``, in which case the active setup is used or
nothing is used.
- specified_version : str, int, float, optional
+ version : str, int, float, optional
Version of AEDT to use. The default is ``None``, in which case
the active version or latest installed version is used. This
parameter is ignored when a script is launched within AEDT.
@@ -2066,7 +2105,7 @@ class Q2d(QExtractor, object):
Whether to launch AEDT in non-graphical mode. The default
is ``False``, in which case AEDT is launched in graphical mode.
This parameter is ignored when a script is launched within AEDT.
- new_desktop_session : bool, optional
+ new_desktop : bool, optional
Whether to launch an instance of AEDT in a new thread, even if
another instance of the ``specified_version`` is active on the
machine. The default is ``False``. This parameter is ignored
@@ -2087,7 +2126,11 @@ class Q2d(QExtractor, object):
The remote server must be up and running with the command `"ansysedt.exe -grpcsrv portnum"`.
aedt_process_id : int, optional
Process ID for the instance of AEDT to point PyAEDT at. The default is
- ``None``. This parameter is only used when ``new_desktop_session = False``.
+ ``None``. This parameter is only used when ``new_desktop = False``.
+ remove_lock : bool, optional
+ Whether to remove lock to project before opening it or not.
+ The default is ``False``, which means to not unlock
+ the existing project if needed and raise an exception.
Examples
--------
@@ -2115,36 +2158,45 @@ def dim(self):
"""Dimension."""
return self.modeler.dimension
+ @pyaedt_function_handler(
+ designname="design",
+ projectname="project",
+ specified_version="version",
+ setup_name="setup",
+ new_desktop_session="new_desktop",
+ )
def __init__(
self,
- projectname=None,
- designname=None,
+ project=None,
+ design=None,
solution_type=None,
- setup_name=None,
- specified_version=None,
+ setup=None,
+ version=None,
non_graphical=False,
- new_desktop_session=False,
+ new_desktop=False,
close_on_exit=False,
student_version=False,
machine="",
port=0,
aedt_process_id=None,
+ remove_lock=False,
):
QExtractor.__init__(
self,
"2D Extractor",
- projectname,
- designname,
+ project,
+ design,
solution_type,
- setup_name,
- specified_version,
+ setup,
+ version,
non_graphical,
- new_desktop_session,
+ new_desktop,
close_on_exit,
student_version,
machine,
port,
aedt_process_id,
+ remove_lock=remove_lock,
)
self.MATRIXOPERATIONS = MATRIXOPERATIONSQ2D()
diff --git a/pyaedt/rmxprt.py b/pyaedt/rmxprt.py
index 3ed62c4855b..3b7582437ef 100644
--- a/pyaedt/rmxprt.py
+++ b/pyaedt/rmxprt.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
"""This module contains these classes: ``RMXprtModule`` and ``Rmxprt``."""
from __future__ import absolute_import # noreorder
@@ -125,12 +149,12 @@ class Rmxprt(FieldAnalysisRMxprt):
Parameters
----------
- projectname : str, optional
+ project : str, optional
Name of the project to select or the full path to the project
or AEDTZ archive to open. The default is ``None``, in which
case an attempt is made to get an active project. If no
projects are present, an empty project is created.
- designname : str, optional
+ design : str, optional
Name of the design to select. The default is ``None``, in
which case an attempt is made to get an active design. If no
designs are present, an empty design is created.
@@ -139,11 +163,11 @@ class Rmxprt(FieldAnalysisRMxprt):
``None``, in which case the default type is applied.
model_units : str, optional
Model units.
- setup_name : str, optional
+ setup : str, optional
Name of the setup to use as the nominal. The default is
``None``, in which case the active setup is used or
nothing is used.
- specified_version : str, int, float, optional
+ version : str, int, float, optional
Version of AEDT to use. The default is ``None``, in which case
the active setup is used or the latest installed version is
used.
@@ -152,7 +176,7 @@ class Rmxprt(FieldAnalysisRMxprt):
Whether to launch AEDT in non-graphical mode. The default
is ``False``, in which case AEDT is launched in graphical mode.
This parameter is ignored when a script is launched within AEDT.
- new_desktop_session : bool, optional
+ new_desktop : bool, optional
Whether to launch an instance of AEDT in a new thread, even if
another instance of the ``specified_version`` is active on the
machine. The default is ``False``.
@@ -171,7 +195,11 @@ class Rmxprt(FieldAnalysisRMxprt):
The remote server must be up and running with the command `"ansysedt.exe -grpcsrv portnum"`.
aedt_process_id : int, optional
Process ID for the instance of AEDT to point PyAEDT at. The default is
- ``None``. This parameter is only used when ``new_desktop_session = False``.
+ ``None``. This parameter is only used when ``new_desktop = False``.
+ remove_lock : bool, optional
+ Whether to remove lock to project before opening it or not.
+ The default is ``False``, which means to not unlock
+ the existing project if needed and raise an exception.
Examples
--------
@@ -198,37 +226,46 @@ class Rmxprt(FieldAnalysisRMxprt):
>>> app = Rmxprt("myfile.aedt")
"""
+ @pyaedt_function_handler(
+ designname="design",
+ projectname="project",
+ specified_version="version",
+ setup_name="setup",
+ new_desktop_session="new_desktop",
+ )
def __init__(
self,
- projectname=None,
- designname=None,
+ project=None,
+ design=None,
solution_type=None,
model_units=None,
- setup_name=None,
- specified_version=None,
+ setup=None,
+ version=None,
non_graphical=False,
- new_desktop_session=False,
+ new_desktop=False,
close_on_exit=False,
student_version=False,
machine="",
port=0,
aedt_process_id=None,
+ remove_lock=False,
):
FieldAnalysisRMxprt.__init__(
self,
"RMxprtSolution",
- projectname,
- designname,
+ project,
+ design,
solution_type,
- setup_name,
- specified_version,
+ setup,
+ version,
non_graphical,
- new_desktop_session,
+ new_desktop,
close_on_exit,
student_version,
machine,
port,
aedt_process_id,
+ remove_lock=remove_lock,
)
if not model_units or model_units == "mm":
model_units = "mm"
diff --git a/pyaedt/rpc/rpyc_services.py b/pyaedt/rpc/rpyc_services.py
index 015fc8c6154..8ce026642bd 100644
--- a/pyaedt/rpc/rpyc_services.py
+++ b/pyaedt/rpc/rpyc_services.py
@@ -11,14 +11,15 @@
from pyaedt import generate_unique_name
from pyaedt.generic.general_methods import env_path
-from pyaedt import is_ironpython
-from pyaedt import is_linux
+from pyaedt.generic.general_methods import is_ironpython
+from pyaedt.generic.settings import is_linux
from pyaedt import is_windows
+from pyaedt.misc.misc import is_safe_path
if is_linux and is_ironpython:
- import subprocessdotnet as subprocess
+ import subprocessdotnet as subprocess # nosec
else:
- import subprocess
+ import subprocess # nosec
if not is_ironpython:
import rpyc
@@ -270,24 +271,37 @@ def exposed_run_script(self, script, aedt_version="2021.2", ansysem_path=None, n
elif os.path.exists(script):
script_file = script
else:
- return "File wrong or wrong commands."
+ return "Wrong file or wrong commands."
+ if not is_safe_path(script_file):
+ return "Script file {} not safe.".format(script_file)
executable = "ansysedt.exe"
if is_linux and not ansysem_path and not env_path(aedt_version):
ansysem_path = os.getenv("PYAEDT_SERVER_AEDT_PATH", "")
if env_path(aedt_version) or ansysem_path:
if not ansysem_path:
ansysem_path = env_path(aedt_version)
-
- ng_feature = " -features=SF159726_SCRIPTOBJECT"
+ exe_path = os.path.join(ansysem_path, executable)
+ if not is_safe_path(exe_path):
+ return "Ansys EM path not safe."
+ command = [exe_path]
+ if non_graphical:
+ command.append("-ng")
+ ng_feature = "-features=SF159726_SCRIPTOBJECT"
if self._beta_options:
for opt in range(self._beta_options.__len__()):
if self._beta_options[opt] not in ng_feature:
ng_feature += "," + self._beta_options[opt]
if non_graphical:
- ng_feature += ",SF6694_NON_GRAPHICAL_COMMAND_EXECUTION -ng"
- command = os.path.join(ansysem_path, executable) + ng_feature + " -RunScriptAndExit " + script_file
- p = subprocess.Popen(command)
- p.wait()
+ ng_feature += ",SF6694_NON_GRAPHICAL_COMMAND_EXECUTION"
+ command.append(ng_feature)
+ command = [exe_path, ng_feature, "-RunScriptAndExit", script_file]
+ try:
+ p = subprocess.Popen(command) # nosec
+ p.wait()
+ except subprocess.CalledProcessError as e:
+ msg = "Command failed with error: {}".format(e)
+ logger.error(msg)
+ return msg
return "Script Executed."
else:
@@ -336,34 +350,34 @@ def exposed_edb(
def exposed_hfss(
self,
- projectname=None,
- designname=None,
+ project=None,
+ design=None,
solution_type=None,
- setup_name=None,
- specified_version=None,
+ setup=None,
+ version=None,
non_graphical=True,
):
"""Starts a new Hfss session.
Parameters
----------
- projectname : str, optional
+ project : str, optional
Name of the project to select or the full path to the project
or AEDTZ archive to open. The default is ``None``, in which
case an attempt is made to get an active project. If no
projects are present, an empty project is created.
- designname : str, optional
+ design : str, optional
Name of the design to select. The default is ``None``, in
which case an attempt is made to get an active design. If no
designs are present, an empty design is created.
solution_type : str, optional
Solution type to apply to the design. The default is
``None``, in which case the default type is applied.
- setup_name : str, optional
+ setup : str, optional
Name of the setup to use as the nominal. The default is
``None``, in which case the active setup is used or
nothing is used.
- specified_version : str, int, float, optional
+ version : str, int, float, optional
Version of AEDT to use. The default is ``None``, in which case
the active version or latest installed version is used.
non_graphical : bool, optional
@@ -376,13 +390,13 @@ def exposed_hfss(
"""
self._beta()
aedtapp = Hfss(
- projectname=projectname,
- designname=designname,
+ project=project,
+ design=design,
solution_type=solution_type,
- setup_name=setup_name,
- specified_version=specified_version,
+ setup=setup,
+ version=version,
non_graphical=non_graphical,
- new_desktop_session=True,
+ new_desktop=True,
close_on_exit=True,
student_version=False,
)
@@ -391,34 +405,34 @@ def exposed_hfss(
def exposed_hfss3dlayout(
self,
- projectname=None,
- designname=None,
+ project=None,
+ design=None,
solution_type=None,
- setup_name=None,
- specified_version=None,
+ setup=None,
+ version=None,
non_graphical=True,
):
"""Starts a new Hfss3dLayout session.
Parameters
----------
- projectname : str, optional
+ project : str, optional
Name of the project to select or the full path to the project
or AEDTZ archive to open. The default is ``None``, in which
case an attempt is made to get an active project. If no
projects are present, an empty project is created.
- designname : str, optional
+ design : str, optional
Name of the design to select. The default is ``None``, in
which case an attempt is made to get an active design. If no
designs are present, an empty design is created.
solution_type : str, optional
Solution type to apply to the design. The default is
``None``, in which case the default type is applied.
- setup_name : str, optional
+ setup : str, optional
Name of the setup to use as the nominal. The default is
``None``, in which case the active setup is used or
nothing is used.
- specified_version : str, int, float, optional
+ version : str, int, float, optional
Version of AEDT to use. The default is ``None``, in which case
the active version or latest installed version is used.
non_graphical : bool, optional
@@ -431,13 +445,13 @@ def exposed_hfss3dlayout(
"""
self._beta()
aedtapp = Hfss3dLayout(
- projectname=projectname,
- designname=designname,
+ project=project,
+ design=design,
solution_type=solution_type,
- setup_name=setup_name,
- specified_version=specified_version,
+ setup=setup,
+ version=version,
non_graphical=non_graphical,
- new_desktop_session=True,
+ new_desktop=True,
close_on_exit=True,
student_version=False,
)
@@ -446,34 +460,34 @@ def exposed_hfss3dlayout(
def exposed_maxwell3d(
self,
- projectname=None,
- designname=None,
+ project=None,
+ design=None,
solution_type=None,
- setup_name=None,
- specified_version=None,
+ setup=None,
+ version=None,
non_graphical=True,
):
"""Starts a new Maxwell3d session.
Parameters
----------
- projectname : str, optional
+ project : str, optional
Name of the project to select or the full path to the project
or AEDTZ archive to open. The default is ``None``, in which
case an attempt is made to get an active project. If no
projects are present, an empty project is created.
- designname : str, optional
+ design : str, optional
Name of the design to select. The default is ``None``, in
which case an attempt is made to get an active design. If no
designs are present, an empty design is created.
solution_type : str, optional
Solution type to apply to the design. The default is
``None``, in which case the default type is applied.
- setup_name : str, optional
+ setup : str, optional
Name of the setup to use as the nominal. The default is
``None``, in which case the active setup is used or
nothing is used.
- specified_version : str, int, float, optional
+ version : str, int, float, optional
Version of AEDT to use. The default is ``None``, in which case
the active version or latest installed version is used.
non_graphical : bool, optional
@@ -486,13 +500,13 @@ def exposed_maxwell3d(
"""
self._beta()
aedtapp = Maxwell3d(
- projectname=projectname,
- designname=designname,
+ project=project,
+ design=design,
solution_type=solution_type,
- setup_name=setup_name,
- specified_version=specified_version,
+ setup=setup,
+ version=version,
non_graphical=non_graphical,
- new_desktop_session=True,
+ new_desktop=True,
close_on_exit=True,
student_version=False,
)
@@ -501,34 +515,34 @@ def exposed_maxwell3d(
def exposed_maxwell2d(
self,
- projectname=None,
- designname=None,
+ project=None,
+ design=None,
solution_type=None,
- setup_name=None,
- specified_version=None,
+ setup=None,
+ version=None,
non_graphical=True,
):
"""Starts a new Maxwell32 session.
Parameters
----------
- projectname : str, optional
+ project : str, optional
Name of the project to select or the full path to the project
or AEDTZ archive to open. The default is ``None``, in which
case an attempt is made to get an active project. If no
projects are present, an empty project is created.
- designname : str, optional
+ design : str, optional
Name of the design to select. The default is ``None``, in
which case an attempt is made to get an active design. If no
designs are present, an empty design is created.
solution_type : str, optional
Solution type to apply to the design. The default is
``None``, in which case the default type is applied.
- setup_name : str, optional
+ setup : str, optional
Name of the setup to use as the nominal. The default is
``None``, in which case the active setup is used or
nothing is used.
- specified_version : str, int, float, optional
+ version : str, int, float, optional
Version of AEDT to use. The default is ``None``, in which case
the active version or latest installed version is used.
non_graphical : bool, optional
@@ -541,13 +555,13 @@ def exposed_maxwell2d(
"""
self._beta()
aedtapp = Maxwell2d(
- projectname=projectname,
- designname=designname,
+ project=project,
+ design=design,
solution_type=solution_type,
- setup_name=setup_name,
- specified_version=specified_version,
+ setup=setup,
+ version=version,
non_graphical=non_graphical,
- new_desktop_session=True,
+ new_desktop=True,
close_on_exit=True,
student_version=False,
)
@@ -556,34 +570,34 @@ def exposed_maxwell2d(
def exposed_icepak(
self,
- projectname=None,
- designname=None,
+ project=None,
+ design=None,
solution_type=None,
- setup_name=None,
- specified_version=None,
+ setup=None,
+ version=None,
non_graphical=True,
):
"""Starts a new Icepak session.
Parameters
----------
- projectname : str, optional
+ project : str, optional
Name of the project to select or the full path to the project
or AEDTZ archive to open. The default is ``None``, in which
case an attempt is made to get an active project. If no
projects are present, an empty project is created.
- designname : str, optional
+ design : str, optional
Name of the design to select. The default is ``None``, in
which case an attempt is made to get an active design. If no
designs are present, an empty design is created.
solution_type : str, optional
Solution type to apply to the design. The default is
``None``, in which case the default type is applied.
- setup_name : str, optional
+ setup : str, optional
Name of the setup to use as the nominal. The default is
``None``, in which case the active setup is used or
nothing is used.
- specified_version : str, int, float, optional
+ version : str, int, float, optional
Version of AEDT to use. The default is ``None``, in which case
the active version or latest installed version is used.
non_graphical : bool, optional
@@ -596,13 +610,13 @@ def exposed_icepak(
"""
self._beta()
aedtapp = Icepak(
- projectname=projectname,
- designname=designname,
+ project=project,
+ design=design,
solution_type=solution_type,
- setup_name=setup_name,
- specified_version=specified_version,
+ setup=setup,
+ version=version,
non_graphical=non_graphical,
- new_desktop_session=True,
+ new_desktop=True,
close_on_exit=True,
student_version=False,
)
@@ -611,34 +625,34 @@ def exposed_icepak(
def exposed_circuit(
self,
- projectname=None,
- designname=None,
+ project=None,
+ design=None,
solution_type=None,
- setup_name=None,
- specified_version=None,
+ setup=None,
+ version=None,
non_graphical=True,
):
"""Starts a new Circuit session.
Parameters
----------
- projectname : str, optional
+ project : str, optional
Name of the project to select or the full path to the project
or AEDTZ archive to open. The default is ``None``, in which
case an attempt is made to get an active project. If no
projects are present, an empty project is created.
- designname : str, optional
+ design : str, optional
Name of the design to select. The default is ``None``, in
which case an attempt is made to get an active design. If no
designs are present, an empty design is created.
solution_type : str, optional
Solution type to apply to the design. The default is
``None``, in which case the default type is applied.
- setup_name : str, optional
+ setup : str, optional
Name of the setup to use as the nominal. The default is
``None``, in which case the active setup is used or
nothing is used.
- specified_version : str, int, float, optional
+ version : str, int, float, optional
Version of AEDT to use. The default is ``None``, in which case
the active version or latest installed version is used.
non_graphical : bool, optional
@@ -651,13 +665,13 @@ def exposed_circuit(
"""
self._beta()
aedtapp = Circuit(
- projectname=projectname,
- designname=designname,
+ project=project,
+ design=design,
solution_type=solution_type,
- setup_name=setup_name,
- specified_version=specified_version,
+ setup=setup,
+ version=version,
non_graphical=non_graphical,
- new_desktop_session=True,
+ new_desktop=True,
close_on_exit=True,
student_version=False,
)
@@ -666,34 +680,34 @@ def exposed_circuit(
def exposed_mechanical(
self,
- projectname=None,
- designname=None,
+ project=None,
+ design=None,
solution_type=None,
- setup_name=None,
- specified_version=None,
+ setup=None,
+ version=None,
non_graphical=True,
):
"""Starts a new Mechanical session.
Parameters
----------
- projectname : str, optional
+ project : str, optional
Name of the project to select or the full path to the project
or AEDTZ archive to open. The default is ``None``, in which
case an attempt is made to get an active project. If no
projects are present, an empty project is created.
- designname : str, optional
+ design : str, optional
Name of the design to select. The default is ``None``, in
which case an attempt is made to get an active design. If no
designs are present, an empty design is created.
solution_type : str, optional
Solution type to apply to the design. The default is
``None``, in which case the default type is applied.
- setup_name : str, optional
+ setup : str, optional
Name of the setup to use as the nominal. The default is
``None``, in which case the active setup is used or
nothing is used.
- specified_version : str, int, float, optional
+ version : str, int, float, optional
Version of AEDT to use. The default is ``None``, in which case
the active version or latest installed version is used.
non_graphical : bool, optional
@@ -706,13 +720,13 @@ def exposed_mechanical(
"""
self._beta()
aedtapp = Mechanical(
- projectname=projectname,
- designname=designname,
+ project=project,
+ design=design,
solution_type=solution_type,
- setup_name=setup_name,
- specified_version=specified_version,
+ setup=setup,
+ version=version,
non_graphical=non_graphical,
- new_desktop_session=True,
+ new_desktop=True,
close_on_exit=True,
student_version=False,
)
@@ -721,34 +735,34 @@ def exposed_mechanical(
def exposed_q3d(
self,
- projectname=None,
- designname=None,
+ project=None,
+ design=None,
solution_type=None,
- setup_name=None,
- specified_version=None,
+ setup=None,
+ version=None,
non_graphical=True,
):
"""Starts a new Q3d session.
Parameters
----------
- projectname : str, optional
+ project : str, optional
Name of the project to select or the full path to the project
or AEDTZ archive to open. The default is ``None``, in which
case an attempt is made to get an active project. If no
projects are present, an empty project is created.
- designname : str, optional
+ design : str, optional
Name of the design to select. The default is ``None``, in
which case an attempt is made to get an active design. If no
designs are present, an empty design is created.
solution_type : str, optional
Solution type to apply to the design. The default is
``None``, in which case the default type is applied.
- setup_name : str, optional
+ setup : str, optional
Name of the setup to use as the nominal. The default is
``None``, in which case the active setup is used or
nothing is used.
- specified_version : str, int, float, optional
+ version : str, int, float, optional
Version of AEDT to use. The default is ``None``, in which case
the active version or latest installed version is used.
non_graphical : bool, optional
@@ -761,13 +775,13 @@ def exposed_q3d(
"""
self._beta()
aedtapp = Q3d(
- projectname=projectname,
- designname=designname,
+ project=project,
+ design=design,
solution_type=solution_type,
- setup_name=setup_name,
- specified_version=specified_version,
+ setup=setup,
+ version=version,
non_graphical=non_graphical,
- new_desktop_session=True,
+ new_desktop=True,
close_on_exit=True,
student_version=False,
)
@@ -776,34 +790,34 @@ def exposed_q3d(
def exposed_q2d(
self,
- projectname=None,
- designname=None,
+ project=None,
+ design=None,
solution_type=None,
- setup_name=None,
- specified_version=None,
+ setup=None,
+ version=None,
non_graphical=True,
):
"""Starts a new Q2d session.
Parameters
----------
- projectname : str, optional
+ project : str, optional
Name of the project to select or the full path to the project
or AEDTZ archive to open. The default is ``None``, in which
case an attempt is made to get an active project. If no
projects are present, an empty project is created.
- designname : str, optional
+ design : str, optional
Name of the design to select. The default is ``None``, in
which case an attempt is made to get an active design. If no
designs are present, an empty design is created.
solution_type : str, optional
Solution type to apply to the design. The default is
``None``, in which case the default type is applied.
- setup_name : str, optional
+ setup : str, optional
Name of the setup to use as the nominal. The default is
``None``, in which case the active setup is used or
nothing is used.
- specified_version : str, int, float, optional
+ version : str, int, float, optional
Version of AEDT to use. The default is ``None``, in which case
the active version or latest installed version is used.
non_graphical : bool, optional
@@ -816,13 +830,13 @@ def exposed_q2d(
"""
self._beta()
aedtapp = Q2d(
- projectname=projectname,
- designname=designname,
+ project=project,
+ design=design,
solution_type=solution_type,
- setup_name=setup_name,
- specified_version=specified_version,
+ setup=setup,
+ version=version,
non_graphical=non_graphical,
- new_desktop_session=True,
+ new_desktop=True,
close_on_exit=True,
student_version=False,
)
@@ -871,7 +885,13 @@ def aedt_grpc(port=None, beta_options=None, use_aedt_relative_path=False, non_gr
from pyaedt.generic.general_methods import grpc_active_sessions
sessions = grpc_active_sessions()
if not port:
- port = check_port(random.randint(18500, 20000))
+ # TODO: Remove once IronPython is deprecated
+ if is_ironpython:
+ port = check_port(random.randint(18500, 20000)) # nosec
+ else:
+ import secrets
+ secure_random = secrets.SystemRandom()
+ port = check_port(secure_random.randint(18500, 20000))
if port == 0:
print("Error. No ports are available.")
@@ -1097,7 +1117,7 @@ def on_disconnect(self, connection):
try:
edb.close_edb()
except Exception:
- pass
+ logger.warning("Error when trying to close EDB.")
def start_service(self, port):
"""Connect to remove service manager and run a new server on specified port.
@@ -1157,5 +1177,11 @@ def exposed_stop_service(self, port):
@staticmethod
def exposed_check_port():
- port_number = random.randint(18500, 20000)
- return check_port(port_number)
+ # TODO: Remove once IronPython is deprecated
+ if is_ironpython: # nosec
+ port = check_port(random.randint(18500, 20000)) # nosec
+ else:
+ import secrets
+ secure_random = secrets.SystemRandom()
+ port = check_port(secure_random.randint(18500, 20000))
+ return port
diff --git a/pyaedt/sbrplus/__init__.py b/pyaedt/sbrplus/__init__.py
index e69de29bb2d..9c4476773da 100644
--- a/pyaedt/sbrplus/__init__.py
+++ b/pyaedt/sbrplus/__init__.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
diff --git a/pyaedt/sbrplus/hdm_parser.py b/pyaedt/sbrplus/hdm_parser.py
index 444ea9b7054..5fe3bec0cc9 100644
--- a/pyaedt/sbrplus/hdm_parser.py
+++ b/pyaedt/sbrplus/hdm_parser.py
@@ -1,3 +1,28 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+import ast
import struct
import warnings
@@ -14,6 +39,8 @@
"Install with \n\npip install numpy\n\nRequires CPython."
)
+from pyaedt.aedt_logger import pyaedt_logger
+
class Parser:
"""
@@ -37,7 +64,13 @@ def __init__(self, filename):
header, binarycontent = binarycontent.split(b"#header end\n")
header = header.decode().splitlines()[1:]
header = [line for line in header if not line.startswith("#")]
- self.header = eval(" ".join(header))
+ header = "".join(header)
+ try:
+ self.header = ast.literal_eval(header)
+ except (ValueError, SyntaxError) as e:
+ pyaedt_logger.error("Header of file '{}' is not a valid dictionary.".format(filename))
+ raise e
+
self._read_header()
self.binarycontent = binarycontent
@@ -90,7 +123,8 @@ def _parse_list(self, type=None, base=None, size=1):
and converted to a NumPy array. A list is converted to a Python list. Only simple base types can be
interpreted as a NumPy array.
"""
- assert base != None
+ if base is None: # pragma: no cover
+ pyaedt_logger.warning("Invalid input provided when parsing for vector or list.")
res = []
bt = self.parser_types[base]
@@ -107,7 +141,7 @@ def _parse_list(self, type=None, base=None, size=1):
if type == "vector":
res = np.array(res)
else:
- res = [self._parse(base) for iel in range(size)]
+ res = [self._parse(base) for _ in range(size)]
if len(res) == 1:
return res[0]
diff --git a/pyaedt/sbrplus/hdm_utils.py b/pyaedt/sbrplus/hdm_utils.py
index 2a2934486af..3de0ba527c5 100644
--- a/pyaedt/sbrplus/hdm_utils.py
+++ b/pyaedt/sbrplus/hdm_utils.py
@@ -1,3 +1,28 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+
def sort_bundle(bundle, monoPW_attrib="sweep_angle_index"):
"""
In-place sorting utility for hdm ray exports.
diff --git a/pyaedt/sbrplus/plot.py b/pyaedt/sbrplus/plot.py
index 9fae5a4b4c3..87675122497 100644
--- a/pyaedt/sbrplus/plot.py
+++ b/pyaedt/sbrplus/plot.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
from collections import defaultdict
import math
import os
@@ -6,8 +30,8 @@
import numpy as np
import pyvista as pv
-from pyaedt import pyaedt_function_handler
from pyaedt.generic.constants import AEDT_UNITS
+from pyaedt.generic.general_methods import pyaedt_function_handler
from pyaedt.generic.plot import CommonPlotter
from pyaedt.generic.plot import ObjClass
diff --git a/pyaedt/twinbuilder.py b/pyaedt/twinbuilder.py
index 2593b9c6780..251a47e6efd 100644
--- a/pyaedt/twinbuilder.py
+++ b/pyaedt/twinbuilder.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
"""This module contains the ``TwinBuilder`` class."""
from __future__ import absolute_import # noreorder
@@ -19,23 +43,23 @@ class TwinBuilder(AnalysisTwinBuilder, object):
Parameters
----------
- projectname : str, optional
+ project : str, optional
Name of the project to select or the full path to the project
or AEDTZ archive to open. The default is ``None``, in which
case an attempt is made to get an active project. If no
projects are present, an empty project is created.
- designname : str, optional
+ design : str, optional
Name of the design to select. The default is ``None``, in
which case an attempt is made to get an active design. If no
designs are present, an empty design is created.
solution_type : str, optional
Solution type to apply to the design. The default is
``None``, in which case the default type is applied.
- setup_name : str, optional
+ setup : str, optional
Name of the setup to use as the nominal. The default is
``None``, in which case the active setup is used or
nothing is used.
- specified_version : str, int, float, optional
+ version : str, int, float, optional
Version of AEDT to use. The default is ``None``, in which
case the active setup or latest installed version is
used.
@@ -44,7 +68,7 @@ class TwinBuilder(AnalysisTwinBuilder, object):
Whether to launch AEDT in non-graphical mode. The default
is ``False``, in which case AEDT is launched in graphical mode.
This parameter is ignored when a script is launched within AEDT.
- new_desktop_session : bool, optional
+ new_desktop : bool, optional
Whether to launch an instance of AEDT in a new thread, even if
another instance of the ``specified_version`` is active on the
machine. The default is ``False``.
@@ -63,7 +87,11 @@ class TwinBuilder(AnalysisTwinBuilder, object):
The remote server must be up and running with command `"ansysedt.exe -grpcsrv portnum"`.
aedt_process_id : int, optional
Process ID for the instance of AEDT to point PyAEDT at. The default is
- ``None``. This parameter is only used when ``new_desktop_session = False``.
+ ``None``. This parameter is only used when ``new_desktop = False``.
+ remove_lock : bool, optional
+ Whether to remove lock to project before opening it or not.
+ The default is ``False``, which means to not unlock
+ the existing project if needed and raise an exception.
Examples
--------
@@ -91,37 +119,46 @@ class TwinBuilder(AnalysisTwinBuilder, object):
>>> app = TwinBuilder("myfile.aedt")
"""
+ @pyaedt_function_handler(
+ designname="design",
+ projectname="project",
+ specified_version="version",
+ setup_name="setup",
+ new_desktop_session="new_desktop",
+ )
def __init__(
self,
- projectname=None,
- designname=None,
+ project=None,
+ design=None,
solution_type=None,
- setup_name=None,
- specified_version=None,
+ setup=None,
+ version=None,
non_graphical=False,
- new_desktop_session=False,
+ new_desktop=False,
close_on_exit=False,
student_version=False,
machine="",
port=0,
aedt_process_id=None,
+ remove_lock=False,
):
"""Constructor."""
AnalysisTwinBuilder.__init__(
self,
"Twin Builder",
- projectname,
- designname,
+ project,
+ design,
solution_type,
- setup_name,
- specified_version,
+ setup,
+ version,
non_graphical,
- new_desktop_session,
+ new_desktop,
close_on_exit,
student_version,
machine,
port,
aedt_process_id,
+ remove_lock=remove_lock,
)
def _init_from_design(self, *args, **kwargs):
@@ -571,7 +608,7 @@ def add_q3d_dynamic_component(
component = self.modeler.schematic.create_component(component_library="", component_name=component_name)
if component:
if is_loaded:
- app.close_project(save_project=False)
+ app.close_project(save=False)
return component
else: # pragma: no cover
raise ValueError("Error in creating the component.")
diff --git a/pyaedt/workflows/__init__.py b/pyaedt/workflows/__init__.py
index 3bc3c8e5b19..f10103137e9 100644
--- a/pyaedt/workflows/__init__.py
+++ b/pyaedt/workflows/__init__.py
@@ -1,6 +1,7 @@
-# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates.
-# SPDX-License-Identifier: MIT
+# -*- coding: utf-8 -*-
#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
diff --git a/pyaedt/workflows/circuit/__init__.py b/pyaedt/workflows/circuit/__init__.py
index 3bc3c8e5b19..f10103137e9 100644
--- a/pyaedt/workflows/circuit/__init__.py
+++ b/pyaedt/workflows/circuit/__init__.py
@@ -1,6 +1,7 @@
-# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates.
-# SPDX-License-Identifier: MIT
+# -*- coding: utf-8 -*-
#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
diff --git a/pyaedt/workflows/customize_automation_tab.py b/pyaedt/workflows/customize_automation_tab.py
index c3309d2ae98..9cc9f384d3d 100644
--- a/pyaedt/workflows/customize_automation_tab.py
+++ b/pyaedt/workflows/customize_automation_tab.py
@@ -1,6 +1,7 @@
-# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates.
-# SPDX-License-Identifier: MIT
+# -*- coding: utf-8 -*-
#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
@@ -36,8 +37,8 @@
from defusedxml.ElementTree import ParseError
from defusedxml.minidom import parseString
-from pyaedt import is_linux
from pyaedt.generic.general_methods import read_toml
+from pyaedt.generic.settings import is_linux
import pyaedt.workflows
import pyaedt.workflows.templates
diff --git a/pyaedt/workflows/emit/__init__.py b/pyaedt/workflows/emit/__init__.py
index 3bc3c8e5b19..f10103137e9 100644
--- a/pyaedt/workflows/emit/__init__.py
+++ b/pyaedt/workflows/emit/__init__.py
@@ -1,6 +1,7 @@
-# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates.
-# SPDX-License-Identifier: MIT
+# -*- coding: utf-8 -*-
#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
diff --git a/pyaedt/workflows/hfss/__init__.py b/pyaedt/workflows/hfss/__init__.py
index 3bc3c8e5b19..f10103137e9 100644
--- a/pyaedt/workflows/hfss/__init__.py
+++ b/pyaedt/workflows/hfss/__init__.py
@@ -1,6 +1,7 @@
-# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates.
-# SPDX-License-Identifier: MIT
+# -*- coding: utf-8 -*-
#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
diff --git a/pyaedt/workflows/hfss/push_excitation_from_file.py b/pyaedt/workflows/hfss/push_excitation_from_file.py
index 3dbe6147de8..ebef439fad4 100644
--- a/pyaedt/workflows/hfss/push_excitation_from_file.py
+++ b/pyaedt/workflows/hfss/push_excitation_from_file.py
@@ -1,6 +1,7 @@
-# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates.
-# SPDX-License-Identifier: MIT
+# -*- coding: utf-8 -*-
#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
@@ -52,8 +53,8 @@ def frontend(): # pragma: no cover
# Get ports
app = pyaedt.Desktop(
- new_desktop_session=False,
- specified_version=version,
+ new_desktop=False,
+ version=version,
port=port,
aedt_process_id=aedt_process_id,
student_version=is_student,
@@ -153,8 +154,8 @@ def main(extension_args):
file_path = extension_args["file_path"]
app = pyaedt.Desktop(
- new_desktop_session=False,
- specified_version=version,
+ new_desktop=False,
+ version=version,
port=port,
aedt_process_id=aedt_process_id,
student_version=is_student,
@@ -171,11 +172,7 @@ def main(extension_args):
if not os.path.isfile(file_path): # pragma: no cover
app.logger.error("File does not exist.")
elif choice:
- hfss.edit_source_from_file(
- choice,
- file_path,
- is_time_domain=True,
- )
+ hfss.edit_source_from_file(choice, file_path, is_time_domain=True)
app.logger.info("Excitation assigned correctly.")
else:
app.logger.error("Failed to select a port.")
diff --git a/pyaedt/workflows/hfss3dlayout/__init__.py b/pyaedt/workflows/hfss3dlayout/__init__.py
index 3bc3c8e5b19..f10103137e9 100644
--- a/pyaedt/workflows/hfss3dlayout/__init__.py
+++ b/pyaedt/workflows/hfss3dlayout/__init__.py
@@ -1,6 +1,7 @@
-# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates.
-# SPDX-License-Identifier: MIT
+# -*- coding: utf-8 -*-
#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
diff --git a/pyaedt/workflows/hfss3dlayout/cutout.py b/pyaedt/workflows/hfss3dlayout/cutout.py
new file mode 100644
index 00000000000..217e1451f78
--- /dev/null
+++ b/pyaedt/workflows/hfss3dlayout/cutout.py
@@ -0,0 +1,251 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+import os
+
+from pyedb import Edb
+
+import pyaedt
+from pyaedt import Hfss3dLayout
+from pyaedt import generate_unique_name
+import pyaedt.workflows.hfss3dlayout
+from pyaedt.workflows.misc import get_aedt_version
+from pyaedt.workflows.misc import get_arguments
+from pyaedt.workflows.misc import get_port
+from pyaedt.workflows.misc import get_process_id
+from pyaedt.workflows.misc import is_student
+
+port = get_port()
+version = get_aedt_version()
+aedt_process_id = get_process_id()
+is_student = is_student()
+
+# Extension batch arguments
+extension_arguments = {
+ "choice": "ConvexHull",
+ "signals": [],
+ "reference": [],
+ "expansion_factor": 3,
+ "fix_disjoints": True,
+}
+extension_description = "Layout Cutout"
+
+
+def frontend(): # pragma: no cover
+ app = pyaedt.Desktop(
+ new_desktop=False,
+ version=version,
+ port=port,
+ aedt_process_id=aedt_process_id,
+ student_version=is_student,
+ )
+ h3d = Hfss3dLayout()
+ objs_net = {}
+ for net in h3d.oeditor.GetNets():
+ objs_net[net] = h3d.modeler.objects_by_net(net)
+ import tkinter
+ from tkinter import ttk
+
+ import PIL.Image
+ import PIL.ImageTk
+
+ master = tkinter.Tk()
+
+ master.geometry("700x450")
+
+ master.title("Advanced Cutout")
+
+ # Load the logo for the main window
+ icon_path = os.path.join(os.path.dirname(pyaedt.workflows.__file__), "images", "large", "logo.png")
+ im = PIL.Image.open(icon_path)
+ photo = PIL.ImageTk.PhotoImage(im)
+
+ # Set the icon for the main window
+ master.iconphoto(True, photo)
+
+ # Configure style for ttk buttons
+ style = ttk.Style()
+ style.configure("Toolbutton.TButton", padding=6, font=("Helvetica", 10))
+
+ var = tkinter.StringVar()
+ label = tkinter.Label(master, textvariable=var)
+ var.set("Cutout Type:")
+ label.grid(row=0, column=0, pady=10)
+ combo = ttk.Combobox(master, width=40) # Set the width of the combobox
+ combo["values"] = ("ConvexHull", "Bounding", "Conforming")
+ combo.current(0)
+ combo.grid(row=0, column=1, pady=10)
+
+ combo.focus_set()
+ master.signal_ui = [i for i in h3d.modeler.signal_nets.keys()]
+ master.reference_ui = [i for i in h3d.modeler.power_nets.keys()]
+
+ def get_selection():
+ sels = h3d.oeditor.GetSelections()
+ selection = []
+ for sel in sels:
+ for net, net_list in objs_net.items():
+ if sel in net_list:
+ selection.append(net)
+ break
+ return selection
+
+ def apply_signal():
+ selection = get_selection()
+ master.signal_ui = list(set(selection))
+ if selection:
+ var2.set("OK")
+ else:
+ var2.set("Empty selection. Select nets from layout and retry.")
+
+ def apply_reference():
+ selection = get_selection()
+ master.reference_ui = list(set(selection))
+ if selection:
+ var3.set("OK")
+ else:
+ var3.set("Empty selection. Select nets from layout and retry.")
+
+ var2 = tkinter.StringVar()
+ label2 = tkinter.Label(master, textvariable=var2, relief=tkinter.RAISED)
+ var2.set("Select")
+ label2.grid(row=1, column=2, pady=10)
+ b_sig = tkinter.Button(master, text="Select signal nets in layout and Apply", width=40, command=apply_signal)
+ b_sig.grid(row=1, column=1, pady=10)
+ var3 = tkinter.StringVar()
+ label3 = tkinter.Label(master, textvariable=var3, relief=tkinter.RAISED)
+ var3.set("Select")
+ label3.grid(row=2, column=2, pady=10)
+ b_ref = tkinter.Button(master, text="Apply Reference Nets", width=40, command=apply_reference)
+ b_ref.grid(row=2, column=1, pady=10)
+
+ var_exp = tkinter.StringVar()
+ label_exp = tkinter.Label(master, textvariable=var_exp)
+ var_exp.set("Expansion factor(mm):")
+ label_exp.grid(row=3, column=0, pady=10)
+ expansion = tkinter.Text(master, width=20, height=1)
+ expansion.insert(tkinter.END, "3")
+ expansion.grid(row=3, column=1, pady=10, padx=5)
+ var_disj = tkinter.StringVar()
+ label_disj = tkinter.Label(master, textvariable=var_disj)
+ var_disj.set("Fix disjoint nets:")
+ label_disj.grid(row=4, column=0, pady=10)
+ disjoint_check = tkinter.IntVar()
+ check2 = tkinter.Checkbutton(master, width=30, variable=disjoint_check)
+ check2.grid(row=4, column=1, pady=10, padx=5)
+
+ def callback():
+ master.choice_ui = combo.get()
+ master.disjoints_ui = True if disjoint_check.get() == 1 else False
+ master.expansion_ui = expansion.get("1.0", tkinter.END).strip()
+ master.destroy()
+
+ b = tkinter.Button(master, text="Create Cutout", width=40, command=callback)
+ b.grid(row=6, column=1, pady=10)
+
+ tkinter.mainloop()
+
+ choice_ui = getattr(master, "choice_ui", extension_arguments["choice"])
+ disjoints_ui = getattr(master, "disjoints_ui", extension_arguments["fix_disjoints"])
+ expansion_ui = getattr(master, "expansion_ui", extension_arguments["expansion_factor"])
+ signal_ui = getattr(master, "signal_ui", extension_arguments["signals"])
+ reference_ui = getattr(master, "reference_ui", extension_arguments["reference"])
+
+ output_dict = {
+ "choice": choice_ui,
+ "signals": signal_ui,
+ "reference": reference_ui,
+ "expansion_factor": expansion_ui,
+ "fix_disjoints": disjoints_ui,
+ }
+ app.release_desktop(False, False)
+ return output_dict
+
+
+def main(extension_args):
+ choice = extension_args["choice"]
+ signal = extension_args["signals"]
+ reference = extension_args["reference"]
+ expansion = extension_args["expansion_factor"]
+ disjoint = extension_args["fix_disjoints"]
+ app = pyaedt.Desktop(
+ new_desktop=False,
+ version=version,
+ port=port,
+ aedt_process_id=aedt_process_id,
+ student_version=is_student,
+ )
+
+ active_project = app.active_project()
+ active_design = app.active_design()
+ aedb_path = os.path.join(active_project.GetPath(), active_project.GetName() + ".aedb")
+ new_path = aedb_path[:-5] + generate_unique_name("_cutout", n=2) + ".aedb"
+ edb = Edb(aedb_path, active_design.GetName().split(";")[1], edbversion=version)
+ edb.save_edb_as(new_path)
+ edb.cutout(
+ signal_list=signal,
+ reference_list=reference,
+ extent_type=choice,
+ expansion_size=float(expansion) / 1000,
+ use_round_corner=False,
+ output_aedb_path=new_path,
+ open_cutout_at_end=True,
+ use_pyaedt_cutout=True,
+ number_of_threads=4,
+ use_pyaedt_extent_computing=True,
+ extent_defeature=0,
+ remove_single_pin_components=True if disjoint else False,
+ custom_extent=None,
+ custom_extent_units="mm",
+ include_partial_instances=False,
+ keep_voids=True,
+ check_terminals=False,
+ include_pingroups=False,
+ expansion_factor=0,
+ maximum_iterations=10,
+ preserve_components_with_model=False,
+ simple_pad_check=True,
+ keep_lines_as_path=False,
+ )
+ if disjoint:
+ edb.nets.find_and_fix_disjoint_nets(reference)
+ edb.close_edb()
+ h3d = Hfss3dLayout(new_path)
+ if not extension_args["is_test"]: # pragma: no cover
+ app.logger.info("Project generated correctly.")
+ app.release_desktop(False, False)
+ return True
+
+
+if __name__ == "__main__": # pragma: no cover
+ args = get_arguments(extension_arguments, extension_description)
+
+ # Open UI
+ if not args["is_batch"]: # pragma: no cover
+ output = frontend()
+ if output:
+ for output_name, output_value in output.items():
+ if output_name in extension_arguments:
+ args[output_name] = output_value
+
+ main(args)
diff --git a/pyaedt/workflows/hfss3dlayout/export_layout.py b/pyaedt/workflows/hfss3dlayout/export_layout.py
new file mode 100644
index 00000000000..e417cf8fb8e
--- /dev/null
+++ b/pyaedt/workflows/hfss3dlayout/export_layout.py
@@ -0,0 +1,164 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+import os
+
+from pyedb import Edb
+
+import pyaedt
+import pyaedt.workflows.hfss3dlayout
+from pyaedt.workflows.misc import get_aedt_version
+from pyaedt.workflows.misc import get_arguments
+from pyaedt.workflows.misc import get_port
+from pyaedt.workflows.misc import get_process_id
+from pyaedt.workflows.misc import is_student
+
+port = get_port()
+version = get_aedt_version()
+aedt_process_id = get_process_id()
+is_student = is_student()
+
+# Extension batch arguments
+extension_arguments = {"export_ipc": True, "export_configuration": True, "export_bom": True}
+extension_description = "Layout Exporter"
+
+
+def frontend(): # pragma: no cover
+ import tkinter
+ from tkinter import ttk
+
+ import PIL.Image
+ import PIL.ImageTk
+
+ master = tkinter.Tk()
+
+ master.geometry("700x450")
+
+ master.title("Layout exporter")
+
+ # Load the logo for the main window
+ icon_path = os.path.join(os.path.dirname(pyaedt.workflows.__file__), "images", "large", "logo.png")
+ im = PIL.Image.open(icon_path)
+ photo = PIL.ImageTk.PhotoImage(im)
+
+ # Set the icon for the main window
+ master.iconphoto(True, photo)
+
+ # Configure style for ttk buttons
+ style = ttk.Style()
+ style.configure("Toolbutton.TButton", padding=6, font=("Helvetica", 10))
+
+ var = tkinter.StringVar()
+ label = tkinter.Label(master, textvariable=var)
+ var.set("Export IPC2581:")
+ label.grid(row=0, column=0, pady=10)
+ ipc_check = tkinter.IntVar()
+ check = tkinter.Checkbutton(master, width=30, variable=ipc_check)
+ check.grid(row=0, column=1, pady=10, padx=5)
+ ipc_check.set(1)
+
+ var2 = tkinter.StringVar()
+ label2 = tkinter.Label(master, textvariable=var2)
+ var2.set("Export Configuration file:")
+ label2.grid(row=1, column=0, pady=10)
+ configuration_check = tkinter.IntVar()
+ check2 = tkinter.Checkbutton(master, width=30, variable=configuration_check)
+ check2.grid(row=1, column=1, pady=10, padx=5)
+ configuration_check.set(1)
+
+ var3 = tkinter.StringVar()
+ label3 = tkinter.Label(master, textvariable=var3)
+ var3.set("Export BOM file:")
+ label3.grid(row=2, column=0, pady=10)
+ bom_check = tkinter.IntVar()
+ check3 = tkinter.Checkbutton(master, width=30, variable=bom_check)
+ check3.grid(row=2, column=1, pady=10, padx=5)
+ bom_check.set(1)
+
+ def callback():
+ master.ipc_ui = True if ipc_check.get() == 1 else False
+ master.confg_ui = True if configuration_check.get() == 1 else False
+ master.bom_ui = True if bom_check.get() == 1 else False
+ master.destroy()
+
+ b = tkinter.Button(master, text="Export", width=40, command=callback)
+ b.grid(row=3, column=1, pady=10)
+
+ tkinter.mainloop()
+
+ ipc_ui = getattr(master, "ipc_ui", extension_arguments["export_ipc"])
+ confg_ui = getattr(master, "confg_ui", extension_arguments["export_configuration"])
+ bom_ui = getattr(master, "bom_ui", extension_arguments["export_bom"])
+
+ output_dict = {
+ "export_ipc": ipc_ui,
+ "export_configuration": confg_ui,
+ "export_bom": bom_ui,
+ }
+ return output_dict
+
+
+def main(extension_args):
+ ipc = extension_args["export_ipc"]
+ bom = extension_args["export_bom"]
+ config = extension_args["export_configuration"]
+ app = pyaedt.Desktop(
+ new_desktop=False,
+ version=version,
+ port=port,
+ aedt_process_id=aedt_process_id,
+ student_version=is_student,
+ )
+
+ active_project = app.active_project()
+ active_design = app.active_design()
+ aedb_path = os.path.join(active_project.GetPath(), active_project.GetName() + ".aedb")
+ edb = Edb(aedb_path, active_design.GetName().split(";")[1], edbversion=version)
+ if ipc:
+ ipc_file = aedb_path[:-5] + "_ipc2581.xml"
+ edb.export_to_ipc2581(ipc_file)
+ if bom:
+ bom_file = aedb_path[:-5] + "_bom.csv"
+ edb.components.export_bom(bom_file)
+ if config:
+ config_file = aedb_path[:-5] + "_config.json"
+ edb.configuration.export(config_file)
+
+ if not extension_args["is_test"]: # pragma: no cover
+ app.logger.info("Project generated correctly.")
+ app.release_desktop(False, False)
+ return True
+
+
+if __name__ == "__main__": # pragma: no cover
+ args = get_arguments(extension_arguments, extension_description)
+
+ # Open UI
+ if not args["is_batch"]: # pragma: no cover
+ output = frontend()
+ if output:
+ for output_name, output_value in output.items():
+ if output_name in extension_arguments:
+ args[output_name] = output_value
+
+ main(args)
diff --git a/pyaedt/workflows/hfss3dlayout/export_to_3d.py b/pyaedt/workflows/hfss3dlayout/export_to_3d.py
index c51c7b83eea..7e8d4ee9bb5 100644
--- a/pyaedt/workflows/hfss3dlayout/export_to_3d.py
+++ b/pyaedt/workflows/hfss3dlayout/export_to_3d.py
@@ -1,6 +1,7 @@
-# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates.
-# SPDX-License-Identifier: MIT
+# -*- coding: utf-8 -*-
#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
@@ -100,8 +101,8 @@ def main(extension_args):
choice = extension_args["choice"]
app = pyaedt.Desktop(
- new_desktop_session=False,
- specified_version=version,
+ new_desktop=False,
+ version=version,
port=port,
aedt_process_id=aedt_process_id,
student_version=is_student,
@@ -119,7 +120,7 @@ def main(extension_args):
app.release_desktop(False, False)
raise Exception("Hfss 3D Layout project is needed.")
- h3d = pyaedt.Hfss3dLayout(projectname=project_name, designname=design_name)
+ h3d = pyaedt.Hfss3dLayout(project=project_name, design=design_name)
setup = h3d.create_setup()
suffix = suffixes[choice]
@@ -133,21 +134,16 @@ def main(extension_args):
h3d.save_project()
if choice == "Export to Q3D":
- _ = pyaedt.Q3d(projectname=h3d.project_file[:-5] + f"_{suffix}.aedt")
+ _ = pyaedt.Q3d(project=h3d.project_file[:-5] + f"_{suffix}.aedt")
else:
- aedtapp = pyaedt.Hfss(projectname=h3d.project_file[:-5] + f"_{suffix}.aedt")
+ aedtapp = pyaedt.Hfss(project=h3d.project_file[:-5] + f"_{suffix}.aedt")
aedtapp2 = None
if choice == "Export to Maxwell 3D":
- aedtapp2 = pyaedt.Maxwell3d(projectname=aedtapp.project_name)
+ aedtapp2 = pyaedt.Maxwell3d(project=aedtapp.project_name)
elif choice == "Export to Icepak":
- aedtapp2 = pyaedt.Icepak(projectname=aedtapp.project_name)
+ aedtapp2 = pyaedt.Icepak(project=aedtapp.project_name)
if aedtapp2:
- aedtapp2.copy_solid_bodies_from(
- aedtapp,
- no_vacuum=False,
- no_pec=False,
- include_sheets=True,
- )
+ aedtapp2.copy_solid_bodies_from(aedtapp, no_vacuum=False, no_pec=False, include_sheets=True)
aedtapp2.delete_design(aedtapp.design_name)
aedtapp2.save_project()
diff --git a/pyaedt/workflows/hfss3dlayout/images/large/cutout.png b/pyaedt/workflows/hfss3dlayout/images/large/cutout.png
new file mode 100644
index 00000000000..996169b4e13
Binary files /dev/null and b/pyaedt/workflows/hfss3dlayout/images/large/cutout.png differ
diff --git a/pyaedt/workflows/hfss3dlayout/images/large/export.png b/pyaedt/workflows/hfss3dlayout/images/large/export.png
new file mode 100644
index 00000000000..820c5ce2392
Binary files /dev/null and b/pyaedt/workflows/hfss3dlayout/images/large/export.png differ
diff --git a/pyaedt/workflows/hfss3dlayout/push_excitation_from_file_3dl.py b/pyaedt/workflows/hfss3dlayout/push_excitation_from_file_3dl.py
new file mode 100644
index 00000000000..f0f8db4819a
--- /dev/null
+++ b/pyaedt/workflows/hfss3dlayout/push_excitation_from_file_3dl.py
@@ -0,0 +1,212 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+import os.path
+
+import pyaedt
+from pyaedt import Hfss3dLayout
+import pyaedt.workflows
+from pyaedt.workflows.misc import get_aedt_version
+from pyaedt.workflows.misc import get_arguments
+from pyaedt.workflows.misc import get_port
+from pyaedt.workflows.misc import get_process_id
+from pyaedt.workflows.misc import is_student
+
+port = get_port()
+version = get_aedt_version()
+aedt_process_id = get_process_id()
+is_student = is_student()
+
+# Extension batch arguments
+extension_arguments = {"file_path": "", "choice": ""}
+extension_description = "Push excitation from file"
+
+
+def frontend(): # pragma: no cover
+
+ import tkinter
+ from tkinter import filedialog
+ from tkinter import ttk
+
+ import PIL.Image
+ import PIL.ImageTk
+
+ # Get ports
+ app = pyaedt.Desktop(
+ new_desktop=False,
+ version=version,
+ port=port,
+ aedt_process_id=aedt_process_id,
+ student_version=is_student,
+ )
+
+ active_project = app.active_project()
+ active_design = app.active_design()
+
+ project_name = active_project.GetName()
+
+ if active_design.GetDesignType() in ["HFSS 3D Layout Design"]:
+ design_name = active_design.GetName().split(";")[1]
+ else: # pragma: no cover
+ app.logger.debug("Hfss 3D Layout project is needed.")
+ app.release_desktop(False, False)
+ raise Exception("Hfss 3D Layout project is needed.")
+
+ hfss_3dl = Hfss3dLayout(project_name, design_name)
+
+ port_selection = hfss_3dl.excitations
+
+ if not port_selection:
+ app.logger.error("No ports found.")
+ hfss_3dl.release_desktop(False, False)
+ output_dict = {"choice": "", "file_path": ""}
+ return output_dict
+
+ # Create UI
+ master = tkinter.Tk()
+
+ master.geometry("700x150")
+
+ master.title("Assign push excitation to port from transient data")
+
+ # Load the logo for the main window
+ icon_path = os.path.join(pyaedt.workflows.__path__[0], "images", "large", "logo.png")
+ im = PIL.Image.open(icon_path)
+ photo = PIL.ImageTk.PhotoImage(im)
+
+ # Set the icon for the main window
+ master.iconphoto(True, photo)
+
+ # Configure style for ttk buttons
+ style = ttk.Style()
+ style.configure("Toolbutton.TButton", padding=6, font=("Helvetica", 8))
+
+ var = tkinter.StringVar()
+ label = tkinter.Label(master, textvariable=var)
+ var.set("Choose a port:")
+ label.grid(row=0, column=0, pady=10)
+ combo = ttk.Combobox(master, width=30)
+ combo["values"] = port_selection
+ combo.current(0)
+ combo.grid(row=0, column=1, pady=10, padx=5)
+ combo.focus_set()
+ var2 = tkinter.StringVar()
+ label2 = tkinter.Label(master, textvariable=var2)
+ var2.set("Browse file:")
+ label2.grid(row=1, column=0, pady=10)
+ text = tkinter.Text(master, width=50, height=1)
+ text.grid(row=1, column=1, pady=10, padx=5)
+
+ def browseFiles():
+ filename = filedialog.askopenfilename(
+ initialdir="/",
+ title="Select a Transient File",
+ filetypes=(("Transient curve", "*.csv*"), ("all files", "*.*")),
+ )
+ text.insert(tkinter.END, filename)
+
+ b1 = tkinter.Button(master, text="...", width=10, command=browseFiles)
+ b1.grid(row=3, column=0)
+ b1.grid(row=1, column=2, pady=10)
+
+ def callback():
+ master.choice_ui = combo.get()
+ master.file_path_ui = text.get("1.0", tkinter.END).strip()
+ master.destroy()
+
+ b = tkinter.Button(master, text="Ok", width=40, command=callback)
+ b.grid(row=2, column=1, pady=10)
+
+ tkinter.mainloop()
+
+ file_path_ui = getattr(master, "file_path_ui", extension_arguments["file_path"])
+ choice_ui = getattr(master, "choice_ui", extension_arguments["choice"])
+
+ if not file_path_ui or not os.path.isfile(file_path_ui):
+ app.logger.error("File does not exist.")
+
+ if not choice_ui:
+ app.logger.error("Excitation not found.")
+
+ hfss_3dl.release_desktop(False, False)
+
+ output_dict = {"choice": choice_ui, "file_path": file_path_ui}
+
+ return output_dict
+
+
+def main(extension_args):
+ choice = extension_args["choice"]
+ file_path = extension_args["file_path"]
+
+ app = pyaedt.Desktop(
+ new_desktop=False,
+ version=version,
+ port=port,
+ aedt_process_id=aedt_process_id,
+ student_version=is_student,
+ )
+
+ active_project = app.active_project()
+ active_design = app.active_design()
+
+ project_name = active_project.GetName()
+
+ if active_design.GetDesignType() in ["HFSS 3D Layout Design"]:
+ design_name = active_design.GetName().split(";")[1]
+ else: # pragma: no cover
+ app.logger.debug("Hfss 3D Layout project is needed.")
+ app.release_desktop(False, False)
+ raise Exception("Hfss 3D Layout project is needed.")
+
+ hfss_3dl = Hfss3dLayout(project_name, design_name)
+
+ if not os.path.isfile(file_path): # pragma: no cover
+ app.logger.error("File does not exist.")
+ elif choice:
+ hfss_3dl.edit_source_from_file(
+ choice,
+ file_path,
+ is_time_domain=True,
+ )
+ app.logger.info("Excitation assigned correctly.")
+ else:
+ app.logger.error("Failed to select a port.")
+
+ if not extension_args["is_test"]: # pragma: no cover
+ app.release_desktop(False, False)
+ return True
+
+
+if __name__ == "__main__": # pragma: no cover
+ args = get_arguments(extension_arguments, extension_description)
+
+ # Open UI
+ if not args["is_batch"]: # pragma: no cover
+ output = frontend()
+ if output:
+ for output_name, output_value in output.items():
+ if output_name in extension_arguments:
+ args[output_name] = output_value
+
+ main(args)
diff --git a/pyaedt/workflows/hfss3dlayout/toolkits_catalog.toml b/pyaedt/workflows/hfss3dlayout/toolkits_catalog.toml
index 4bbf3a28f65..58893164913 100644
--- a/pyaedt/workflows/hfss3dlayout/toolkits_catalog.toml
+++ b/pyaedt/workflows/hfss3dlayout/toolkits_catalog.toml
@@ -4,3 +4,24 @@ script = "export_to_3d.py"
icon = "images/large/cad3d.png"
template = "run_pyaedt_toolkit_script"
pip = ""
+
+[PushfromTransient]
+name = "Push Excitation from transient data"
+script = "push_excitation_from_file_3dl.py"
+icon = "images/large/push.png"
+template = "run_pyaedt_toolkit_script"
+pip = ""
+
+[ExportFiles]
+name = "Export Layout info"
+script = "export_layout.py"
+icon = "images/large/export.png"
+template = "run_pyedb_toolkit_script"
+pip = ""
+
+[Cutout]
+name = "Advanced cutout"
+script = "cutout.py"
+icon = "images/large/cutout.png"
+template = "run_pyedb_toolkit_script"
+pip = ""
\ No newline at end of file
diff --git a/pyaedt/workflows/icepak/__init__.py b/pyaedt/workflows/icepak/__init__.py
index 3bc3c8e5b19..f10103137e9 100644
--- a/pyaedt/workflows/icepak/__init__.py
+++ b/pyaedt/workflows/icepak/__init__.py
@@ -1,6 +1,7 @@
-# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates.
-# SPDX-License-Identifier: MIT
+# -*- coding: utf-8 -*-
#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
diff --git a/pyaedt/workflows/installer/__init__.py b/pyaedt/workflows/installer/__init__.py
index 3bc3c8e5b19..f10103137e9 100644
--- a/pyaedt/workflows/installer/__init__.py
+++ b/pyaedt/workflows/installer/__init__.py
@@ -1,6 +1,7 @@
-# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates.
-# SPDX-License-Identifier: MIT
+# -*- coding: utf-8 -*-
#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
diff --git a/pyaedt/workflows/installer/console_setup.py b/pyaedt/workflows/installer/console_setup.py
index b32f3273fa1..0ea19672ce0 100644
--- a/pyaedt/workflows/installer/console_setup.py
+++ b/pyaedt/workflows/installer/console_setup.py
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
"""
Launches an interactive shell with an instance of HFSS
@@ -64,18 +88,18 @@ def release(d):
error = False
if port:
desktop = Desktop(
- specified_version=version,
+ version=version,
port=port,
- new_desktop_session=False,
+ new_desktop=False,
non_graphical=False,
close_on_exit=False,
student_version=student_version,
)
elif is_windows:
desktop = Desktop(
- specified_version=version,
+ version=version,
aedt_process_id=aedt_process_id,
- new_desktop_session=False,
+ new_desktop=False,
non_graphical=False,
close_on_exit=False,
student_version=student_version,
diff --git a/pyaedt/workflows/installer/extension_manager.py b/pyaedt/workflows/installer/extension_manager.py
index f07cfd6ce82..d90a781474c 100644
--- a/pyaedt/workflows/installer/extension_manager.py
+++ b/pyaedt/workflows/installer/extension_manager.py
@@ -1,6 +1,7 @@
-# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates.
-# SPDX-License-Identifier: MIT
+# -*- coding: utf-8 -*-
#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
@@ -240,9 +241,9 @@ def button_is_clicked(
name = toolkit_name.get()
desktop = Desktop(
- specified_version=version,
+ version=version,
port=port,
- new_desktop_session=False,
+ new_desktop=False,
non_graphical=False,
close_on_exit=False,
student_version=student_version,
@@ -293,6 +294,9 @@ def button_is_clicked(
if not file:
file = os.path.join(os.path.dirname(pyaedt.workflows.templates.__file__), "extension_template.py")
if os.path.isfile(executable_interpreter):
+ template_file = "run_pyaedt_toolkit_script"
+ if selected_toolkit_info:
+ template_file = selected_toolkit_info.get("template")
add_script_to_menu(
name=name,
script_file=file,
@@ -301,6 +305,7 @@ def button_is_clicked(
executable_interpreter=executable_interpreter,
personal_lib=desktop.personallib,
aedt_version=desktop.aedt_version_id,
+ template_file=template_file,
)
desktop.logger.info("{} installed".format(name))
else:
diff --git a/pyaedt/workflows/installer/pyaedt_installer.py b/pyaedt/workflows/installer/pyaedt_installer.py
index 8d7a5ef0d63..29959a4b6c1 100644
--- a/pyaedt/workflows/installer/pyaedt_installer.py
+++ b/pyaedt/workflows/installer/pyaedt_installer.py
@@ -1,6 +1,7 @@
-# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates.
-# SPDX-License-Identifier: MIT
+# -*- coding: utf-8 -*-
#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
diff --git a/pyaedt/workflows/maxwell2d/__init__.py b/pyaedt/workflows/maxwell2d/__init__.py
index 3bc3c8e5b19..f10103137e9 100644
--- a/pyaedt/workflows/maxwell2d/__init__.py
+++ b/pyaedt/workflows/maxwell2d/__init__.py
@@ -1,6 +1,7 @@
-# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates.
-# SPDX-License-Identifier: MIT
+# -*- coding: utf-8 -*-
#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
diff --git a/pyaedt/workflows/maxwell3d/__init__.py b/pyaedt/workflows/maxwell3d/__init__.py
index 3bc3c8e5b19..f10103137e9 100644
--- a/pyaedt/workflows/maxwell3d/__init__.py
+++ b/pyaedt/workflows/maxwell3d/__init__.py
@@ -1,6 +1,7 @@
-# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates.
-# SPDX-License-Identifier: MIT
+# -*- coding: utf-8 -*-
#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
diff --git a/pyaedt/workflows/mechanical/__init__.py b/pyaedt/workflows/mechanical/__init__.py
index 3bc3c8e5b19..f10103137e9 100644
--- a/pyaedt/workflows/mechanical/__init__.py
+++ b/pyaedt/workflows/mechanical/__init__.py
@@ -1,6 +1,7 @@
-# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates.
-# SPDX-License-Identifier: MIT
+# -*- coding: utf-8 -*-
#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
diff --git a/pyaedt/workflows/misc.py b/pyaedt/workflows/misc.py
index 687620ba188..89ba7b998a6 100644
--- a/pyaedt/workflows/misc.py
+++ b/pyaedt/workflows/misc.py
@@ -1,6 +1,7 @@
-# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates.
-# SPDX-License-Identifier: MIT
+# -*- coding: utf-8 -*-
#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
diff --git a/pyaedt/workflows/project/__init__.py b/pyaedt/workflows/project/__init__.py
index 3bc3c8e5b19..f10103137e9 100644
--- a/pyaedt/workflows/project/__init__.py
+++ b/pyaedt/workflows/project/__init__.py
@@ -1,6 +1,7 @@
-# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates.
-# SPDX-License-Identifier: MIT
+# -*- coding: utf-8 -*-
#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
diff --git a/pyaedt/workflows/project/advanced_fields_calculator.py b/pyaedt/workflows/project/advanced_fields_calculator.py
new file mode 100644
index 00000000000..e60709d2746
--- /dev/null
+++ b/pyaedt/workflows/project/advanced_fields_calculator.py
@@ -0,0 +1,274 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+import os.path
+
+import pyaedt
+from pyaedt import get_pyaedt_app
+from pyaedt.generic.general_methods import generate_unique_name
+from pyaedt.modeler.cad.elements3d import FacePrimitive
+import pyaedt.workflows
+from pyaedt.workflows.misc import get_aedt_version
+from pyaedt.workflows.misc import get_arguments
+from pyaedt.workflows.misc import get_port
+from pyaedt.workflows.misc import get_process_id
+from pyaedt.workflows.misc import is_student
+
+port = get_port()
+version = get_aedt_version()
+aedt_process_id = get_process_id()
+is_student = is_student()
+
+# Extension batch arguments
+extension_arguments = {"setup": "", "calculation": "", "assignment": []}
+extension_description = "Simplified use of Fields Calculator"
+
+
+def frontend(): # pragma: no cover
+
+ import tkinter
+ from tkinter import ttk
+
+ import PIL.Image
+ import PIL.ImageTk
+
+ # Get ports
+ app = pyaedt.Desktop(
+ new_desktop=False,
+ specified_version=version,
+ port=port,
+ aedt_process_id=aedt_process_id,
+ student_version=is_student,
+ )
+
+ active_project = app.active_project()
+ active_design = app.active_design()
+
+ project_name = active_project.GetName()
+ if active_design.GetDesignType() == "HFSS 3D Layout Design":
+ design_name = active_design.GetDesignName()
+ else:
+ design_name = active_design.GetName()
+
+ aedtapp = get_pyaedt_app(project_name, design_name)
+
+ # Load new expressions from file
+ current_directory = os.getcwd()
+ all_files = os.listdir(current_directory)
+ toml_files = [f for f in all_files if f.endswith(".toml")]
+ for toml_file in toml_files:
+ aedtapp.post.fields_calculator.load_expression_file(toml_file)
+
+ # Personal Lib directory
+ all_files = os.listdir(aedtapp.personallib)
+ toml_files = [os.path.join(aedtapp.personallib, f) for f in all_files if f.endswith(".toml")]
+ for toml_file in toml_files:
+ aedtapp.post.fields_calculator.load_expression_file(toml_file)
+
+ # Available fields calculator expressions
+ available_expressions = aedtapp.post.fields_calculator.expression_catalog
+ available_descriptions = {}
+ for expression, expression_info in available_expressions.items():
+ if "design_type" in expression_info and aedtapp.design_type in expression_info["design_type"]:
+ if "Transient" in aedtapp.solution_type and "Transient" in expression_info["solution_type"]:
+ available_descriptions[expression] = expression_info["description"]
+ elif "Transient" not in aedtapp.solution_type and "Transient" not in expression_info["solution_type"]:
+ available_descriptions[expression] = expression_info["description"]
+
+ available_setups = aedtapp.existing_analysis_sweeps
+
+ if not available_setups:
+ app.logger.error("No setups defined.")
+ aedtapp.release_desktop(False, False)
+ output_dict = {"setup": "", "calculation": "", "assignment": []}
+ return output_dict
+
+ # Create UI
+ master = tkinter.Tk()
+
+ master.geometry("700x150")
+
+ master.title("Advanced fields calculator")
+
+ # Load the logo for the main window
+ icon_path = os.path.join(pyaedt.workflows.__path__[0], "images", "large", "logo.png")
+ im = PIL.Image.open(icon_path)
+ photo = PIL.ImageTk.PhotoImage(im)
+
+ # Set the icon for the main window
+ master.iconphoto(True, photo)
+
+ # Configure style for ttk buttons
+ style = ttk.Style()
+ style.configure("Toolbutton.TButton", padding=6, font=("Helvetica", 8))
+
+ var = tkinter.StringVar()
+ label = tkinter.Label(master, textvariable=var)
+ var.set("Solved setup:")
+ label.grid(row=0, column=0, pady=10, padx=15)
+ combo_setup = ttk.Combobox(master, width=30)
+ combo_setup["values"] = available_setups
+ combo_setup.current(0)
+ combo_setup.grid(row=0, column=1, pady=10, padx=10)
+ combo_setup.focus_set()
+
+ var = tkinter.StringVar()
+ label = tkinter.Label(master, textvariable=var)
+ var.set("Calculations:")
+ label.grid(row=1, column=0, pady=10, padx=15)
+ combo_calculation = ttk.Combobox(master, width=30)
+ combo_calculation["values"] = list(available_descriptions.values())
+ combo_calculation.current(0)
+ combo_calculation.grid(row=1, column=1, pady=10, padx=10)
+ combo_calculation.focus_set()
+
+ def callback():
+ master.setup = combo_setup.get()
+ master.calculation = combo_calculation.get()
+ master.destroy()
+
+ b = tkinter.Button(master, text="Ok", width=40, command=callback)
+ b.grid(row=2, column=1, pady=10)
+
+ tkinter.mainloop()
+
+ setup_ui = getattr(master, "setup", extension_arguments["setup"])
+ if getattr(master, "setup"):
+ setup = setup_ui
+ else:
+ setup = extension_arguments["setup"]
+
+ calculation_ui = getattr(master, "calculation", extension_arguments["calculation"])
+ calculation = extension_arguments["setup"]
+
+ if getattr(master, "setup"):
+ calculation_description = calculation_ui
+ for k, v in available_descriptions.items():
+ if calculation_description == v:
+ calculation = k
+ break
+
+ assignments = aedtapp.modeler.convert_to_selections(aedtapp.modeler.selections, True)
+
+ app.release_desktop(False, False)
+
+ output_dict = {"setup": setup, "calculation": calculation, "assignment": assignments}
+
+ return output_dict
+
+
+def main(extension_args):
+ setup = extension_args["setup"]
+ calculation = extension_args["calculation"]
+ assignment_selection = extension_args["assignment"]
+
+ app = pyaedt.Desktop(
+ new_desktop=False,
+ version=version,
+ port=port,
+ aedt_process_id=aedt_process_id,
+ student_version=is_student,
+ )
+
+ active_project = app.active_project()
+ active_design = app.active_design()
+
+ project_name = active_project.GetName()
+ if active_design.GetDesignType() == "HFSS 3D Layout Design": # pragma: no cover
+ design_name = active_design.GetDesignName()
+ else:
+ design_name = active_design.GetName()
+
+ aedtapp = get_pyaedt_app(project_name, design_name)
+
+ if not calculation:
+ aedtapp.logger.warning("No calculation selected.")
+ if not extension_args["is_test"]: # pragma: no cover
+ app.release_desktop(False, False)
+ return False
+
+ assignments = []
+ for assignment in assignment_selection:
+ if assignment not in aedtapp.modeler.object_names and "Face" in assignment:
+ assignments.append(aedtapp.modeler.get_face_by_id(int(assignment[4:])))
+ else:
+ assignments.append(assignment)
+
+ # Load new expressions from file
+ # Current directory
+ current_directory = os.getcwd()
+ all_files = os.listdir(current_directory)
+ toml_files = [f for f in all_files if f.endswith(".toml")]
+ for toml_file in toml_files:
+ aedtapp.post.fields_calculator.load_expression_file(toml_file)
+
+ # Personal Lib directory
+ all_files = os.listdir(aedtapp.personallib)
+ toml_files = [os.path.join(aedtapp.personallib, f) for f in all_files if f.endswith(".toml")]
+ for toml_file in toml_files:
+ aedtapp.post.fields_calculator.load_expression_file(toml_file)
+
+ names = []
+
+ if not aedtapp.post.fields_calculator.is_general_expression(calculation):
+ for assignment in assignments:
+ assignment_str = assignment
+ if isinstance(assignment_str, FacePrimitive):
+ assignment_str = str(assignment.id)
+ elif not isinstance(assignment_str, str): # pragma: no cover
+ assignment_str = generate_unique_name(calculation)
+ name = aedtapp.post.fields_calculator.add_expression(
+ calculation, assignment, calculation + "_" + assignment_str
+ )
+ if name:
+ names.append(name)
+ else:
+ aedtapp.logger.error("Wrong assignment.")
+ if not extension_args["is_test"]: # pragma: no cover
+ app.release_desktop(False, False)
+ return False
+ else:
+ names.append(aedtapp.post.fields_calculator.add_expression(calculation, None))
+
+ if not aedtapp.post.fields_calculator.is_general_expression(calculation):
+ _ = aedtapp.post.fields_calculator.expression_plot(calculation, None, names, setup)
+ else:
+ _ = aedtapp.post.fields_calculator.expression_plot(calculation, assignments, names, setup)
+
+ if not extension_args["is_test"]: # pragma: no cover
+ app.release_desktop(False, False)
+ return True
+
+
+if __name__ == "__main__": # pragma: no cover
+ args = get_arguments(extension_arguments, extension_description)
+
+ # Open UI
+ if not args["is_batch"]: # pragma: no cover
+ output = frontend()
+ if output:
+ for output_name, output_value in output.items():
+ if output_name in extension_arguments:
+ args[output_name] = output_value
+
+ main(args)
diff --git a/pyaedt/workflows/project/configure_edb.py b/pyaedt/workflows/project/configure_edb.py
new file mode 100644
index 00000000000..1934e746b3d
--- /dev/null
+++ b/pyaedt/workflows/project/configure_edb.py
@@ -0,0 +1,187 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+import os.path
+
+from pyedb import Edb
+
+import pyaedt
+from pyaedt import Hfss3dLayout
+from pyaedt import generate_unique_name
+from pyaedt.generic.filesystem import search_files
+import pyaedt.workflows
+from pyaedt.workflows.misc import get_aedt_version
+from pyaedt.workflows.misc import get_arguments
+from pyaedt.workflows.misc import get_port
+from pyaedt.workflows.misc import get_process_id
+from pyaedt.workflows.misc import is_student
+
+port = get_port()
+version = get_aedt_version()
+aedt_process_id = get_process_id()
+is_student = is_student()
+
+# Extension batch arguments
+extension_arguments = {"aedb_path": "", "configuration_path": ""}
+extension_description = "Configure project from aedb file"
+
+
+def frontend(): # pragma: no cover
+
+ import tkinter
+ from tkinter import filedialog
+ from tkinter import ttk
+
+ import PIL.Image
+ import PIL.ImageTk
+
+ master = tkinter.Tk()
+
+ master.geometry("750x250")
+
+ master.title(extension_description)
+
+ # Load the logo for the main window
+ icon_path = os.path.join(pyaedt.workflows.__path__[0], "images", "large", "logo.png")
+ im = PIL.Image.open(icon_path)
+ photo = PIL.ImageTk.PhotoImage(im)
+
+ # Set the icon for the main window
+ master.iconphoto(True, photo)
+
+ # Configure style for ttk buttons
+ style = ttk.Style()
+ style.configure("Toolbutton.TButton", padding=6, font=("Helvetica", 8))
+
+ var2 = tkinter.StringVar()
+ label2 = tkinter.Label(master, textvariable=var2)
+ var2.set("Browse file:")
+ label2.grid(row=0, column=0, pady=10)
+ text = tkinter.Text(master, width=40, height=1)
+ text.grid(row=0, column=1, pady=10, padx=5)
+
+ def browse_aedb():
+ filename = filedialog.askopenfilename(
+ initialdir="/",
+ title="Select a layout folder or file",
+ filetypes=(("aedb file", "*.def"), ("brd", "*.brd"), ("all files", "*.*")),
+ )
+ if filename.endswith(".def"):
+ filename = os.path.dirname(filename)
+ text.insert(tkinter.END, filename)
+
+ b1 = tkinter.Button(master, text="...", width=10, command=browse_aedb)
+ b1.grid(row=0, column=2, pady=10)
+
+ var3 = tkinter.StringVar()
+ label3 = tkinter.Label(master, textvariable=var3)
+ var3.set("Browse configuration file or folder:")
+ label3.grid(row=1, column=0, pady=10)
+ text2 = tkinter.Text(master, width=40, height=1)
+ text2.grid(row=1, column=1, pady=10, padx=5)
+
+ def browse_config():
+ inital_dir = text.get("1.0", tkinter.END).strip()
+ filename = filedialog.askopenfilename(
+ initialdir=os.path.dirname(inital_dir) if inital_dir else "/",
+ title="Select configuration file",
+ filetypes=(("Configuration file", "*.json"), ("Configuration file", "*.toml")),
+ )
+ text2.insert(tkinter.END, filename)
+
+ b2 = tkinter.Button(master, text="...", width=10, command=browse_config)
+ b2.grid(row=1, column=2, pady=10)
+
+ def callback():
+ master.aedb_path_ui = text.get("1.0", tkinter.END).strip()
+ master.configuration_path_ui = text2.get("1.0", tkinter.END).strip()
+ master.destroy()
+
+ b3 = tkinter.Button(master, text="Ok", width=40, command=callback)
+ b3.grid(row=25, column=1, pady=10, padx=10)
+
+ tkinter.mainloop()
+
+ aedb_path_ui = getattr(master, "aedb_path_ui", extension_arguments["aedb_path"])
+
+ configuration_path_ui = getattr(master, "configuration_path_ui", extension_arguments["configuration_path"])
+
+ output_dict = {
+ "configuration_path": configuration_path_ui,
+ "aedb_path": aedb_path_ui,
+ }
+ return output_dict
+
+
+def main(extension_args):
+ aedb_path = extension_args["aedb_path"]
+ config = extension_args["configuration_path"]
+ if os.path.isdir(config):
+ configs = search_files(config, "*.json")
+ configs += search_files(config, "*.toml")
+ else:
+ configs = [config]
+ app = pyaedt.Desktop(
+ new_desktop_session=False,
+ specified_version=version,
+ port=port,
+ aedt_process_id=aedt_process_id,
+ student_version=is_student,
+ )
+ if aedb_path == "":
+ project_name = app.active_project().GetName()
+ aedb_path = os.path.join(app.active_project().GetPath(), project_name + ".aedb")
+ else:
+ project_name = os.path.splitext(os.path.split(aedb_path)[-1])[0]
+ if project_name in app.project_list():
+ app.odesktop.CloseProject(project_name)
+ for config in configs:
+ edbapp = Edb(aedb_path, edbversion=version)
+ config_name = os.path.splitext(os.path.split(config)[-1])[0]
+ output_path = aedb_path[:-5] + f"_{config_name}.aedb"
+ if os.path.exists(output_path):
+ new_name = generate_unique_name(config_name, n=2)
+ output_path = aedb_path[:-5] + f"_{new_name}.aedb"
+ edbapp.configuration.load(config_file=config)
+ edbapp.configuration.run()
+ edbapp.save_edb_as(output_path)
+ edbapp.close()
+ h3d = Hfss3dLayout(output_path)
+ h3d.save_project()
+ if not extension_args["is_test"]: # pragma: no cover
+ app.release_desktop(False, False)
+ return True
+
+
+if __name__ == "__main__": # pragma: no cover
+ args = get_arguments(extension_arguments, extension_description)
+
+ # Open UI
+ if not args["is_batch"]: # pragma: no cover
+ output = frontend()
+ if output:
+ for output_name, output_value in output.items():
+ if output_name in extension_arguments:
+ args[output_name] = output_value
+
+ main(args)
diff --git a/pyaedt/workflows/project/create_report.py b/pyaedt/workflows/project/create_report.py
index ed8fe38d95c..a2b7e1a1e42 100644
--- a/pyaedt/workflows/project/create_report.py
+++ b/pyaedt/workflows/project/create_report.py
@@ -1,6 +1,7 @@
-# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates.
-# SPDX-License-Identifier: MIT
+# -*- coding: utf-8 -*-
#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
@@ -44,8 +45,8 @@
def main(extension_args):
app = pyaedt.Desktop(
- new_desktop_session=False,
- specified_version=version,
+ new_desktop=False,
+ version=version,
port=port,
aedt_process_id=aedt_process_id,
student_version=is_student,
diff --git a/pyaedt/workflows/project/images/large/aedb.png b/pyaedt/workflows/project/images/large/aedb.png
new file mode 100644
index 00000000000..380c40ca09e
Binary files /dev/null and b/pyaedt/workflows/project/images/large/aedb.png differ
diff --git a/pyaedt/workflows/project/images/large/fields.png b/pyaedt/workflows/project/images/large/fields.png
new file mode 100644
index 00000000000..ec44b53d34f
Binary files /dev/null and b/pyaedt/workflows/project/images/large/fields.png differ
diff --git a/pyaedt/workflows/project/import_nastran.py b/pyaedt/workflows/project/import_nastran.py
index d728cf204bf..9bfc0968727 100644
--- a/pyaedt/workflows/project/import_nastran.py
+++ b/pyaedt/workflows/project/import_nastran.py
@@ -1,6 +1,7 @@
-# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates.
-# SPDX-License-Identifier: MIT
+# -*- coding: utf-8 -*-
#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
@@ -23,8 +24,8 @@
import os.path
import pyaedt
-from pyaedt import generate_unique_name
from pyaedt import get_pyaedt_app
+from pyaedt.modules.solutions import nastran_to_stl
import pyaedt.workflows
from pyaedt.workflows.misc import get_aedt_version
from pyaedt.workflows.misc import get_arguments
@@ -69,47 +70,47 @@ def frontend(): # pragma: no cover
style = ttk.Style()
style.configure("Toolbutton.TButton", padding=6, font=("Helvetica", 8))
+ var2 = tkinter.StringVar()
+ label2 = tkinter.Label(master, textvariable=var2)
+ var2.set("Browse file:")
+ label2.grid(row=0, column=0, pady=10)
+ text = tkinter.Text(master, width=40, height=1)
+ text.grid(row=0, column=1, pady=10, padx=5)
+
+ def browseFiles():
+ filename = filedialog.askopenfilename(
+ initialdir="/",
+ title="Select a Nastran or stl File",
+ filetypes=(("Nastran", "*.nas"), ("STL", "*.stl"), ("all files", "*.*")),
+ )
+ text.insert(tkinter.END, filename)
+
+ b1 = tkinter.Button(master, text="...", width=10, command=browseFiles)
+ b1.grid(row=0, column=2, pady=10)
+
var = tkinter.StringVar()
label = tkinter.Label(master, textvariable=var)
var.set("Decimation factor (0-0.9). It may affect results:")
- label.grid(row=0, column=0, pady=10)
+ label.grid(row=1, column=0, pady=10)
check = tkinter.Text(master, width=20, height=1)
check.insert(tkinter.END, "0.0")
- check.grid(row=0, column=1, pady=10, padx=5)
+ check.grid(row=1, column=1, pady=10, padx=5)
var = tkinter.StringVar()
label = tkinter.Label(master, textvariable=var)
var.set("Import as lightweight (only HFSS):")
- label.grid(row=1, column=0, pady=10)
+ label.grid(row=2, column=0, pady=10)
light = tkinter.IntVar()
check2 = tkinter.Checkbutton(master, width=30, variable=light)
- check2.grid(row=1, column=1, pady=10, padx=5)
+ check2.grid(row=2, column=1, pady=10, padx=5)
var = tkinter.StringVar()
label = tkinter.Label(master, textvariable=var)
var.set("Enable planar merge:")
- label.grid(row=2, column=0, pady=10)
+ label.grid(row=3, column=0, pady=10)
planar = tkinter.IntVar(value=1)
check3 = tkinter.Checkbutton(master, width=30, variable=planar)
- check3.grid(row=2, column=1, pady=10, padx=5)
-
- var2 = tkinter.StringVar()
- label2 = tkinter.Label(master, textvariable=var2)
- var2.set("Browse file:")
- label2.grid(row=3, column=0, pady=10)
- text = tkinter.Text(master, width=40, height=1)
- text.grid(row=3, column=1, pady=10, padx=5)
-
- def browseFiles():
- filename = filedialog.askopenfilename(
- initialdir="/",
- title="Select a Nastran or stl File",
- filetypes=(("Nastran", "*.nas"), ("STL", "*.stl"), ("all files", "*.*")),
- )
- text.insert(tkinter.END, filename)
-
- b1 = tkinter.Button(master, text="...", width=10, command=browseFiles)
- b1.grid(row=3, column=2, pady=10)
+ check3.grid(row=3, column=1, pady=10, padx=5)
def callback():
master.decimate_ui = float(check.get("1.0", tkinter.END).strip())
@@ -125,21 +126,7 @@ def preview():
master.file_path_ui = text.get("1.0", tkinter.END).strip()
if master.file_path_ui.endswith(".nas"):
- design_name = generate_unique_name("Preview", n=2)
-
- app = pyaedt.Hfss(
- new_desktop_session=False,
- specified_version=version,
- port=port,
- aedt_process_id=aedt_process_id,
- student_version=is_student,
- designname=design_name,
- )
-
- app.modeler.import_nastran(
- master.file_path_ui, decimation=master.decimate_ui, save_only_stl=True, preview=True
- )
- app.release_desktop(False, False)
+ nastran_to_stl(input_file=master.file_path_ui, decimation=master.decimate_ui, preview=True)
else:
from pyaedt.modules.solutions import simplify_stl
@@ -175,8 +162,8 @@ def main(extension_args):
if os.path.exists(file_path):
app = pyaedt.Desktop(
- new_desktop_session=False,
- specified_version=version,
+ new_desktop=False,
+ version=version,
port=port,
aedt_process_id=aedt_process_id,
student_version=is_student,
@@ -204,8 +191,8 @@ def main(extension_args):
app.logger.info("Geometry imported correctly.")
else:
app = pyaedt.Desktop(
- new_desktop_session=False,
- specified_version=version,
+ new_desktop=False,
+ version=version,
port=port,
aedt_process_id=aedt_process_id,
student_version=is_student,
diff --git a/pyaedt/workflows/project/toolkits_catalog.toml b/pyaedt/workflows/project/toolkits_catalog.toml
index 60ece1bdd81..6974adca284 100644
--- a/pyaedt/workflows/project/toolkits_catalog.toml
+++ b/pyaedt/workflows/project/toolkits_catalog.toml
@@ -11,3 +11,17 @@ script = "import_nastran.py"
icon = "images/large/cad3d.png"
template = "run_pyaedt_toolkit_script"
pip = ""
+
+[ConfigureEdb]
+name = "Configure layout"
+script = "configure_edb.py"
+icon = "images/large/aedb.png"
+template = "run_pyedb_toolkit_script"
+pip = ""
+
+[FieldsCalculator]
+name = "Advanced Fields Calculator"
+script = "advanced_fields_calculator.py"
+icon = "images/large/fields.png"
+template = "run_pyaedt_toolkit_script"
+pip = ""
diff --git a/pyaedt/workflows/q2d/__init__.py b/pyaedt/workflows/q2d/__init__.py
index 3bc3c8e5b19..f10103137e9 100644
--- a/pyaedt/workflows/q2d/__init__.py
+++ b/pyaedt/workflows/q2d/__init__.py
@@ -1,6 +1,7 @@
-# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates.
-# SPDX-License-Identifier: MIT
+# -*- coding: utf-8 -*-
#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
diff --git a/pyaedt/workflows/q3d/__init__.py b/pyaedt/workflows/q3d/__init__.py
index 3bc3c8e5b19..f10103137e9 100644
--- a/pyaedt/workflows/q3d/__init__.py
+++ b/pyaedt/workflows/q3d/__init__.py
@@ -1,6 +1,7 @@
-# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates.
-# SPDX-License-Identifier: MIT
+# -*- coding: utf-8 -*-
#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
diff --git a/pyaedt/workflows/templates/__init__.py b/pyaedt/workflows/templates/__init__.py
index 3bc3c8e5b19..f10103137e9 100644
--- a/pyaedt/workflows/templates/__init__.py
+++ b/pyaedt/workflows/templates/__init__.py
@@ -1,6 +1,7 @@
-# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates.
-# SPDX-License-Identifier: MIT
+# -*- coding: utf-8 -*-
#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
diff --git a/pyaedt/workflows/templates/extension_template.py b/pyaedt/workflows/templates/extension_template.py
index 81beff8b5ae..7cfb4586fbf 100644
--- a/pyaedt/workflows/templates/extension_template.py
+++ b/pyaedt/workflows/templates/extension_template.py
@@ -1,6 +1,7 @@
-# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates.
-# SPDX-License-Identifier: MIT
+# -*- coding: utf-8 -*-
#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
@@ -42,8 +43,8 @@
def main(extension_args):
app = pyaedt.Desktop(
- new_desktop_session=False,
- specified_version=version,
+ new_desktop=False,
+ version=version,
port=port,
aedt_process_id=aedt_process_id,
student_version=is_student,
diff --git a/pyaedt/workflows/templates/pyaedt_utils.py b/pyaedt/workflows/templates/pyaedt_utils.py
index 7e26a366cf0..108b8f7941f 100644
--- a/pyaedt/workflows/templates/pyaedt_utils.py
+++ b/pyaedt/workflows/templates/pyaedt_utils.py
@@ -1,6 +1,7 @@
-# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates.
-# SPDX-License-Identifier: MIT
+# -*- coding: utf-8 -*-
#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
diff --git a/pyaedt/workflows/templates/run_pyedb_toolkit_script.py_build b/pyaedt/workflows/templates/run_pyedb_toolkit_script.py_build
new file mode 100644
index 00000000000..37ac2d0db09
--- /dev/null
+++ b/pyaedt/workflows/templates/run_pyedb_toolkit_script.py_build
@@ -0,0 +1,76 @@
+# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
+#
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+"""
+* * * This script is meant to run in IronPython within AEDT. * * *
+
+The script executes the PyAEDT workflow.
+
+"""
+import os
+import sys
+
+is_linux = os.name == "posix"
+
+if is_linux:
+ import subprocessdotnet as subprocess
+else:
+ import subprocess
+
+toolkits_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))
+
+sys.path.append(toolkits_dir)
+
+import pyaedt_utils
+
+
+def main():
+ try:
+ # Get AEDT version
+ short_version = oDesktop.GetVersion()[2:6].replace(".", "")
+ oDesktop.AddMessage("", "", 0, "Toolkit launched. Wait.")
+ # CPython interpreter
+ python_exe = r"##PYTHON_EXE##"
+ # Python script
+ pyaedt_script = r"##PYTHON_SCRIPT##"
+ # Check if CPython interpreter and AEDT release match
+ python_exe = pyaedt_utils.sanitize_interpreter_path(python_exe, short_version)
+ # Check python executable
+ python_exe_flag = pyaedt_utils.check_file(python_exe, oDesktop)
+ if not python_exe_flag:
+ return
+ # Check script file
+ pyaedt_script_flag = pyaedt_utils.check_file(pyaedt_script, oDesktop)
+ if not pyaedt_script_flag:
+ return
+ # Add environment variables
+ pyaedt_utils.environment_variables(oDesktop)
+ # Run workflow
+ my_env = dict(os.environ.copy())
+ command = [python_exe, pyaedt_script]
+ subprocess.Popen(command, env=my_env)
+ except Exception as e:
+ pyaedt_utils.show_error(str(e), oDesktop)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/pyaedt/workflows/twinbuilder/__init__.py b/pyaedt/workflows/twinbuilder/__init__.py
index 3bc3c8e5b19..f10103137e9 100644
--- a/pyaedt/workflows/twinbuilder/__init__.py
+++ b/pyaedt/workflows/twinbuilder/__init__.py
@@ -1,6 +1,7 @@
-# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates.
-# SPDX-License-Identifier: MIT
+# -*- coding: utf-8 -*-
#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
diff --git a/pyaedt/workflows/twinbuilder/convert_to_circuit.py b/pyaedt/workflows/twinbuilder/convert_to_circuit.py
index 1a1aa2e9b51..2a7e2c6d255 100644
--- a/pyaedt/workflows/twinbuilder/convert_to_circuit.py
+++ b/pyaedt/workflows/twinbuilder/convert_to_circuit.py
@@ -1,6 +1,7 @@
-# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates.
-# SPDX-License-Identifier: MIT
+# -*- coding: utf-8 -*-
#
+# Copyright (C) 2021 - 2024 ANSYS, Inc. and/or its affiliates.
+# SPDX-License-Identifier: MIT
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
@@ -25,8 +26,8 @@
import sys
import pyaedt
-from pyaedt import is_linux
from pyaedt.generic.general_methods import read_toml
+from pyaedt.generic.settings import is_linux
import pyaedt.workflows
from pyaedt.workflows.misc import get_aedt_version
from pyaedt.workflows.misc import get_arguments
@@ -47,8 +48,8 @@
def main(extension_args):
app = pyaedt.Desktop(
- new_desktop_session=False,
- specified_version=version,
+ new_desktop=False,
+ version=version,
port=port,
aedt_process_id=aedt_process_id,
student_version=is_student,
@@ -67,14 +68,14 @@ def main(extension_args):
if active_design.GetDesignType() in ["Twin Builder"]:
design_name = active_design.GetName().split(";")[1]
- tb = pyaedt.TwinBuilder(designname=design_name, projectname=project_name)
+ tb = pyaedt.TwinBuilder(design=design_name, project=project_name)
else: # pragma: no cover
app.logger.error("An active TwinBuilder Design is needed.")
sys.exit()
catalog = read_toml(os.path.join(pyaedt.__path__[0], "misc", "tb_nexxim_mapping.toml"))
scale = catalog["General"]["scale"]
- cir = pyaedt.Circuit(designname=tb.design_name + "_Translated")
+ cir = pyaedt.Circuit(design=tb.design_name + "_Translated")
from pyaedt.generic.constants import unit_converter
diff --git a/pyproject.toml b/pyproject.toml
index 65ff3a1b2b1..9b165f845ab 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -26,9 +26,8 @@ classifiers = [
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
- "Topic :: Scientific/Engineering :: Libraries",
- "Topic :: Scientific/Engineering :: Scientific/Engineering",
- "Topic :: Scientific/Engineering :: Scientific/Engineering :: Electronic Design Automation (EDA)",
+ "Topic :: Software Development :: Libraries",
+ "Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)",
"Topic :: Scientific/Engineering :: Information Analysis",
# Additional specific classifiers
"Operating System :: OS Independent",
@@ -39,7 +38,7 @@ dependencies = [
"jsonschema",
"psutil",
"pyedb>=0.4.0",
- "pytomlpp; python_version < '3.12'",
+ "pytomlpp",
"rpyc>=6.0.0,<6.1",
]
@@ -60,10 +59,10 @@ tests = [
"pyvista>=0.38.0,<0.44",
# Never directly imported but required when loading ML related file see #4713
"scikit-learn>=1.0.0,<1.6",
- "scikit-rf>=0.30.0,<1.1",
+ "scikit-rf>=0.30.0,<1.2",
"SRTM.py",
"utm",
- "vtk==9.2.6",
+ "vtk==9.2.6; python_version < '3.12'",
]
dotnet = [
"ansys-pythonnet>=3.1.0rc3",
@@ -90,7 +89,7 @@ doc = [
#"pytest-sphinx",
"pyvista>=0.38.0,<0.44",
"recommonmark",
- "scikit-rf>=0.30.0,<1.1",
+ "scikit-rf>=0.30.0,<1.2",
"Sphinx==5.3.0; python_version == '3.7'",
"Sphinx>=7.1.0,<7.4; python_version > '3.7'",
"sphinx-autobuild==2021.3.14; python_version == '3.7'",
@@ -104,7 +103,7 @@ doc = [
#"sphinxcontrib-websupport",
"SRTM.py",
"utm",
- "vtk==9.2.6",
+ "vtk==9.2.6; python_version < '3.12'",
]
doc-no-examples = [
"ansys-sphinx-theme>=0.10.0,<0.17",
@@ -135,10 +134,10 @@ all = [
"fast-simplification>=0.1.7",
# Never directly imported but required when loading ML related file see #4713
"scikit-learn>=1.0.0,<1.6",
- "scikit-rf>=0.30.0,<1.1",
+ "scikit-rf>=0.30.0,<1.2",
"SRTM.py",
"utm",
- "vtk==9.2.6",
+ "vtk==9.2.6; python_version < '3.12'",
]
installer = [
"imageio>=2.30.0,<2.35",
@@ -150,10 +149,10 @@ installer = [
"pyvista>=0.38.0,<0.44",
# Never directly imported but required when loading ML related file see #4713
"scikit-learn>=1.0.0,<1.6",
- "scikit-rf>=0.30.0,<1.1",
+ "scikit-rf>=0.30.0,<1.2",
"SRTM.py",
"utm",
- "vtk==9.2.6",
+ "vtk==9.2.6; python_version < '3.12'",
"jupyterlab>=3.6.0,<4.3",
"ipython>=7.30.0,<8.26",
"ipyvtklink>=0.2.0,<0.2.4",
@@ -193,6 +192,7 @@ source = ["pyaedt"]
[tool.coverage.report]
show_missing = true
+omit = ["pyaedt/rpc/*.py"]
[tool.pytest.ini_options]
minversion = "7.1"