diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index 0e6a2fa85..01c86f885 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -19,6 +19,7 @@ env: PYAEDT_NON_GRAPHICAL: '1' # To keep as it impacts pyaedt behavior PYAEDT_DOC_GENERATION: '1' + SPHINXBUILD_HTML_AND_PDF_WORKFLOW: '1' concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -41,6 +42,8 @@ jobs: doc-build: name: Build documentation runs-on: [self-hosted, Windows, pyaedt-examples] + env: + FORCE_COLOR: '1' steps: - uses: actions/checkout@v4 @@ -62,13 +65,11 @@ jobs: .venv\Scripts\Activate.ps1 pip install --no-cache-dir -r requirements/requirements_doc.txt - # Use environment variable speed up build for PDF pages - name: Create HTML documentation - env: - SPHINXBUILD_HTML_AND_PDF_WORKFLOW: "1" run: | .venv\Scripts\Activate.ps1 . .\doc\make.bat html --color + . .\doc\make.bat pdf # NOTE: Ugly HTML checking but redirecting errors with our docs either leads # to errors in powershell or workflows getting stuck in Github CICD. @@ -81,6 +82,12 @@ jobs: exit 1 } + - name: Create HTML documentation + run: | + .venv\Scripts\Activate.ps1 + . .\doc\make.bat html --color + . .\doc\make.bat pdf + - name: Upload HTML documentation artifact uses: actions/upload-artifact@v4 with: @@ -88,15 +95,6 @@ jobs: path: doc/_build/html retention-days: 7 - # Use environment variable to remove the doctree after the build of PDF pages - # Keeping doctree could cause an issue, see https://github.com/ansys/pyaedt/pull/3844/files - - name: Create PDF documentation - env: - SPHINXBUILD_HTML_AND_PDF_WORKFLOW: "1" - run: | - .venv\Scripts\Activate.ps1 - . .\doc\make.bat pdf - - name: Upload PDF documentation artifact uses: actions/upload-artifact@v4 with: diff --git a/doc/make.bat b/doc/make.bat index a153eb9d5..288d623d6 100644 --- a/doc/make.bat +++ b/doc/make.bat @@ -5,7 +5,7 @@ pushd %~dp0 REM Command file for Sphinx documentation if "%SPHINXOPTS%" == "" ( - set SPHINXOPTS=-j auto --color + set SPHINXOPTS=-j auto --color -W -v ) if "%SPHINXBUILD%" == "" ( set SPHINXBUILD=sphinx-build diff --git a/doc/source/conf.py b/doc/source/conf.py index e445672ba..3ec31636e 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -113,7 +113,7 @@ def copy_examples_structure(app: Sphinx, config: Config): logger.info(f"Copy performed.") -def copy_script_examples(app: Sphinx, config: Config): +def copy_script_examples(app: Sphinx, exception: Exception | None): """Copy root directory examples script into Sphinx application out directory. This is required to allow users to download python scripts in the admonition. @@ -125,15 +125,18 @@ def copy_script_examples(app: Sphinx, config: Config): config : sphinx.config.Config Configuration file abstraction. """ - destination_dir = Path(app.outdir, "examples").resolve() - logger.info(f"Copying script examples into out directory {destination_dir}.") + if exception is None: + destination_dir = Path(app.outdir, "examples").resolve() + logger.info(f"Copying script examples into out directory {destination_dir}.") - EXAMPLES = EXAMPLES_DIRECTORY.glob("**/*.py") - for example in EXAMPLES: - example_path = str(example).split("examples" + os.sep)[-1] - shutil.copyfile(example, str(destination_dir / example_path)) + EXAMPLES = EXAMPLES_DIRECTORY.glob("**/*.py") + for example in EXAMPLES: + example_path = str(example).split("examples" + os.sep)[-1] + shutil.copyfile(example, str(destination_dir / example_path)) - logger.info(f"Copy performed.") + logger.info(f"Copy performed.") + else: + logger.warning(f"An exception occured. Skipping copy_script_examples.") def adjust_image_path(app: Sphinx, docname, source): diff --git a/doc/source/index.rst b/doc/source/index.rst index 530d829e0..79a0715f8 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -70,7 +70,7 @@ This repository contains end-to-end embedding examples that demonstrate how to u :link-type: doc .. image:: examples/electrothermal/_static/icepak_logo.png - :alt: Icepak + :alt: icepak :width: 250px :height: 200px :align: center diff --git a/examples/aedt/_static/aedt.png b/examples/aedt/_static/aedt.png deleted file mode 100644 index e7213e3e4..000000000 Binary files a/examples/aedt/_static/aedt.png and /dev/null differ diff --git a/examples/aedt/circuit/index.rst b/examples/aedt/circuit/index.rst deleted file mode 100644 index 942ec13ac..000000000 --- a/examples/aedt/circuit/index.rst +++ /dev/null @@ -1,122 +0,0 @@ -Circuit -~~~~~~~ - -These examples use PyAEDT to show Circuit capabilities. - - .. grid-item-card:: Circuit schematic creation and analysis - :padding: 2 2 2 2 - :link: ../../aedt_general/modeler/circuit_schematic - :link-type: doc - - .. image:: ../../aedt_general/modeler/_static/circuit.png - :alt: Circuit - :width: 250px - :height: 200px - :align: center - - This example shows how to build a circuit schematic and run a transient circuit simulation. - - .. grid-item-card:: Circuit Netlist to Schematic - :padding: 2 2 2 2 - :link: ../../aedt_general/modeler/netlist_to_schematic - :link-type: doc - - .. image:: ../../aedt_general/modeler/_static/netlist.png - :alt: Netlist - :width: 250px - :height: 250px - :align: center - - This example shows how to build a circuit schematic and run a transient circuit simulation. - - .. grid-item-card:: Automatic report creation - :padding: 2 2 2 2 - :link: ../../aedt_general/report/automatic_report - :link-type: doc - - .. image:: ../../aedt_general/report/_static/automatic_report.png - :alt: Automatic report - :width: 250px - :height: 200px - :align: center - - This example shows how to create reports from a JSON template file. - - .. grid-item-card:: PCIE virtual compliance - :padding: 2 2 2 2 - :link: ../../aedt_general/report/virtual_compliance - :link-type: doc - - .. image:: ../../aedt_general/report/_static/virtual_compliance_eye.png - :alt: Virtual compliance - :width: 250px - :height: 200px - :align: center - - This example shows how to generate a compliance report in PyAEDT using the VirtualCompliance class. - - .. grid-item-card:: Schematic subcircuit management - :padding: 2 2 2 2 - :link: ../../high_frequency/emc/subcircuit - :link-type: doc - - .. image:: ../../high_frequency/emc/_static/subcircuit.png - :alt: Cable - :width: 250px - :height: 200px - :align: center - - This example shows how to add a subcircuit to a circuit design. - It changes the focus within the hierarchy between the child subcircuit and the parent design. - - .. grid-item-card:: AMI Postprocessing - :padding: 2 2 2 2 - :link: ../../high_frequency/layout/signal_integrity/ami - :link-type: doc - - .. image:: ../../high_frequency/layout/signal_integrity/_static/ami.png - :alt: AMI - :width: 250px - :height: 200px - :align: center - - This example demonstrates advanced postprocessing of AMI simulations. - - .. grid-item-card:: Multi-zone simulation with SIwave - :padding: 2 2 2 2 - :link: ../../high_frequency/layout/signal_integrity/multizone - :link-type: doc - - .. image:: ../../high_frequency/layout/signal_integrity/_static/multizone.png - :alt: Multizone - :width: 250px - :height: 200px - :align: center - - This example shows how to simulate multiple zones with SIwave. - - .. grid-item-card:: Circuit transient analysis and eye diagram - :padding: 2 2 2 2 - :link: ../../high_frequency/layout/signal_integrity/circuit_transient - :link-type: doc - - .. image:: ../../high_frequency/layout/signal_integrity/_static/circuit_transient.png - :alt: Circuit transient - :width: 250px - :height: 200px - :align: center - - This example shows how to create a circuit design, run a Nexxim time-domain simulation, and create an eye diagram. - - - .. toctree:: - :hidden: - - ../../aedt_general/modeler/circuit_schematic - ../../aedt_general/modeler/netlist_to_schematic - ../../aedt_general/report/automatic_report - ../../aedt_general/report/virtual_compliance - ../../high_frequency/emc/subcircuit.py - ../../high_frequency/layout/signal_integrity/ami - ../../high_frequency/layout/signal_integrity/multizone - ../../high_frequency/layout/signal_integrity/circuit_transient diff --git a/examples/aedt/emit/index.rst b/examples/aedt/emit/index.rst deleted file mode 100644 index 11ff2bd90..000000000 --- a/examples/aedt/emit/index.rst +++ /dev/null @@ -1,82 +0,0 @@ -EMIT -~~~~ - -These examples use PyAEDT to show EMIT capabilities. - -.. grid:: 2 - - .. grid-item-card:: Antenna - :padding: 2 2 2 2 - :link: ../../high_frequency/antenna/interferences/antenna - :link-type: doc - - .. image:: ../../high_frequency/antenna/interferences/_static/emit.png - :alt: Antenna - :width: 250px - :height: 200px - :align: center - - This example shows how to create a project in EMIT for the simulation of an antenna using HFSS. - - .. grid-item-card:: HFSS to EMIT coupling - :padding: 2 2 2 2 - :link: ../../high_frequency/antenna/interferences/hfss_emit - :link-type: doc - - .. image:: ../../high_frequency/antenna/interferences/_static/emit_hfss.png - :alt: EMIT HFSS - :width: 250px - :height: 200px - :align: center - - This example shows how to link an HFSS design to EMIT and model RF interference among various components. - - .. grid-item-card:: Interference type classification - :padding: 2 2 2 2 - :link: ../../high_frequency/antenna/interferences/interference - :link-type: doc - - .. image:: ../../high_frequency/antenna/interferences/_static/interference.png - :alt: EMIT HFSS - :width: 250px - :height: 200px - :align: center - - This example shows how to load an existing AEDT EMIT design and analyze the results to classify the worst-case interference. - - .. grid-item-card:: Compute receiver protection levels - :padding: 2 2 2 2 - :link: ../../high_frequency/antenna/interferences/interference_type - :link-type: doc - - .. image:: ../../high_frequency/antenna/interferences/_static/protection.png - :alt: EMIT protection - :width: 250px - :height: 200px - :align: center - - This example shows how to open an AEDT project with an EMIT design and analyze the results to determine if - the received power at the input to each receiver exceeds the specified protection levels. - - .. grid-item-card:: Interference type classification using a GUI - :padding: 2 2 2 2 - :link: ../../high_frequency/antenna/interferences/interference_type - :link-type: doc - - .. image:: ../../high_frequency/antenna/interferences/_static/interference_type.png - :alt: EMIT protection - :width: 250px - :height: 200px - :align: center - - This example uses a GUI to open an AEDT project with an EMIT design and analyze the results to classify - the worst-case interference. - - .. toctree:: - :hidden: - - ../../high_frequency/antenna/interferences/antenna - ../../high_frequency/antenna/interferences/hfss_emit - ../../high_frequency/antenna/interferences/interference - ../../high_frequency/antenna/interferences/protection - ../../high_frequency/antenna/interferences/interference_type diff --git a/examples/aedt/hfss/index.rst b/examples/aedt/hfss/index.rst deleted file mode 100644 index 77669165e..000000000 --- a/examples/aedt/hfss/index.rst +++ /dev/null @@ -1,250 +0,0 @@ -HFSS -~~~~ - -These examples use PyAEDT to show HFSS capabilities - -.. grid:: 2 - - .. grid-item-card:: Dipole antenna - :padding: 2 2 2 2 - :link: ../../high_frequency/antenna/dipole - :link-type: doc - - .. image:: ../../high_frequency/antenna/_static/dipole.png - :alt: Antenna - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create a dipole antenna in HFSS and postprocess results. - - .. grid-item-card:: Component antenna array - :padding: 2 2 2 2 - :link: ../../high_frequency/antenna/array - :link-type: doc - - .. image:: ../../high_frequency/antenna/_static/array.png - :alt: Antenna - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create an antenna array. - - .. grid-item-card:: Probe-fed patch antenna - :padding: 2 2 2 2 - :link: ../../high_frequency/antenna/patch - :link-type: doc - - .. image:: ../../high_frequency/antenna/_static/patch.png - :alt: Patch - :width: 250px - :height: 200px - :align: center - - This example shows how to use the Stackup3D class to create and analyze a patch antenna in HFSS. - - .. grid-item-card:: FSS unit cell simulation - :padding: 2 2 2 2 - :link: ../../high_frequency/antenna/fss_unitcell - :link-type: doc - - .. image:: ../../high_frequency/antenna/_static/unitcell.png - :alt: FSS - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to model and simulate a unit cell for a frequency-selective surface in HFSS. - - .. grid-item-card:: Geometry import from maps - :padding: 2 2 2 2 - :link: ../../high_frequency/antenna/large_scenarios/city - :link-type: doc - - .. image:: ../../high_frequency/antenna/large_scenarios/_static/city.png - :alt: City - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create an HFSS SBR+ project from OpenStreetMap. - - .. grid-item-card:: Doppler setup - :padding: 2 2 2 2 - :link: ../../high_frequency/antenna/large_scenarios/doppler - :link-type: doc - - .. image:: ../../high_frequency/antenna/large_scenarios/_static/doppler.png - :alt: Doppler - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create a multipart scenario in HFSS SBR+ and set up a doppler analysis. - - .. grid-item-card:: Reflector - :padding: 2 2 2 2 - :link: ../../high_frequency/antenna/large_scenarios/reflector - :link-type: doc - - .. image:: ../../high_frequency/antenna/large_scenarios/_static/reflector.png - :alt: Reflector - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create an HFSS SBR+ project from an HFSS antenna and run a simulation. - - .. grid-item-card:: HFSS to SBR+ time animation - :padding: 2 2 2 2 - :link: ../../high_frequency/antenna/large_scenarios/time_domain - :link-type: doc - - .. image:: ../../high_frequency/antenna/large_scenarios/_static/time_domain.png - :alt: SBR Time - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create an SBR+ time animation and save it to a GIF file. - - .. grid-item-card:: Choke - :padding: 2 2 2 2 - :link: ../../high_frequency/emc/choke - :link-type: doc - - .. image:: ../../high_frequency/emc/_static/choke.png - :alt: Choke - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create a choke setup in HFSS. - - .. grid-item-card:: Eigenmode filter - :padding: 2 2 2 2 - :link: ../../high_frequency/emc/eigenmode - :link-type: doc - - .. image:: ../../high_frequency/emc/_static/eigenmode.png - :alt: Eigenmode - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to automate the Eigenmode solver in HFSS. - - .. grid-item-card:: Flex cable CPWG - :padding: 2 2 2 2 - :link: ../../high_frequency/emc/flex_cable - :link-type: doc - - .. image:: ../../high_frequency/emc/_static/flex_cable.png - :alt: Flex cable - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create a flex cable CPWG (coplanar waveguide with ground). - - .. grid-item-card:: HFSS-Mechanical MRI analysis - :padding: 2 2 2 2 - :link: ../../high_frequency/multiphysics/mri - :link-type: doc - - .. image:: ../../high_frequency/multiphysics/_static/mri.png - :alt: MRI - :width: 250px - :height: 200px - :align: center - - This example uses a coil tuned to 63.8 MHz to determine the temperature rise in a gel phantom near - an implant given a background SAR of 1 W/kg. - - .. grid-item-card:: HFSS-Mechanical multiphysics analysis - :padding: 2 2 2 2 - :link: ../../high_frequency/multiphysics/hfss_mechanical - :link-type: doc - - .. image:: ../../high_frequency/multiphysics/_static/hfss_mechanical.png - :alt: HFSS Mechanical - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create a multiphysics workflow that includes Circuit, HFSS, and Mechanical. - - .. grid-item-card:: Inductive iris waveguide filter - :padding: 2 2 2 2 - :link: ../../high_frequency/radiofrequency_mmwave/iris_filter - :link-type: doc - - .. image:: ../../high_frequency/radiofrequency_mmwave/_static/wgf.png - :alt: Waveguide filter - :width: 250px - :height: 200px - :align: center - - This example shows how to build and analyze a four-pole X-Band waveguide filter using inductive irises. - - .. grid-item-card:: Spiral inductor - :padding: 2 2 2 2 - :link: ../../high_frequency/radiofrequency_mmwave/spiral - :link-type: doc - - .. image:: ../../high_frequency/radiofrequency_mmwave/_static/spiral.png - :alt: Spiral - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create a spiral inductor, solve it, and plot results. - - .. grid-item-card:: Coaxial - :padding: 2 2 2 2 - :link: ../../electrothermal/ccoaxial_hfss_icepak - :link-type: doc - - .. image:: ../../electrothermal/_static/coaxial.png - :alt: Coaxial - :width: 250px - :height: 200px - :align: center - - This example shows how to create a project from scratch in HFSS and Icepak. - - .. grid-item-card:: Circuit-HFSS-Icepak coupling workflow - :padding: 2 2 2 2 - :link: ../../electrothermal/icepak_circuit_hfss_coupling - :link-type: doc - - .. image:: ../../electrothermal/_static/ring.png - :alt: Ring - :width: 250px - :height: 200px - :align: center - - This example shows how to create a two-way coupling between HFSS and Icepak. - - - .. toctree:: - :hidden: - - ../../high_frequency/antenna/array - ../../high_frequency/antenna/dipole - ../../high_frequency/antenna/fss_unitcell - ../../high_frequency/antenna/patch - ../../high_frequency/antenna/large_scenarios/city - ../../high_frequency/antenna/large_scenarios/doppler - ../../high_frequency/antenna/large_scenarios/reflector - ../../high_frequency/antenna/large_scenarios/time_domain - ../../high_frequency/emc/choke - ../../high_frequency/emc/eigenmode - ../../high_frequency/emc/flex_cable.py - ../../high_frequency/multiphysics/hfss_mechanical - ../../high_frequency/multiphysics/mri - ../../high_frequency/radiofrequency_mmwave/iris_filter - ../../high_frequency/radiofrequency_mmwave/spiral - ../../electrothermal/coaxial_hfss_icepak - ../../electrothermal/icepak_circuit_hfss_coupling diff --git a/examples/aedt/hfss_3d_layout/index.rst b/examples/aedt/hfss_3d_layout/index.rst deleted file mode 100644 index 481e34ef4..000000000 --- a/examples/aedt/hfss_3d_layout/index.rst +++ /dev/null @@ -1,82 +0,0 @@ -HFSS 3D Layout -~~~~~~~~~~~~~~ - -These examples use PyAEDT to show HFSS 3D Layout capabilities. - -.. grid:: 2 - - .. grid-item-card:: Power integrity analysis - :padding: 2 2 2 2 - :link: ../../high_frequency/layout/power_integrity/power_integrity - :link-type: doc - - .. image:: ../../high_frequency/layout/power_integrity/_static/power_integrity.png - :alt: Power integrity - :width: 250px - :height: 200px - :align: center - - This example shows how to use the Ansys Electronics Database (EDB) for power integrity analysis. - - .. grid-item-card:: DC IR analysis - :padding: 2 2 2 2 - :link: ../../high_frequency/layout/power_integrity/dcir - :link-type: doc - - .. image:: ../../high_frequency/layout/power_integrity/_static/dcir.png - :alt: DCIR - :width: 250px - :height: 200px - :align: center - - This example shows how to configure EDB for DC IR analysis and load EDB into the HFSS 3D Layout UI for analysis - and postprocessing. - - .. grid-item-card:: Pre-layout signal integrity - :padding: 2 2 2 2 - :link: ../../high_frequency/layout/signal_integrity/pre_layout - :link-type: doc - - .. image:: ../../high_frequency/layout/signal_integrity/_static/pre_layout_sma_connector_on_pcb.png - :alt: Pre layout connector - :width: 250px - :height: 200px - :align: center - - This example shows how to create a parameterized layout design and load the layout into HFSS 3D Layout - for analysis and postprocessing. - - .. grid-item-card:: Pre-layout Parameterized PCB - :padding: 2 2 2 2 - :link: ../../high_frequency/layout/signal_integrity/pre_layout_parametrized - :link-type: doc - - .. image:: ../../high_frequency/layout/signal_integrity/_static/pre_layout_parameterized_pcb.png - :alt: Pre layout parametrized - :width: 250px - :height: 200px - :align: center - - This example shows how to use the EDB interface along with HFSS 3D Layout to create and solve a parameterized layout. - - .. grid-item-card:: HFSS 3D Layout GUI modificatation - :padding: 2 2 2 2 - :link: ../../high_frequency/layout/gui_manipulation - :link-type: doc - - .. image:: ../../high_frequency/layout/_static/user_interface.png - :alt: UI 3D Layout - :width: 250px - :height: 200px - :align: center - - Provides HFSS 3D Layout GUI modification examples. - - .. toctree:: - :hidden: - - ../../high_frequency/layout/power_integrity/power_integrity - ../../high_frequency/layout/power_integrity/dcir - ../../high_frequency/layout/signal_integrity/pre_layout - ../../high_frequency/layout/signal_integrity/pre_layout_parametrized - ../../high_frequency/layout/gui_manipulation diff --git a/examples/aedt/icepak/index.rst b/examples/aedt/icepak/index.rst deleted file mode 100644 index 622602bc0..000000000 --- a/examples/aedt/icepak/index.rst +++ /dev/null @@ -1,148 +0,0 @@ -Icepak -~~~~~~ - -These examples use PyAEDT to show Icepak capabilities. - -.. grid:: 2 - - .. grid-item-card:: PCB component definition from CSV file and model image exports - :padding: 2 2 2 2 - :link: ../../electrothermal/components_csv - :link-type: doc - - .. image:: ../../electrothermal/_static/icepak_csv.png - :alt: Icepak CSV - :width: 250px - :height: 200px - :align: center - - This example shows how to create different types of blocks and assign power and material to them using a CSV input file. - - - .. grid-item-card:: Import of a PCB and its components via IDF and EDB - :padding: 2 2 2 2 - :link: ../../electrothermal/ecad_import - :link-type: doc - - .. image:: ../../electrothermal/_static/ecad.png - :alt: Icepak ECAD - :width: 250px - :height: 200px - :align: center - - This example shows how to import a PCB and its components using IDF files (LDB and BDF). - You can also use a combination of EMN and EMP files in a similar way. - - - .. grid-item-card:: Thermal analysis with 3D components - :padding: 2 2 2 2 - :link: ../../electrothermal/component_3d - :link-type: doc - - .. image:: ../../electrothermal/_static/component.png - :alt: Thermal component - :width: 250px - :height: 200px - :align: center - - This example shows how to create a thermal analysis of an electronic package by taking advantage of 3D components with advanced features added by PyAEDT. - - - .. grid-item-card:: Graphic card thermal analysis - :padding: 2 2 2 2 - :link: ../../electrothermal/graphic_card - :link-type: doc - - .. image:: ../../electrothermal/_static/graphic.png - :alt: Graphic card - :width: 250px - :height: 200px - :align: center - - This example shows how to use pyAEDT to create a graphic card setup in Icepak and postprocess the results. - The example file is an Icepak project with a model that is already created and has materials assigned. - - - .. grid-item-card:: Coaxial - :padding: 2 2 2 2 - :link: ../../electrothermal/coaxial_hfss_icepak - :link-type: doc - - .. image:: ../../electrothermal/_static/coaxial.png - :alt: Coaxial - :width: 250px - :height: 200px - :align: center - - This example shows how to create a project from scratch in HFSS and Icepak. - - - .. grid-item-card:: Setup from Sherlock inputs - :padding: 2 2 2 2 - :link: ../../electrothermal/sherlock - :link-type: doc - - .. image:: ../../electrothermal/_static/sherlock.png - :alt: PyAEDT logo - :width: 250px - :height: 200px - :align: center - - This example shows how to create an Icepak project from Sherlock files (STEP and CSV) and an AEDB board. - - .. grid-item-card:: Circuit-HFSS-Icepak coupling workflow - :padding: 2 2 2 2 - :link: ../../electrothermal/icepak_circuit_hfss_coupling - :link-type: doc - - .. image:: ../../electrothermal/_static/ring.png - :alt: Ring - :width: 250px - :height: 200px - :align: center - - This example shows how to create a two-way coupling between HFSS and Icepak. - - - .. grid-item-card:: Electrothermal analysis - :padding: 2 2 2 2 - :link: ../../electrothermal/electrothermal - :link-type: doc - - .. image:: ../../electrothermal/_static/electrothermal.png - :alt: Electrothermal - :width: 250px - :height: 200px - :align: center - - This example shows how to use the EDB for DC IR analysis and electrothermal analysis. - The EDB is loaded into SIwave for analysis and postprocessing. - In the end, an Icepak project is exported from SIwave. - - - .. grid-item-card:: Maxwell 3D-Icepak electrothermal analysis - :padding: 2 2 2 2 - :link: ../../low_frequency/multiphysics/maxwell_icepak - :link-type: doc - - .. image:: ../../low_frequency/multiphysics/_static/charging.png - :alt: Charging - :width: 250px - :height: 200px - :align: center - - This example uses PyAEDT to set up a simple Maxwell design consisting of a coil and a ferrite core. - - - .. toctree:: - :hidden: - - ../../electrothermal/components_csv - ../../electrothermal/ecad_import - ../../electrothermal/component_3d - ../../electrothermal/graphic_card - ../../electrothermal/coaxial_hfss_icepak - ../../electrothermal/sherlock - ../../electrothermal/icepak_circuit_hfss_coupling - ../../electrothermal/electrothermal - ../../low_frequency/multiphysics/maxwell_icepak diff --git a/examples/aedt/index.rst b/examples/aedt/index.rst deleted file mode 100644 index fb6fb4d59..000000000 --- a/examples/aedt/index.rst +++ /dev/null @@ -1,77 +0,0 @@ -Examples by AEDT application -============================ - -These examples are groped by AEDT applications. - - -.. grid:: 2 - - .. grid-item-card:: HFSS - :padding: 2 2 2 2 - :link: hfss/index - :link-type: doc - - HFSS examples - - .. grid-item-card:: Maxwell 3D - :padding: 2 2 2 2 - :link: maxwell_3d/index - :link-type: doc - - Maxwell 3D examples - - .. grid-item-card:: Maxwell 2D - :padding: 2 2 2 2 - :link: maxwell_2d/index - :link-type: doc - - Maxwell 2D examples - - .. grid-item-card:: Icepak - :padding: 2 2 2 2 - :link: icepak/index - :link-type: doc - - Icepak examples - - .. grid-item-card:: HFSS 3D Layout - :padding: 2 2 2 2 - :link: hfss_3d_layout/index - :link-type: doc - - HFSS 3D Layout examples - - .. grid-item-card:: Q3D and 2D Extractor - :padding: 2 2 2 2 - :link: q3d_q2d/index - :link-type: doc - - Q3D and 2D Extractor examples - - .. grid-item-card:: Circuit - :padding: 2 2 2 2 - :link: circuit/index - :link-type: doc - - Circuit examples - - .. grid-item-card:: EMIT - :padding: 2 2 2 2 - :link: emit/index - :link-type: doc - - EMIT examples - - .. grid-item-card:: Twin Builder - :padding: 2 2 2 2 - :link: twin_builder/index - :link-type: doc - - Twin Builder examples - - .. grid-item-card:: Miscellaneous - :padding: 2 2 2 2 - :link: misc/index - :link-type: doc - - Miscellaneous examples \ No newline at end of file diff --git a/examples/aedt/maxwell_2d/index.rst b/examples/aedt/maxwell_2d/index.rst deleted file mode 100644 index 37a785a4e..000000000 --- a/examples/aedt/maxwell_2d/index.rst +++ /dev/null @@ -1,167 +0,0 @@ -Maxwell 2D -~~~~~~~~~~ - -These examples use PyAEDT to show Maxwell 2D capabilities. - -.. grid:: 2 - - .. grid-item-card:: Control program enablement - :padding: 2 2 2 2 - :link: ../../low_frequency/general/control_program - :link-type: doc - - .. image:: ../../low_frequency/general/_static/control_program.png - :alt: Maxwell general - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to enable a control program in a Maxwell 2D project. - - .. grid-item-card:: Resistance calculation - :padding: 2 2 2 2 - :link: ../../low_frequency/general/resistance - :link-type: doc - - .. image:: ../../low_frequency/general/_static/resistance.png - :alt: Maxwell resistance - :width: 250px - :height: 200px - :align: center - - This example uses PyAEDT to set up a resistance calculation and solve it using the Maxwell 2D DCConduction solver. - - - .. grid-item-card:: Eddy current analysis and reduced matrix - :padding: 2 2 2 2 - :link: ../../low_frequency/general/eddy_current - :link-type: doc - - .. image:: ../../low_frequency/general/_static/eddy_current.png - :alt: Maxwell Eddy current - :width: 250px - :height: 200px - :align: center - - This example shows how to leverage PyAEDT to assign a matrix and perform series or parallel connections in a Maxwell 2D design. - - - .. grid-item-card:: Electrostatic analysis - :padding: 2 2 2 2 - :link: ../../low_frequency/general/electrostatic - :link-type: doc - - .. image:: ../../low_frequency/general/_static/electrostatic.png - :alt: Maxwell electrostatic - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create a Maxwell 2D electrostatic analysis. - - - .. grid-item-card:: External delta circuit - :padding: 2 2 2 2 - :link: ../../low_frequency/general/external_circuit - :link-type: doc - - .. image:: ../../low_frequency/general/_static/external_circuit.png - :alt: External circuit - :width: 250px - :height: 200px - :align: center - - This example shows how to create an external delta circuit and connect it with a Maxwell 2D design. - - .. grid-item-card:: Magnetomotive force - :padding: 2 2 2 2 - :link: ../../low_frequency/magnetic/magneto_motive_line - :link-type: doc - - .. image:: ../../low_frequency/magnetic/_static/magneto.png - :alt: Maxwell magneto force - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to calculate the magnetomotive force. - - .. grid-item-card:: Transient winding analysis - :padding: 2 2 2 2 - :link: ../../low_frequency/magnetic/transient_winding - :link-type: doc - - .. image:: ../../low_frequency/magnetic/_static/transient.png - :alt: Maxwell transient - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create a project in Maxwell 2D and run a transient simulation. - - .. grid-item-card:: Lorentz actuator - :padding: 2 2 2 2 - :link: ../../low_frequency/magnetic/lorentz_actuator - :link-type: doc - - .. image:: ../../low_frequency/magnetic/_static/lorentz_actuator.png - :alt: Maxwell general - :width: 250px - :height: 200px - :align: center - - This example uses PyAEDT to set up a Lorentz actuator and solve it using the Maxwell 2D transient solver. - - .. grid-item-card:: PM synchronous motor transient analysis - :padding: 2 2 2 2 - :link: ../../low_frequency/motor/aedt_motor/pm_synchronous - :link-type: doc - - .. image:: ../../low_frequency/motor/aedt_motor/_static/pm_synchronous.png - :alt: Maxwell general - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create a Maxwell 2D transient analysis for an interior permanent magnet (PM) electric motor. - - .. grid-item-card:: Motor creation and export - :padding: 2 2 2 2 - :link: ../../low_frequency/motor/aedt_motor/rmxpert - :link-type: doc - - .. image:: ../../low_frequency/motor/aedt_motor/_static/rmxpert.png - :alt: Maxwell general - :width: 250px - :height: 200px - :align: center - - This example uses PyAEDT to create a RMxprt project and export it to Maxwell 2D. - - .. grid-item-card:: Transformer leakage inductance calculation - :padding: 2 2 2 2 - :link: ../../low_frequency/motor/aedt_motor/transformer_inductance - :link-type: doc - - .. image:: ../../low_frequency/motor/aedt_motor/_static/transformer2.png - :alt: Maxwell general - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create a Maxwell 2D magnetostatic analysis to calculate transformer leakage inductance and reactance. - - .. toctree:: - :hidden: - - ../../low_frequency/general/control_program - ../../low_frequency/general/resistance - ../../low_frequency/general/eddy_current - ../../low_frequency/general/electrostatic - ../../low_frequency/general/external_circuit - ../../low_frequency/magnetic/magneto_motive_line - ../../low_frequency/magnetic/transient_winding - ../../low_frequency/magnetic/lorentz_actuator - ../../low_frequency/motor/aedt_motor/pm_synchronous - ../../low_frequency/motor/aedt_motor/rmxpert - ../../low_frequency/motor/aedt_motor/transformer_inductance diff --git a/examples/aedt/maxwell_3d/index.rst b/examples/aedt/maxwell_3d/index.rst deleted file mode 100644 index 0d541b6f4..000000000 --- a/examples/aedt/maxwell_3d/index.rst +++ /dev/null @@ -1,126 +0,0 @@ -Maxwell 3D -~~~~~~~~~~ - -These examples use PyAEDT to show Maxwell 3D capabilities. - -.. grid:: 2 - - .. grid-item-card:: Electro DC analysis - :padding: 2 2 2 2 - :link: ../../low_frequency/general/dc_analysis - :link-type: doc - - .. image:: ../../low_frequency/general/_static/dc.png - :alt: Maxwell DC - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create a Maxwell DC analysis, compute mass center, and move coordinate systems. - - - .. grid-item-card:: Fields export in transient analysis - :padding: 2 2 2 2 - :link: ../../low_frequency/general/field_export - :link-type: doc - - .. image:: ../../low_frequency/general/_static/field.png - :alt: Maxwell field - :width: 250px - :height: 200px - :align: center - - This example shows how to leverage PyAEDT to set up a Maxwell 3D transient analysis and then - compute the average value of the current density field over a specific coil surface and the magnitude - of the current density field over all coil surfaces at each time step of the transient analysis. - - .. grid-item-card:: Choke setup - :padding: 2 2 2 2 - :link: ../../low_frequency/magnetic/choke - :link-type: doc - - .. image:: ../../low_frequency/magnetic/_static/choke.png - :alt: Maxwell choke - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create a choke setup in Maxwell 3D. - - .. grid-item-card:: Magnet segmentation - :padding: 2 2 2 2 - :link: ../../low_frequency/motor/aedt_motor/magnet_segmentation - :link-type: doc - - .. image:: ../../low_frequency/motor/aedt_motor/_static/magnet_segmentation.png - :alt: Maxwell general - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to segment magnets of an electric motor. The method is valid and usable for any object you would like to segment. - - .. grid-item-card:: Transformer - :padding: 2 2 2 2 - :link: ../../low_frequency/motor/aedt_motor/transformer - :link-type: doc - - .. image:: ../../low_frequency/motor/aedt_motor/_static/transformer.png - :alt: Maxwell general - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to set core loss given a set of power-volume [kw/m^3] curves at different frequencies. - - .. grid-item-card:: Maxwell 3D-Icepak electrothermal analysis - :padding: 2 2 2 2 - :link: ../../low_frequency/multiphysics/maxwell_icepak - :link-type: doc - - .. image:: ../../low_frequency/multiphysics/_static/charging.png - :alt: Charging - :width: 250px - :height: 200px - :align: center - - This example uses PyAEDT to set up a simple Maxwell design consisting of a coil and a ferrite core. - - .. grid-item-card:: Asymmetric conductor analysis - :padding: 2 2 2 2 - :link: ../../low_frequency/team_problem/asymmetric_conductor - :link-type: doc - - .. image:: ../../low_frequency/team_problem/_static/asymmetric_conductor.png - :alt: Asymmetric conductor - :width: 250px - :height: 200px - :align: center - - This example uses PyAEDT to set up the TEAM 7 problem for an asymmetric conductor with a hole and solve it using the Maxwell 3D eddy current solver. - - .. grid-item-card:: Bath plate analysis - :padding: 2 2 2 2 - :link: ../../low_frequency/team_problem/bath_plate - :link-type: doc - - .. image:: ../../low_frequency/team_problem/_static/bath.png - :alt: Bath - :width: 250px - :height: 200px - :align: center - - This example uses PyAEDT to set up the TEAM 3 bath plate problem and solve it using the Maxwell 3D eddy current solver. - - - .. toctree:: - :hidden: - - ../../low_frequency/general/dc_analysis - ../../low_frequency/general/field_export - ../../low_frequency/magnetic/choke - ../../low_frequency/motor/aedt_motor/magnet_segmentation - ../../low_frequency/motor/aedt_motor/transformer - ../../low_frequency/multiphysics/maxwell_icepak - ../../low_frequency/team_problem/asymmetric_conductor - ../../low_frequency/team_problem/bath_plate diff --git a/examples/aedt/misc/index.rst b/examples/aedt/misc/index.rst deleted file mode 100644 index d05564c73..000000000 --- a/examples/aedt/misc/index.rst +++ /dev/null @@ -1,53 +0,0 @@ -Miscellaneous -~~~~~~~~~~~~~ - -These examples use PyAEDT to show miscellaneous capabilities. - -.. grid:: 2 - - .. grid-item-card:: Touchstone files - :padding: 2 2 2 2 - :link: ../../aedt_general/report/touchstone_file - :link-type: doc - - .. image:: ../../aedt_general/report/_static/touchstone_skitrf.png - :alt: Touchstone file - :width: 250px - :height: 200px - :align: center - - This example shows how to use objects in a Touchstone file without opening AEDT. - - .. grid-item-card:: Channel Operating Margin (COM) - :padding: 2 2 2 2 - :link: ../../high_frequency/layout/signal_integrity/com_analysis - :link-type: doc - - .. image:: ../../high_frequency/layout/signal_integrity/_static/com_eye.png - :alt: COM - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT for COM analysis. - - .. grid-item-card:: Lumped element filter design - :padding: 2 2 2 2 - :link: ../../high_frequency/radiofrequency_mmwave/lumped_element - :link-type: doc - - .. image:: ../../high_frequency/radiofrequency_mmwave/_static/lumped_filter.png - :alt: Stripline - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to use the FilterSolutions module to design and visualize the frequency - response of a band-pass Butterworth filter. - - .. toctree:: - :hidden: - - ../../aedt_general/report/touchstone_file - ../../high_frequency/layout/signal_integrity/com_analysis - ../../high_frequency/radiofrequency_mmwave/lumped_element diff --git a/examples/aedt/q3d_q2d/index.rst b/examples/aedt/q3d_q2d/index.rst deleted file mode 100644 index 66c4792d3..000000000 --- a/examples/aedt/q3d_q2d/index.rst +++ /dev/null @@ -1,99 +0,0 @@ -Q2D-Q3D -~~~~~~~ - -These examples use PyAEDT to show Q3D and 2D Extractor capabilities. - -.. grid:: 2 - - .. grid-item-card:: Cable parameter identification - :padding: 2 2 2 2 - :link: ../../high_frequency/emc/armoured_cable - :link-type: doc - - .. image:: ../../high_frequency/emc/_static/armoured.png - :alt: Cable - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create see a 4 Core Armoured Power Cable. - - .. grid-item-card:: Busbar analysis - :padding: 2 2 2 2 - :link: ../../high_frequency/emc/busbar - :link-type: doc - - .. image:: ../../high_frequency/emc/_static/busbar.png - :alt: Busbar - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create a busbar design in Q3D Extractor and run a simulation. - - .. grid-item-card:: PCB DCIR analysis - :padding: 2 2 2 2 - :link: ../../high_frequency/layout//power_integrity/dcir_q3d - :link-type: doc - - .. image:: ../../high_frequency/layout//power_integrity/_static/dcir_q3d.png - :alt: DCIR - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create a design in Q3D Extractor and run a DC IR drop simulation starting - from an EDB project. - - .. grid-item-card:: PCB AC analysis - :padding: 2 2 2 2 - :link: ../../high_frequency/layout//power_integrity/ac_q3d - :link-type: doc - - .. image:: ../../high_frequency/layout//power_integrity/_static/ac_q3d.png - :alt: AC Q3D - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create a design in Q3D Extractor and run a simulation starting - from an EDB project. - - .. grid-item-card:: CPWG analysis - :padding: 2 2 2 2 - :link: ../../high_frequency/radiofrequency_mmwave/coplanar_waveguide - :link-type: doc - - .. image:: ../../high_frequency/radiofrequency_mmwave/_static/cpwg.png - :alt: CPWG - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create a CPWG (coplanar waveguide with ground) design in 2D Extractor and run a simulation. - - .. grid-item-card:: Stripline analysis - :padding: 2 2 2 2 - :link: ../../high_frequency/radiofrequency_mmwave/stripline - :link-type: doc - - .. image:: ../../high_frequency/radiofrequency_mmwave/_static/stripline.png - :alt: Stripline - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create a differential stripline design in 2D Extractor and run a simulation. - - - .. toctree:: - :hidden: - - ../../high_frequency/emc/armoured_cable - ../../high_frequency/emc/busbar - ../../high_frequency/layout//power_integrity/dcir_q3d - ../../high_frequency/layout/power_integrity/ac_q3d - ../../high_frequency/radiofrequency_mmwave/coplanar_waveguide - ../../high_frequency/radiofrequency_mmwave/stripline - - diff --git a/examples/aedt/twin_builder/index.rst b/examples/aedt/twin_builder/index.rst deleted file mode 100644 index cffa8161a..000000000 --- a/examples/aedt/twin_builder/index.rst +++ /dev/null @@ -1,82 +0,0 @@ -Twin Builder -~~~~~~~~~~~~ - -These examples use PyAEDT to show Twin Builder capabilities. - -.. grid:: 2 - - .. grid-item-card:: RC circuit design analysis - :padding: 2 2 2 2 - :link: ../../low_frequency/general/twin_builder/rc_circuit - :link-type: doc - - .. image:: ../../low_frequency/general/twin_builder/_static/rc.png - :alt: TB RC - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create a Twin Builder design and run a Twin Builder time-domain simulation. - - .. grid-item-card:: Wiring of a rectifier with a capacitor filter - :padding: 2 2 2 2 - :link: ../../low_frequency/general/twin_builder/rectifier - :link-type: doc - - .. image:: ../../low_frequency/general/twin_builder/_static/rectifier_response.png - :alt: TB Rectifier response - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create a Twin Builder design and run a Twin Builder time-domain simulation. - - - .. grid-item-card:: Static ROM - :padding: 2 2 2 2 - :link: ../../low_frequency/general/twin_builder/static_rom - :link-type: doc - - .. image:: ../../low_frequency/general/twin_builder/_static/static_rom.png - :alt: Static ROM - :width: 250px - :height: 200px - :align: center - - This example shows how to create a static reduced order model (ROM) in Twin Builder and run a transient simulation. - - .. grid-item-card:: Dynamic ROM - :padding: 2 2 2 2 - :link: ../../low_frequency/general/twin_builder/dynamic_rom - :link-type: doc - - .. image:: ../../low_frequency/general/twin_builder/_static/dynamic_rom_plot.png - :alt: Dynamic ROM plot - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create a dynamic reduced order model (ROM) in Twin Builder and run a Twin Builder time-domain simulation. - - .. grid-item-card:: LTI ROM - :padding: 2 2 2 2 - :link: ../../low_frequency/general/twin_builder/lti_rom_sml - :link-type: doc - - .. image:: ../../low_frequency/general/twin_builder/_static/lti_rom.png - :alt: LTI ROM plot - :width: 250px - :height: 200px - :align: center - - This example shows how you can use PyAEDT to create a Linear Time Invariant (LTI) ROM in Twin Builder - and run a Twin Builder time-domain simulation. - - .. toctree:: - :hidden: - - ../../low_frequency/general/twin_builder/dynamic_rom - ../../low_frequency/general/twin_builder/rc_circuit - ../../low_frequency/general/twin_builder/rectifier - ../../low_frequency/general/twin_builder/static_rom - ../../low_frequency/general/twin_builder/lti_rom_sml \ No newline at end of file diff --git a/examples/aedt_general/components/_static/component_3d.png b/examples/aedt_general/components/_static/component_3d.png deleted file mode 100644 index 1719286cc..000000000 Binary files a/examples/aedt_general/components/_static/component_3d.png and /dev/null differ diff --git a/examples/aedt_general/components/_static/e3dcomp.png b/examples/aedt_general/components/_static/e3dcomp.png deleted file mode 100644 index 37f678838..000000000 Binary files a/examples/aedt_general/components/_static/e3dcomp.png and /dev/null differ diff --git a/examples/aedt_general/components/component_conversion.py b/examples/aedt_general/components/component_conversion.py deleted file mode 100644 index abe8bf402..000000000 --- a/examples/aedt_general/components/component_conversion.py +++ /dev/null @@ -1,113 +0,0 @@ -# # Encrypted 3D component conversion -# -# This example shows how to convert an encrypted -# 3D component from ACIS to Parasolid in different AEDT releases. -# If you have models previous to Ansys AEDT 2023 R1 with an ACIS kernel, -# you can convert it to Parasolid. -# -# Keywords: **HFSS**, **Encrypted**, **3D component**, **Modeler kernel**. - -# - -# ## Perform imports and define constants -# -# Import the required packages. -# - -import os -import tempfile -import time - -from pyaedt import Desktop, Hfss, settings -from pyedb.misc.downloads import download_file - -# Define constants. - -AEDT_VERSION = "2024.2" -OLD_AEDT_VERSION = "2024.1" -NUM_CORES = 4 -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Download encrypted example -# -# Download the encrypted 3D component example. - -a3dcomp = download_file( - directory="component_3d", - filename="SMA_Edge_Connector_23r2_encrypted_password_ansys.a3dcomp", - destination=temp_folder.name, -) - -# ## Enable multiple desktop support - -settings.use_multi_desktop = True - -# ## Prepare encrypted 3D component in ACIS -# -# Launch the old AEDT release. - -aedt_old = Desktop(new_desktop=True, version=OLD_AEDT_VERSION) - -# Insert an empty HFSS design. - -hfss1 = Hfss(aedt_process_id=aedt_old.aedt_process_id, solution_type="Terminal") - -# Insert the encrypted 3D component. - -cmp = hfss1.modeler.insert_3d_component(comp_file=a3dcomp, password="ansys") - -# Open the 3D component in an HFSS design. - -app_comp = cmp.edit_definition(password="ansys") - -# ## Create an encrypted 3D component in Parasolid -# -# Launch the new AEDT release - -aedt = Desktop(new_desktop_session=True, specified_version=AEDT_VERSION) - -# Insert an empty HFSS design. - -hfss2 = Hfss(aedt_process_id=aedt.aedt_process_id, solution_type="Terminal") - -# Copy objects from the old design. - -hfss2.copy_solid_bodies_from(design=app_comp, no_vacuum=False, no_pec=False) - -# Create the new encrypted 3D component. - -hfss2.modeler.create_3dcomponent( - input_file=os.path.join(temp_folder.name, r"SMA_Edge_Connector_encrypted.a3dcomp"), - is_encrypted=True, - edit_password="ansys", - hide_contents=False, - allow_edit=True, - password_type="InternalPassword", -) - -# ## Release AEDT - -aedt.save_project() -aedt_old.save_project() -aedt.release_desktop() -aedt_old.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. -# If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell -# removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/aedt_general/components/index.rst b/examples/aedt_general/components/index.rst deleted file mode 100644 index bb4420276..000000000 --- a/examples/aedt_general/components/index.rst +++ /dev/null @@ -1,38 +0,0 @@ -3D components -~~~~~~~~~~~~~ - -These examples use PyAEDT to show some 3D component capabilities. - -.. grid:: 2 - - .. grid-item-card:: 3D component creation and reuse - :padding: 2 2 2 2 - :link: reuse_component - :link-type: doc - - .. image:: _static/component_3d.png - :alt: Component creation - :width: 250px - :height: 200px - :align: center - - This example shows how to create and use 3D components. - - .. grid-item-card:: Encrypted 3D component conversion - :padding: 2 2 2 2 - :link: component_conversion - :link-type: doc - - .. image:: _static/e3dcomp.png - :alt: Connector component - :width: 250px - :height: 200px - :align: center - - This example shows how to convert an encrypted 3D component from ACIS to Parasolid in different AEDT releases. - -.. toctree:: - :hidden: - - reuse_component - component_conversion diff --git a/examples/aedt_general/components/reuse_component.py b/examples/aedt_general/components/reuse_component.py deleted file mode 100644 index b9e6a7f56..000000000 --- a/examples/aedt_general/components/reuse_component.py +++ /dev/null @@ -1,221 +0,0 @@ -# # 3D component creation and reuse - -# Here is a workflow for creating a 3D component and reusing it: -# -# Step 1: Create an antenna using PyAEDT and HFSS 3D Modeler. (The antenna can also be created using EDB and -# HFSS 3D Layout). -# -# Step 2. Store the object as a 3D component on the disk. -# -# Step 3. Reuse the 3D component in another project. -# -# Step 4. Parametrize and optimize the target design. -# -# Keywords: **AEDT**, **General**, **3D component**. - -# ## Perform imports and define constants -# Import the required packages. - -import os -import tempfile -import time - -from ansys.aedt.core import Hfss - -# Define constants. - -AEDT_VERSION = "2024.2" -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# Create an HFSS object. - -hfss = Hfss( - version=AEDT_VERSION, - new_desktop=True, - close_on_exit=True, - non_graphical=NG_MODE, - solution_type="Modal", -) -hfss.save_project(os.path.join(temp_folder.name, "example.aedt")) - -# ## Define variables -# -# PyAEDT can create and store all variables available in AEDT (such as design, project, -# and postprocessing). - -hfss["thick"] = "0.1mm" -hfss["width"] = "1mm" - -# ## Create modeler objects -# -# PyAEDT supports all modeler functionalities available in AEDT. -# You can create, delete, and modify objects using all available Boolean operations. -# PyAEDT can also fully access history. - -# + -substrate = hfss.modeler.create_box( - ["-width", "-width", "-thick"], - ["2*width", "2*width", "thick"], - material="FR4_epoxy", - name="sub", -) - -patch = hfss.modeler.create_rectangle( - "XY", ["-width/2", "-width/2", "0mm"], ["width", "width"], name="patch1" -) - -via1 = hfss.modeler.create_cylinder( - 2, - ["-width/8", "-width/4", "-thick"], - "0.01mm", - "thick", - material="copper", - name="via_inner", -) - -via_outer = hfss.modeler.create_cylinder( - 2, - ["-width/8", "-width/4", "-thick"], - "0.025mm", - "thick", - material="Teflon_based", - name="via_teflon", -) -# - - -# ## Assign bundaries -# -# Most of HFSS boundaries and excitations are already available in PyAEDT. -# You can easily assign a boundary to a face or to an object by taking advantage of -# Object-Oriented Programming (OOP) available in PyAEDT. - -# ### Assign Perfect E boundary to sheets -# -# Assign a Perfect E boundary to sheets. - -hfss.assign_perfecte_to_sheets(patch) - -# ### Assign boundaries to faces -# -# Assign boundaries to the top and bottom faces of an object. - -# + -side_face = [ - i - for i in via_outer.faces - if i.id not in [via_outer.top_face_z.id, via_outer.bottom_face_z.id] -] - -hfss.assign_perfecte_to_sheets(side_face) -hfss.assign_perfecte_to_sheets(substrate.bottom_face_z) -# - - -# ## Create wave port -# -# You can assign a wave port to a sheet or to a face of an object. - -hfss.wave_port( - via_outer.bottom_face_z, - name="P1", -) - -# ## Create 3D component -# -# Once the model is ready, you can create a 3D component. -# Multiple options are available to partially select objects, coordinate systems, -# boundaries, and mesh operations. You can also create encrypted 3D components. - -component_path = os.path.join(temp_folder.name, "component_test.aedbcomp") -hfss.modeler.create_3dcomponent(component_path, "patch_antenna") - -# ## Manage multiple project -# -# PyAEDT lets you control multiple projects, designs, and solution types at the same time. - -new_project = os.path.join(temp_folder.name, "new_project.aedt") -hfss2 = Hfss( - version=AEDT_VERSION, - project=new_project, - design="new_design", - solution_type="Modal", -) - -# ## Insert 3D component -# -# You can insert a 3D component without supplying additional information. -# All needed information is read from the file itself. - -hfss2.modeler.insert_3d_component(component_path) - -# ## Parametrize 3D components -# -# You can specify parameters for any 3D components. - -hfss2.modeler.user_defined_components["patch_antenna1"].parameters -hfss2["p_thick"] = "1mm" -hfss2.modeler.user_defined_components["patch_antenna1"].parameters["thick"] = "p_thick" - -# ## Insert multiple 3D components -# -# There is no limit to the number of 3D components that can be inserted in a design. -# These components can be the same or linked to different files. - -hfss2.modeler.create_coordinate_system(origin=[20, 20, 10], name="Second_antenna") -ant2 = hfss2.modeler.insert_3d_component( - component_path, coordinate_system="Second_antenna" -) - -# ## Move 3D components -# -# Move a 3D component by either changing its position or moving the relative coordinate system. - -hfss2.modeler.coordinate_systems[0].origin = [10, 10, 3] - -# ## Create air region -# -# Create an air region and assign a boundary to a face or an object. - -hfss2.modeler.create_air_region(30, 30, 30, 30, 30, 30) -hfss2.assign_radiation_boundary_to_faces(hfss2.modeler["Region"].faces) - -# ## Create setup and optimetrics analysis -# -# Once a project is ready to be solved, use PyAEDT to create a setup and parametrics analysis. -# All setup parameters can be edited. - -setup1 = hfss2.create_setup() -optim = hfss2.parametrics.add("p_thick", "0.2mm", "1.5mm", step=14) - -# ## Plot objects - -hfss2.modeler.fit_all() -hfss2.plot( - show=False, - output_file=os.path.join(hfss.working_directory, "Image.jpg"), - plot_air_objects=True, -) - -# ## Release AEDT - -hfss2.save_project() -hfss2.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. -# If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell removes -# all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/aedt_general/configuration_files.py b/examples/aedt_general/configuration_files.py index f4cdb64a4..8f4975ce5 100644 --- a/examples/aedt_general/configuration_files.py +++ b/examples/aedt_general/configuration_files.py @@ -28,127 +28,10 @@ # ## Perform imports and define constants # Import the required packages. -# + -import os -import tempfile import time -import ansys.aedt.core +time.sleep(20) -# - +1 / 0 -# Define constants. - -AEDT_VERSION = "2024.2" -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Create temporary directory -# -# Create the temporary directory. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Download project -# -# Download the Icepack project. - -project_full_name = ansys.aedt.core.downloads.download_icepak( - destination=temp_folder.name -) - -# ## Open project -# -# Open the Icepak project from the project folder. - -ipk = ansys.aedt.core.Icepak( - project=project_full_name, - version=AEDT_VERSION, - new_desktop=True, - non_graphical=NG_MODE, -) -ipk.autosave_disable() - -# ## Create source blocks -# -# Create a source block on the CPU and memories. - -ipk.create_source_block(object_name="CPU", input_power="25W") -ipk.create_source_block(object_name=["MEMORY1", "MEMORY1_1"], input_power="5W") - -# ## Assign boundaries -# -# Assign the opening and grille. - -region = ipk.modeler["Region"] -ipk.assign_openings(air_faces=region.bottom_face_x.id) -ipk.assign_grille(air_faces=region.top_face_x.id, free_area_ratio=0.8) - -# ## Create setup -# -# Create the setup. Properties can be set up from the ``setup`` object -# with getters and setters. They don't have to perfectly match the property -# syntax. - -setup1 = ipk.create_setup() -setup1["FlowRegime"] = "Turbulent" -setup1["Max Iterations"] = 5 -setup1["Solver Type Pressure"] = "flex" -setup1["Solver Type Temperature"] = "flex" -ipk.save_project() - -# ## Export project to step file -# -# Export the project to the step file. - -filename = ipk.design_name -file_path = os.path.join(ipk.working_directory, filename + ".step") -ipk.export_3d_model( - file_name=filename, - file_path=ipk.working_directory, - file_format=".step", - assignment_to_export=[], - assignment_to_remove=[], -) - -# ## Export configuration files -# -# Export the configuration files. You can optionally disable the export and -# import sections. Supported formats are JSON and TOML files. - -conf_file = ipk.configurations.export_config( - os.path.join(ipk.working_directory, "config.toml") -) -ipk.close_project() - -# ## Create project -# -# Create an Icepak project and import the step. - -new_project = os.path.join(temp_folder.name, "example.aedt") -app = ansys.aedt.core.Icepak(version=AEDT_VERSION, project=new_project) -app.modeler.import_3d_cad(file_path) - -# ## Import and apply configuration file -# -# Import and apply the configuration file. You can apply all or part of the -# JSON file that you import using options in the ``configurations`` object. - -out = app.configurations.import_config(conf_file) -is_conf_imported = app.configurations.results.global_import_success - -# ## Release AEDT -# Close the project and release AEDT. - -app.release_desktop() -time.sleep(3) # Allow AEDT to shut down before cleaning the temporary project folder. - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. -# If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell removes -# all temporary files, including the project folder. - -temp_folder.cleanup() +print("never called") \ No newline at end of file diff --git a/examples/aedt_general/index.rst b/examples/aedt_general/index.rst index 14085e292..883b8eb4e 100644 --- a/examples/aedt_general/index.rst +++ b/examples/aedt_general/index.rst @@ -18,64 +18,8 @@ Provides examples of some general AEDT pre-processing and post-processing capabi This example shows how to use PyAEDT to export configuration files and reuse them to import in a new project. - .. grid-item-card:: Modeler - :padding: 2 2 2 2 - :link: modeler/index - :link-type: doc - - .. image:: _static/modeler.png - :alt: Modeler - :width: 250px - :height: 200px - :align: center - - These examples use PyAEDT to show some modeler capabilities. - - .. grid-item-card:: Optimetrics setup - :padding: 2 2 2 2 - :link: optimetrics - :link-type: doc - - .. image:: _static/optimetrics.png - :alt: Optimetrics - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create a project in HFSS and create all optimetrics setups. - - .. grid-item-card:: Components - :padding: 2 2 2 2 - :link: components/index - :link-type: doc - - .. image:: _static/components.png - :alt: Components - :width: 250px - :height: 200px - :align: center - - These examples use PyAEDT to show some 3D component capabilities. - - .. grid-item-card:: Report - :padding: 2 2 2 2 - :link: report/index - :link-type: doc - - .. image:: _static/touchstone.png - :alt: Components - :width: 250px - :height: 200px - :align: center - - These examples use PyAEDT to show some report capabilities. - .. toctree:: :hidden: configuration_files - modeler/index - optimetrics - components/index - report/index \ No newline at end of file diff --git a/examples/aedt_general/modeler/_static/circuit.png b/examples/aedt_general/modeler/_static/circuit.png deleted file mode 100644 index 60919670b..000000000 Binary files a/examples/aedt_general/modeler/_static/circuit.png and /dev/null differ diff --git a/examples/aedt_general/modeler/_static/coordinate_system.png b/examples/aedt_general/modeler/_static/coordinate_system.png deleted file mode 100644 index eb887c92b..000000000 Binary files a/examples/aedt_general/modeler/_static/coordinate_system.png and /dev/null differ diff --git a/examples/aedt_general/modeler/_static/netlist.png b/examples/aedt_general/modeler/_static/netlist.png deleted file mode 100644 index 0f975446f..000000000 Binary files a/examples/aedt_general/modeler/_static/netlist.png and /dev/null differ diff --git a/examples/aedt_general/modeler/_static/polyline.png b/examples/aedt_general/modeler/_static/polyline.png deleted file mode 100644 index 0390f434a..000000000 Binary files a/examples/aedt_general/modeler/_static/polyline.png and /dev/null differ diff --git a/examples/aedt_general/modeler/circuit_schematic.py b/examples/aedt_general/modeler/circuit_schematic.py deleted file mode 100644 index ff26945ab..000000000 --- a/examples/aedt_general/modeler/circuit_schematic.py +++ /dev/null @@ -1,154 +0,0 @@ -# # Circuit schematic creation and analysis -# -# This example shows how to build a circuit schematic -# and run a transient circuit simulation. - -# -# -# Keywords: **AEDT**, **Circuit**, **Schematic**. - -# ## Import packages and define constants -# -# Perform required imports. - -# + -import os -import tempfile -import time - -import ansys.aedt.core - -# - - -# Define constants. - -AEDT_VERSION = "2024.2" -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Launch AEDT with Circuit -# -# Launch AEDT with Circuit. The [pyaedt.Desktop]( -# https://aedt.docs.pyansys.com/version/stable/API/_autosummary/pyaedt.desktop.Desktop.html#pyaedt.desktop.Desktop) -# class initializes AEDT and starts the specified version in the specified mode. - -# + - -circuit = ansys.aedt.core.Circuit( - project=os.path.join(temp_folder.name, "CircuitExample"), - design="Simple", - version=AEDT_VERSION, - non_graphical=NG_MODE, - new_desktop=True, -) - -circuit.modeler.schematic.schematic_units = "mil" -# - - -# ## Create circuit setup -# -# Create and customize a linear network analysis (LNA) setup. - -setup1 = circuit.create_setup("MyLNA") -setup1.props["SweepDefinition"]["Data"] = "LINC 0GHz 4GHz 10001" - -# ## Place components -# -# Place components such as an inductor, resistor, and capacitor. The ``location`` argument -# provides the ``[x, y]`` coordinates to place the component. - -inductor = circuit.modeler.schematic.create_inductor( - name="L1", value=1e-9, location=[0, 0] -) -resistor = circuit.modeler.schematic.create_resistor( - name="R1", value=50, location=[500, 0] -) -capacitor = circuit.modeler.schematic.create_capacitor( - name="C1", value=1e-12, location=[1000, 0] -) - -# ## Get all pins -# -# The component pins are instances of the -# ``ansys.aedt.core.modeler.circuits.objct3dcircuit.CircuitPins`` class and -# provide access to the -# pin location, net connectivity, and the ``connect_to_component()`` method, which -# can be used to connect components in the schematic -# as demonstrated in this example. - -# ## Place a port and ground -# -# Place a port and a ground in the schematic. - -port = circuit.modeler.components.create_interface_port( - name="myport", location=[-300, 50] -) -gnd = circuit.modeler.components.create_gnd(location=[1200, -100]) - -# ## Connect components -# -# Connect components with wires in the schematic. The ``connect_to_component()`` -# method is used to create connections between pins. - -port.pins[0].connect_to_component(assignment=inductor.pins[0], use_wire=True) -inductor.pins[1].connect_to_component(assignment=resistor.pins[1], use_wire=True) -resistor.pins[0].connect_to_component(assignment=capacitor.pins[0], use_wire=True) -capacitor.pins[1].connect_to_component(assignment=gnd.pins[0], use_wire=True) - -# ## Create transient setup -# -# Create a transient setup. - -setup2 = circuit.create_setup( - name="MyTransient", setup_type=circuit.SETUPS.NexximTransient -) -setup2.props["TransientData"] = ["0.01ns", "200ns"] -setup3 = circuit.create_setup(name="MyDC", setup_type=circuit.SETUPS.NexximDC) - -# ## Solve transient setup -# -# Solve the transient setup. - -circuit.analyze_setup("MyLNA") -circuit.export_fullwave_spice() - -# ## Create report -# -# Create a report displaying the scattering parameters. - -solutions = circuit.post.get_solution_data( - expressions=circuit.get_traces_for_plot(category="S"), -) -solutions.enable_pandas_output = True -real, imag = solutions.full_matrix_real_imag -print(real) - -# ## Create plot -# -# Create a plot based on solution data. - -fig = solutions.plot() - -# ## Release AEDT -# -# Release AEDT and close the example. - -circuit.save_project() -circuit.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/aedt_general/modeler/coordinate_system.py b/examples/aedt_general/modeler/coordinate_system.py deleted file mode 100644 index ad54a83c3..000000000 --- a/examples/aedt_general/modeler/coordinate_system.py +++ /dev/null @@ -1,300 +0,0 @@ -# # Coordinate system creation -# -# This example shows how to use PyAEDT to create and modify coordinate systems in the modeler. -# -# Keywords: **AEDT**, **modeler**, **coordinate system**. - -# ## Perform imports and define constants -# Import the required packages. - -import os -import tempfile -import time - -import ansys.aedt.core - -# Define constants. - -AEDT_VERSION = "2024.2" -NG_MODE = False # Open the AEDT UI when it is launched. - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Launch AEDT - -d = ansys.aedt.core.launch_desktop( - version=AEDT_VERSION, non_graphical=NG_MODE, new_desktop=True -) - -# ## Insert HFSS design -# -# Insert an HFSS design with the default name. - -project_name = os.path.join(temp_folder.name, "CoordSysDemo.aedt") -hfss = ansys.aedt.core.Hfss(version=AEDT_VERSION, project=project_name) - -# ## Create coordinate system -# -# The coordinate system is centered on the global origin and has the axis -# aligned to the global coordinate system. The new coordinate system is -# saved in the object ``cs1``. - -cs1 = hfss.modeler.create_coordinate_system() - -# ## Modify coordinate system -# -# The ``cs1`` object exposes properties and methods to manipulate the -# coordinate system. The origin can be changed. - -cs1["OriginX"] = 10 -cs1.props["OriginY"] = 10 -cs1.props["OriginZ"] = 10 - -# The orientation of the coordinate system can be modified by -# updating the direction vectors for the coordinate system. - -ypoint = [0, -1, 0] -cs1.props["YAxisXvec"] = ypoint[0] -cs1.props["YAxisYvec"] = ypoint[1] -cs1.props["YAxisZvec"] = ypoint[2] - -# ## Rename coordinate system -# -# Rename the coordinate system. - -cs1.rename("newCS") - -# ## Change coordinate system mode -# -# Use the ``change_cs_mode`` method to change the mode. Options are: -# -# - ``0`` for axis/position -# - ``1`` for Euler angle ZXZ -# - ``2`` for Euler angle ZYZ -# -# Here ``1`` sets Euler angle ZXZ as the mode. - -cs1.change_cs_mode(1) - -# The following lines use the ZXZ Euler angle definition to rotate the coordinate system. - -cs1.props["Phi"] = "10deg" -cs1.props["Theta"] = "22deg" -cs1.props["Psi"] = "30deg" - -# ## Delete coordinate system -# -# Delete the coordinate system. - -cs1.delete() - -# ## Define a new coordinate system -# -# Create a coordinate system by defining the axes. You can -# specify all coordinate system properties as shown here. - -cs2 = hfss.modeler.create_coordinate_system( - name="CS2", - origin=[1, 2, 3.5], - mode="axis", - x_pointing=[1, 0, 1], - y_pointing=[0, -1, 0], -) - -# A new coordinate system can also be created based on the Euler angle convention. - -cs3 = hfss.modeler.create_coordinate_system( - name="CS3", origin=[2, 2, 2], mode="zyz", phi=10, theta=20, psi=30 -) - -# Create a coordinate system that is defined by standard views in the modeler. The options are: -# -# - ``"iso"`` -# - ``"XY"`` -# - ``"XZ"`` -# - ``"XY"`` -# -# Here ``"iso"`` is specified. The axes are set automatically. - -cs4 = hfss.modeler.create_coordinate_system( - name="CS4", origin=[1, 0, 0], reference_cs="CS3", mode="view", view="iso" -) - -# ## Create coordinate system by defining axis and angle rotation -# -# Create a coordinate system by defining the axis and angle rotation. When you -# specify the axis and angle rotation, this data is automatically translated -# to Euler angles. - -cs5 = hfss.modeler.create_coordinate_system( - name="CS5", mode="axisrotation", u=[1, 0, 0], theta=123 -) - -# Face coordinate systems are bound to an object face. -# First create a box and then define the face coordinate system on one of its -# faces. To create the reference face for the face coordinate system, you must -# specify starting and ending points for the axis. - -box = hfss.modeler.create_box([0, 0, 0], [2, 2, 2]) -face = box.faces[0] -fcs1 = hfss.modeler.create_face_coordinate_system( - face=face, origin=face.edges[0], axis_position=face.edges[1], name="FCS1" -) - -# Create a face coordinate system centered on the face with the X axis pointing -# to the edge vertex. - -fcs2 = hfss.modeler.create_face_coordinate_system( - face=face, origin=face, axis_position=face.edges[0].vertices[0], name="FCS2" -) - -# Swap the X axis and Y axis of the face coordinate system. The X axis is the -# pointing ``axis_position`` by default. You can optionally select the Y axis. - -fcs3 = hfss.modeler.create_face_coordinate_system( - face=face, origin=face, axis_position=face.edges[0], axis="Y" -) - -# The face coordinate system can also be rotated by changing the -# reference axis. - -fcs3.props["WhichAxis"] = "X" - - -# ### Rotate the coordinate system -# -# Apply a rotation around the Z axis. The Z axis of a face coordinate system -# is always orthogonal to the face. A rotation can be applied at definition. -# Rotation is expressed in degrees. - -fcs4 = hfss.modeler.create_face_coordinate_system( - face=face, origin=face, axis_position=face.edges[1], rotation=10.3 -) - -# Rotation can also be changed after coordinate system creation. - -fcs4.props["ZRotationAngle"] = "3deg" - -# ### Offset the coordinate system -# -# Apply an offset to the X axis and Y axis of a face coordinate system. -# The offset is in respect to the face coordinate system itself. - -fcs5 = hfss.modeler.create_face_coordinate_system( - face=face, origin=face, axis_position=face.edges[2], offset=[0.5, 0.3] -) - -# The offset can be changed after the coordinate system has been created. - -fcs5.props["XOffset"] = "0.2mm" -fcs5.props["YOffset"] = "0.1mm" - -# ### Create a dependent coordinate system -# -# The use of dependent coordinate systems can simplify model creation. The following -# cell shows how to create a coordinate system whose reference is the face coordinate system. - -face = box.faces[1] -fcs6 = hfss.modeler.create_face_coordinate_system( - face=face, origin=face, axis_position=face.edges[0] -) -cs_fcs = hfss.modeler.create_coordinate_system( - name="CS_FCS", origin=[0, 0, 0], reference_cs=fcs6.name, mode="view", view="iso" -) - -# ### Create object coordinate systems -# -# A coordinate system can also be defined relative to elements -# belonging to an object. For example, the coordinate system can be -# connected to an object face. - -obj_cs = hfss.modeler.create_object_coordinate_system( - assignment=box, - origin=box.faces[0], - x_axis=box.edges[0], - y_axis=[0, 0, 0], - name="box_obj_cs", -) -obj_cs.rename("new_obj_cs") - -# Create an object coordinate system whose origin is linked to the edge of an object. - -obj_cs_1 = hfss.modeler.create_object_coordinate_system( - assignment=box.name, - origin=box.edges[0], - x_axis=[1, 0, 0], - y_axis=[0, 1, 0], - name="obj_cs_1", -) -obj_cs_1.set_as_working_cs() - -# Create an object coordinate system with an origin specified on a point within an object. - -obj_cs_2 = hfss.modeler.create_object_coordinate_system( - assignment=box.name, - origin=[0, 0.8, 0], - x_axis=[1, 0, 0], - y_axis=[0, 1, 0], - name="obj_cs_2", -) -new_obj_cs_2 = hfss.modeler.duplicate_coordinate_system_to_global(obj_cs_2) -obj_cs_2.delete() - -# Create an object coordinate system with an origin on the vertex. - -obj_cs_3 = hfss.modeler.create_object_coordinate_system( - obj=box.name, - origin=box.vertices[1], - x_axis=box.faces[2], - y_axis=box.faces[4], - name="obj_cs_3", -) -obj_cs_3.props["MoveToEnd"] = False -obj_cs_3.update() - -# ### Get all coordinate systems -# -# Easily retrieve and subsequently manipulate all coordinate systems. - -css = hfss.modeler.coordinate_systems -names = [i.name for i in css] -print(names) - -# ## Select coordinate system -# -# Select an existing coordinate system. - -css = hfss.modeler.coordinate_systems -cs_selected = css[0] -cs_selected.delete() - -# ## Get point coordinate under another coordinate system -# -# Get a point coordinate under another coordinate system. A point coordinate -# can be translated in respect to any coordinate system. - -hfss.modeler.create_box([-10, -10, -10], [20, 20, 20], "Box1") -p = hfss.modeler["Box1"].faces[0].vertices[0].position -print("Global: ", p) -p2 = hfss.modeler.global_to_cs(p, "CS5") -print("CS5 :", p2) - -# ## Release AEDT -# Close the project and release AEDT. - -d.release_desktop() -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/aedt_general/modeler/index.rst b/examples/aedt_general/modeler/index.rst deleted file mode 100644 index 4adb4d9f5..000000000 --- a/examples/aedt_general/modeler/index.rst +++ /dev/null @@ -1,67 +0,0 @@ -Modeler -~~~~~~~ -These examples use PyAEDT to show some modeler capabilities. - -.. grid:: 2 - - .. grid-item-card:: Coordinate system creation - :padding: 2 2 2 2 - :link: coordinate_system - :link-type: doc - - .. image:: _static/coordinate_system.png - :alt: Coordinate system - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create and modify coordinate systems in the modeler. - - - .. grid-item-card:: Polyline creation - :padding: 2 2 2 2 - :link: polyline - :link-type: doc - - .. image:: _static/polyline.png - :alt: Polyline - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create and manipulate polylines. - - .. grid-item-card:: Circuit schematic creation and analysis - :padding: 2 2 2 2 - :link: circuit_schematic - :link-type: doc - - .. image:: _static/circuit.png - :alt: Circuit - :width: 250px - :height: 200px - :align: center - - This example shows how to build a circuit schematic and run a transient circuit simulation. - - .. grid-item-card:: Circuit Netlist to Schematic - :padding: 2 2 2 2 - :link: netlist_to_schematic - :link-type: doc - - .. image:: _static/netlist.png - :alt: Netlist - :width: 250px - :height: 250px - :align: center - - This example shows how to build a circuit schematic and run a transient circuit simulation. - - -.. toctree:: - :hidden: - - coordinate_system - polyline - circuit_schematic - netlist_to_schematic diff --git a/examples/aedt_general/modeler/netlist_to_schematic.py b/examples/aedt_general/modeler/netlist_to_schematic.py deleted file mode 100644 index 67a30617e..000000000 --- a/examples/aedt_general/modeler/netlist_to_schematic.py +++ /dev/null @@ -1,78 +0,0 @@ -# # Circuit Netlist to Schematic -# -# This example shows how to create components -# in the circuit schematic editor from a netlist file. -# -# Note that HSPICE files are fully supported and that broad coverage is provided for many other formats. -# -# Keywords: **Circuit**, **netlist**. - -# ## Perform imports and define constants -# -# Import the required packages. - -# + -import os -import tempfile -import time - -import ansys.aedt.core - -# - - -# ## Define constants. - -AEDT_VERSION = "2024.2" -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Launch AEDT with Circuit -# -# Launch AEDT with Circuit. The `ansys.aedt.core.Desktop` class initializes AEDT -# and starts it on the specified version in the specified graphical mode. - -netlist = ansys.aedt.core.downloads.download_netlist(destination=temp_folder.name) -circuit = ansys.aedt.core.Circuit( - project=os.path.join(temp_folder.name, "NetlistExample"), - version=AEDT_VERSION, - non_graphical=NG_MODE, - new_desktop=True, -) - -# ## Define a parameter -# -# Specify the voltage as a parameter. - -circuit["Voltage"] = "5" - -# ## Create schematic from netlist file -# -# Create a schematic from a netlist file. The ``create_schematic_from_netlist()`` -# method reads the netlist file and parses it. All components are parsed, -# but only these categories are mapped: R, L, C, Q, U, J, V, and I. - -circuit.create_schematic_from_netlist(netlist) - -# ## Release AEDT -# -# Release AEDT and close the example. - -circuit.save_project() -circuit.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/aedt_general/modeler/polyline.py b/examples/aedt_general/modeler/polyline.py deleted file mode 100644 index afe0e3c70..000000000 --- a/examples/aedt_general/modeler/polyline.py +++ /dev/null @@ -1,350 +0,0 @@ -# # Polyline creation -# -# This example shows how to use PyAEDT to create and manipulate polylines. -# -# Keywords: **AEDT**, **modeler**, **polyline**. - -# ## Import packages and define constants -# Import the required packages. - -import os -import tempfile -import time - -import ansys.aedt.core - -# Define constants - -AEDT_VERSION = "2024.2" -NG_MODE = False # Open AEDT UI when it is launched. - - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Create Maxwell 3D object -# -# Create a `Maxwell3d` object and set the unit type to ``"mm"``. - -project_name = os.path.join(temp_folder.name, "polyline.aedt") -maxwell = ansys.aedt.core.Maxwell3d( - project=project_name, - solution_type="Transient", - design="test_polyline_3D", - version=AEDT_VERSION, - new_desktop=True, - non_graphical=NG_MODE, -) -maxwell.modeler.model_units = "mm" -modeler = maxwell.modeler - -# ## Define variables -# -# Define two design variables as parameters for the polyline objects. - -maxwell["p1"] = "100mm" -maxwell["p2"] = "71mm" - -# ## Input data -# -# Input data. All data for the polyline functions can be entered as either floating point -# values or strings. Floating point values are assumed to be in model units -# (``maxwell.modeler.model_units``). - -test_points = [ - ["0mm", "p1", "0mm"], - ["-p1", "0mm", "0mm"], - ["-p1/2", "-p1/2", "0mm"], - ["0mm", "0mm", "0mm"], -] - -# ## Create polyline primitives -# -# The following examples are for creating polyline primitives. - -# ### Create line primitive -# -# Create a line primitive. The basic polyline command takes a list of positions -# (``[X, Y, Z]`` coordinates) and creates a polyline object with one or more -# segments. The supported segment types are ``Line``, ``Arc`` (3 points), -# ``AngularArc`` (center-point + angle), and ``Spline``. - -line1 = modeler.create_polyline(points=test_points[0:2], name="PL01_line") -print("Created Polyline with name: {}".format(modeler.objects[line1.id].name)) -print("Segment types : {}".format([s.type for s in line1.segment_types])) -print("primitive id = {}".format(line1.id)) - -# ### Create arc primitive -# -# Create an arc primitive. The ``position_list`` parameter must contain at -# least three position values. The first three position values are used. - -line2 = modeler.create_polyline( - points=test_points[0:3], segment_type="Arc", name="PL02_arc" -) -print( - "Created object with id {} and name {}.".format( - line2.id, modeler.objects[line2.id].name - ) -) - -# ### Create spline primitive -# -# Create a spline primitive. Defining the segment using a ``PolylineSegment`` -# object allows you to provide additional input parameters for the spine, such -# as the number of points (in this case 4). The ``points`` parameter -# must contain at least four position values. - -line3 = modeler.create_polyline( - points=test_points, - segment_type=modeler.polyline_segment("Spline", num_points=4), - name="PL03_spline_4pt", -) - -# ### Create center-point arc primitive -# -# Create a center-point arc primitive. A center-point arc segment is defined -# by a starting point, a center point, and an angle of rotation around the -# center point. The rotation occurs in a plane parallel to the XY, YZ, or ZX -# plane of the active coordinate system. The starting point and the center point -# must therefore have one coordinate value (X, Y, or Z) with the same value. -# -# In this first code example, ``start-point`` and ``center-point`` have a common -# Z position, ``"0mm"``. The curve therefore lies in the XY plane at $ z = 0 $. - -start_point = [100, 100, 0] -center_point = [0, 0, 0] -line4 = modeler.create_polyline( - points=[start_point], - segment_type=modeler.polyline_segment( - "AngularArc", arc_center=center_point, arc_angle="30deg" - ), - name="PL04_center_point_arc", -) - -# In this second code example, ``start_point`` and ``center_point`` have the same -# values for the Y and Z coordinates, so the plane or rotation could be either XY or ZX. -# For these special cases when the rotation plane is ambiguous, you can specify -# the plane explicitly. - -start_point = [100, 0, 0] -center_point = [0, 0, 0] -line4_xy = modeler.create_polyline( - points=[start_point], - segment_type=modeler.polyline_segment( - "AngularArc", arc_center=center_point, arc_angle="30deg", arc_plane="XY" - ), - name="PL04_center_point_arc_rot_XY", -) -line4_zx = modeler.create_polyline( - points=[start_point], - segment_type=modeler.polyline_segment( - "AngularArc", arc_center=center_point, arc_angle="30deg", arc_plane="ZX" - ), - name="PL04_center_point_arc_rot_ZX", -) - -# ## Create compound polylines -# -# You can pass a list of points to the ``create_polyline()`` method to create a multi-segment -# polyline. -# -# If the type of segment is not specified, all points -# are connected by straight line segments. - -line6 = modeler.create_polyline(points=test_points, name="PL06_segmented_compound_line") - -# You can specify the segment type as an optional named argument to -# define the segment type used to connect the points. - -line5 = modeler.create_polyline( - points=test_points, segment_type=["Line", "Arc"], name="PL05_compound_line_arc" -) - -# Setting the named argument ``close_surface=True`` ensures -# that the polyline starting point and -# ending point are the same. You can also explicitly close the -# polyline by setting the last point equal -# to the first point in the list of points. - -line7 = modeler.create_polyline( - points=test_points, close_surface=True, name="PL07_segmented_compound_line_closed" -) - -# Setting the named argument ``cover_surface=True`` also -# covers the polyline and creates a sheet object. - -line_cover = modeler.create_polyline( - points=test_points, cover_surface=True, name="SPL01_segmented_compound_line" -) - -# ## Insert compound lines -# -# The following examples are for inserting compound lines. -# -# ### Insert line segment -# -# Insert a line segment starting at vertex 1 ``["100mm", "0mm", "0mm"]`` -# of an existing polyline and ending at some new point ``["90mm", "20mm", "0mm"].`` -# By numerical comparison of the starting point with the existing vertices of the -# original polyline object, it is determined automatically that the segment is -# inserted after the first segment of the original polyline. - -line8_segment = modeler.create_polyline( - points=test_points, - close_surface=True, - name="PL08_segmented_compound_insert_segment", -) -points_line8_segment = line8_segment.points[1] -insert_point = ["-100mm", "20mm", "0mm"] -line8_segment.insert_segment(points=[insert_point, points_line8_segment]) - -# ### Insert compound line with insert curve -# -# Insert a compound line starting a line segment at vertex 1 ``["100mm", "0mm", "0mm"]`` -# of an existing polyline and ending at some new point ``["90mm", "20mm", "0mm"]``. -# By numerical comparison of the starting point, it is determined automatically -# that the segment is inserted after the first segment of the original polyline. - -# + -line8_segment_arc = modeler.create_polyline( - points=test_points, close_surface=False, name="PL08_segmented_compound_insert_arc" -) - -start_point = line8_segment_arc.vertex_positions[1] -insert_point1 = ["90mm", "20mm", "0mm"] -insert_point2 = [40, 40, 0] - -line8_segment_arc.insert_segment( - points=[start_point, insert_point1, insert_point2], segment="Arc" -) -# - - -# ### Insert compound line at end of a center-point arc -# -# Insert a compound line at the end of a center-point arc (``type="AngularArc"``). -# This is a special case. -# -# Step 1: Draw a center-point arc. - -# + -start_point = [2200.0, 0.0, 1200.0] -arc_center_1 = [1400, 0, 800] -arc_angle_1 = "43.47deg" - -line_arc = modeler.create_polyline( - name="First_Arc", - points=[start_point], - segment_type=modeler.polyline_segment( - type="AngularArc", arc_angle=arc_angle_1, arc_center=arc_center_1 - ), -) -# - - -# Step 2: Insert a line segment at the end of the arc with a specified end point. - -start_of_line_segment = line_arc.end_point -end_of_line_segment = [3600, 200, 30] -line_arc.insert_segment(points=[start_of_line_segment, end_of_line_segment]) - -# Step 3: Append a center-point arc segment to the line object. - -arc_angle_2 = "39.716deg" -arc_center_2 = [3400, 200, 3800] -line_arc.insert_segment( - points=[end_of_line_segment], - segment=modeler.polyline_segment( - type="AngularArc", arc_center=arc_center_2, arc_angle=arc_angle_2 - ), -) - -# You can use the compound polyline definition to complete all three steps in -# a single step. - -modeler.create_polyline( - points=[start_point, end_of_line_segment], - segment_type=[ - modeler.polyline_segment( - type="AngularArc", arc_angle="43.47deg", arc_center=arc_center_1 - ), - modeler.polyline_segment(type="Line"), - modeler.polyline_segment( - type="AngularArc", arc_angle=arc_angle_2, arc_center=arc_center_2 - ), - ], - name="Compound_Polyline_One_Command", -) - -# ## Insert two 3-point arcs forming a circle -# -# Insert two 3-point arcs forming a circle. -# Note that the last point of the second arc segment is not defined in -# the position list. - -line_three_points = modeler.create_polyline( - points=[ - [34.1004, 14.1248, 0], - [27.646, 16.7984, 0], - [24.9725, 10.3439, 0], - [31.4269, 7.6704, 0], - ], - segment_type=["Arc", "Arc"], - cover_surface=True, - close_surface=True, - name="line_covered", - material="vacuum", -) - -# Here is an example of a complex polyline where the number of points is -# insufficient to populate the requested segments. This results in an -# ``IndexError`` that PyAEDT catches silently. The return value of the command -# is ``False``, which can be caught at the app level. While this example might -# not be so useful in a Jupyter Notebook, it is important for unit tests. - -line_points = [ - ["67.1332mm", "2.9901mm", "0mm"], - ["65.9357mm", "2.9116mm", "0mm"], - ["65.9839mm", "1.4562mm", "0mm"], - ["66mm", "0mm", "0mm"], - ["99mm", "0mm", "0mm"], - ["98.788mm", "6.4749mm", "0mm"], - ["98.153mm", "12.9221mm", "0mm"], - ["97.0977mm", "19.3139mm", "0mm"], -] - - -line_segments = ["Line", "Arc", "Line", "Arc", "Line"] -line_complex1 = modeler.create_polyline( - points=line_points, segment_type=line_segments, name="Polyline_example" -) - -# Here is an example that provides more points than the segment list requires. -# This is valid usage. The remaining points are ignored. - -line_segments = ["Line", "Arc", "Line", "Arc"] -line_complex2 = modeler.create_polyline( - line_points, segment_type=line_segments, name="Polyline_example2" -) - -# ## Save project -# -# Save the project. - -maxwell.save_project() -maxwell.release_desktop() -time.sleep(3) # Allow AEDT to shut down before cleaning the temporary project folder. - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. -# If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell removes -# all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/aedt_general/optimetrics.py b/examples/aedt_general/optimetrics.py deleted file mode 100644 index 72c8c92bf..000000000 --- a/examples/aedt_general/optimetrics.py +++ /dev/null @@ -1,176 +0,0 @@ -# # Optimetrics setup -# -# This example shows how to use PyAEDT to create a project in HFSS and create all optimetrics -# setups. -# -# Keywords: **AEDT**, **General**, **optimetrics**. - -# ## Perform imports and define constants -# Import the required packages. - -import os -import tempfile -import time - -import ansys.aedt.core - -# Define constants. - -AEDT_VERSION = "2024.2" -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Initialize HFSS and create variables -# -# Initialize the ``Hfss`` object and create two needed design variables, -# ``w1`` and ``w2``. - -# + -project_name = os.path.join(temp_folder.name, "optimetrics.aedt") - -hfss = ansys.aedt.core.Hfss( - project=project_name, - version=AEDT_VERSION, - new_desktop=True, - non_graphical=NG_MODE, - solution_type="Modal", -) - -hfss["w1"] = "1mm" -hfss["w2"] = "100mm" -# - - -# ## Create waveguide with sheets on it -# -# Create one of the standard waveguide structures and parametrize it. -# You can also create rectangles of waveguide openings and assign ports later. - -# + -wg1, p1, p2 = hfss.modeler.create_waveguide( - [0, 0, 0], - hfss.AXIS.Y, - "WG17", - wg_thickness="w1", - wg_length="w2", - create_sheets_on_openings=True, -) - -model = hfss.plot(show=False) - -model.show_grid = False -model.plot(os.path.join(hfss.working_directory, "Image.jpg")) -# - - -# ## Create wave ports on sheets -# -# Create two wave ports on the sheets. - -hfss.wave_port(p1, integration_line=hfss.AxisDir.ZPos, name="1") -hfss.wave_port(p2, integration_line=hfss.AxisDir.ZPos, name="2") - -# ## Create setup and frequency sweep -# -# Create a setup and a frequency sweep to use as the base for optimetrics -# setups. - -setup = hfss.create_setup() -hfss.create_linear_step_sweep( - setup=setup.name, - unit="GHz", - start_frequency=1, - stop_frequency=5, - step_size=0.1, - name="Sweep1", - save_fields=True, -) - -# ## Create optimetrics analyses -# -# ### Create parametric analysis -# -# Create a simple optimetrics parametrics analysis with output calculations. - -sweep = hfss.parametrics.add("w2", 90, 200, 5) -sweep.add_variation("w1", 0.1, 2, 10) -sweep.add_calculation(calculation="dB(S(1,1))", ranges={"Freq": "2.5GHz"}) -sweep.add_calculation(calculation="dB(S(1,1))", ranges={"Freq": "2.6GHz"}) - -# ### Create sensitivity analysis -# -# Create an optimetrics sensitivity analysis with output calculations. - -sweep2 = hfss.optimizations.add( - calculation="dB(S(1,1))", ranges={"Freq": "2.5GHz"}, optimization_type="Sensitivity" -) -sweep2.add_variation("w1", 0.1, 3, 0.5) -sweep2.add_calculation(calculation="dB(S(1,1))", ranges={"Freq": "2.6GHz"}) - -# ### Create an optimization analysis -# -# Create an optimization analysis based on goals and calculations. - -sweep3 = hfss.optimizations.add(calculation="dB(S(1,1))", ranges={"Freq": "2.5GHz"}) -sweep3.add_variation("w1", 0.1, 3, 0.5) -sweep3.add_goal(calculation="dB(S(1,1))", ranges={"Freq": "2.6GHz"}) -sweep3.add_goal(calculation="dB(S(1,1))", ranges={"Freq": ("2.6GHz", "5GHz")}) -sweep3.add_goal( - calculation="dB(S(1,1))", - ranges={"Freq": ("2.6GHz", "5GHz")}, - condition="Maximize", -) - -# ### Create a DesignXplorer optimization -# -# Create a DesignXplorer optimization based on a goal and a calculation. - -sweep4 = hfss.optimizations.add( - calculation="dB(S(1,1))", - ranges={"Freq": "2.5GHz"}, - optimization_type="DesignExplorer", -) -sweep4.add_goal(calculation="dB(S(1,1))", ranges={"Freq": "2.6GHz"}) - -# ### Create a Design of Experiments (DOE) -# -# Create a DOE based on a goal and a calculation. - -sweep5 = hfss.optimizations.add( - calculation="dB(S(1,1))", ranges={"Freq": "2.5GHz"}, optimization_type="DXDOE" -) - -# ### Create another DOE -# -# Create another DOE based on a goal and a calculation. - -region = hfss.modeler.create_region() -hfss.assign_radiation_boundary_to_objects(region) -hfss.insert_infinite_sphere(name="Infinite_1") -sweep6 = hfss.optimizations.add( - calculation="RealizedGainTotal", - solution=hfss.nominal_adaptive, - ranges={"Freq": "5GHz", "Theta": ["0deg", "10deg", "20deg"], "Phi": "0deg"}, - context="Infinite_1", -) - -# ## Release AEDT - -hfss.save_project() -hfss.release_desktop() -time.sleep(3) # Allow AEDT to shut down before cleaning the temporary project folder. - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. -# If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell removes -# all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/aedt_general/report/_static/automatic_report.png b/examples/aedt_general/report/_static/automatic_report.png deleted file mode 100644 index e8ba6df51..000000000 Binary files a/examples/aedt_general/report/_static/automatic_report.png and /dev/null differ diff --git a/examples/aedt_general/report/_static/touchstone_skitrf.png b/examples/aedt_general/report/_static/touchstone_skitrf.png deleted file mode 100644 index fcd2a8466..000000000 Binary files a/examples/aedt_general/report/_static/touchstone_skitrf.png and /dev/null differ diff --git a/examples/aedt_general/report/_static/virtual_compliance_class.png b/examples/aedt_general/report/_static/virtual_compliance_class.png deleted file mode 100644 index d6c3e6bf3..000000000 Binary files a/examples/aedt_general/report/_static/virtual_compliance_class.png and /dev/null differ diff --git a/examples/aedt_general/report/_static/virtual_compliance_configs.png b/examples/aedt_general/report/_static/virtual_compliance_configs.png deleted file mode 100644 index 85f93b218..000000000 Binary files a/examples/aedt_general/report/_static/virtual_compliance_configs.png and /dev/null differ diff --git a/examples/aedt_general/report/_static/virtual_compliance_eye.png b/examples/aedt_general/report/_static/virtual_compliance_eye.png deleted file mode 100644 index 890d49ffa..000000000 Binary files a/examples/aedt_general/report/_static/virtual_compliance_eye.png and /dev/null differ diff --git a/examples/aedt_general/report/_static/virtual_compliance_scattering1.png b/examples/aedt_general/report/_static/virtual_compliance_scattering1.png deleted file mode 100644 index a78e3dc84..000000000 Binary files a/examples/aedt_general/report/_static/virtual_compliance_scattering1.png and /dev/null differ diff --git a/examples/aedt_general/report/_static/virtual_compliance_scattering2.png b/examples/aedt_general/report/_static/virtual_compliance_scattering2.png deleted file mode 100644 index e9afcb68a..000000000 Binary files a/examples/aedt_general/report/_static/virtual_compliance_scattering2.png and /dev/null differ diff --git a/examples/aedt_general/report/_static/virtual_compliance_usage.png b/examples/aedt_general/report/_static/virtual_compliance_usage.png deleted file mode 100644 index 779026001..000000000 Binary files a/examples/aedt_general/report/_static/virtual_compliance_usage.png and /dev/null differ diff --git a/examples/aedt_general/report/automatic_report.py b/examples/aedt_general/report/automatic_report.py deleted file mode 100644 index 46ee62985..000000000 --- a/examples/aedt_general/report/automatic_report.py +++ /dev/null @@ -1,158 +0,0 @@ -# # Automatic report creation -# -# This example shows how to create reports from a JSON template file. -# -# -# Keywords: **Circuit**, **report**. - -# ## Perform imports and define constants -# -# Import the required packages. This example uses -# data from the [example-data repository](https://github.com/ansys/example-data/tree/master) -# located in ``pyaedt\custom_reports``. - -# + -import os -import tempfile -import time - -import ansys.aedt.core -from IPython.display import Image - -# Define constants. - -AEDT_VERSION = "2024.2" -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Launch AEDT with Circuit -# -# AEDT is started by instantiating an instance of -# [pyaedt.Circuit](https://aedt.docs.pyansys.com/version/stable/API/_autosummary/pyaedt.circuit.Circuit.html). -# -# ### Application keyword arguments -# -# - The argument ``non_graphical`` specifies whether an interactive session is launched or if -# AEDT is to run in non-graphical mode. -# - The Boolean parameter ``new_desktop`` specifies if a new instance -# of AEDT is launched. If it is set to ``False``, the API tries to connect to a running session. -# -# This example extracts an archived project. The full path -# to the extracted project is accessible from the ``cir.project_file`` property. - -# + -project_path = ansys.aedt.core.downloads.download_file( - source="custom_reports/", destination=temp_folder.name -) - -circuit = ansys.aedt.core.Circuit( - project=os.path.join(project_path, "CISPR25_Radiated_Emissions_Example23R1.aedtz"), - non_graphical=NG_MODE, - version=AEDT_VERSION, - new_desktop=True, -) -circuit.analyze() # Run the circuit analysis. -# - - -# ## Create a spectral report -# -# The JSON file is used to customize the report. In a spectral report, you can add limit lines. You can also -# add notes to a report and modify the axes, grid, and legend. Custom reports -# can be created in AEDT in non-graphical mode using version 2023 R2 and later. - -report1 = circuit.post.create_report_from_configuration( - os.path.join(project_path, "Spectrum_CISPR_Basic.json") -) -out = circuit.post.export_report_to_jpg( - project_path=circuit.working_directory, plot_name=report1.plot_name -) - -# Render the image. - -Image(os.path.join(circuit.working_directory, report1.plot_name + ".jpg")) - -# You can customize every aspect of the report. The method ``crate_report_from_configuration()`` reads the -# report configuration from a JSON file and generates the custom report. - -report1_full = circuit.post.create_report_from_configuration( - os.path.join(project_path, "Spectrum_CISPR_Custom.json") -) -out = circuit.post.export_report_to_jpg( - circuit.working_directory, report1_full.plot_name -) -Image(os.path.join(circuit.working_directory, report1_full.plot_name + ".jpg")) - -# ## Create a transient report -# -# The JSON configuration file can be read and modified from the API prior to creating the report. -# The following code modifies the trace rendering prior to creating the report. - -# + -props = ansys.aedt.core.general_methods.read_json( - os.path.join(project_path, "Transient_CISPR_Custom.json") -) - -report2 = circuit.post.create_report_from_configuration( - report_settings=props, solution_name="NexximTransient" -) -out = circuit.post.export_report_to_jpg(circuit.working_directory, report2.plot_name) -Image(os.path.join(circuit.working_directory, report2.plot_name + ".jpg")) -# - - -# The ``props`` dictionary can be used to customize any aspect of an existing report or generate a new report. -# In this example, the name of the curve is customized. - -props["expressions"] = {"V(Battery)": {}, "V(U1_VDD)": {}} -props["plot_name"] = "Battery Voltage" -report3 = circuit.post.create_report_from_configuration( - report_settings=props, solution_name="NexximTransient" -) -out = circuit.post.export_report_to_jpg(circuit.working_directory, report3.plot_name) -Image(os.path.join(circuit.working_directory, report3.plot_name + ".jpg")) - -# ## Create an eye diagram -# -# You can use the JSON file to create an eye diagram. The following code includes the eye. - -report4 = circuit.post.create_report_from_configuration( - os.path.join(project_path, "EyeDiagram_CISPR_Basic.json") -) -out = circuit.post.export_report_to_jpg(circuit.working_directory, report4.plot_name) -Image(os.path.join(circuit.working_directory, report4.plot_name + ".jpg")) - -# + -report4_full = circuit.post.create_report_from_configuration( - os.path.join(project_path, "EyeDiagram_CISPR_Custom.json") -) - -out = circuit.post.export_report_to_jpg( - circuit.working_directory, report4_full.plot_name -) -Image(os.path.join(circuit.working_directory, report4_full.plot_name + ".jpg")) -# - - -# ## Save project and close AEDT -# -# Save the project and close AEDT. The example has finished running. You can retrieve project files -# from ``temp_folder.name``. - -circuit.save_project() -print("Project Saved in {}".format(circuit.project_path)) - -circuit.release_desktop() -time.sleep(3) - -# ## Clean up -# -# The following cell cleans up the temporary directory and -# removes all project files. - -temp_folder.cleanup() diff --git a/examples/aedt_general/report/index.rst b/examples/aedt_general/report/index.rst deleted file mode 100644 index b55d60a62..000000000 --- a/examples/aedt_general/report/index.rst +++ /dev/null @@ -1,52 +0,0 @@ -Report -~~~~~~ - -These examples use PyAEDT to show some report capabilities. - -.. grid:: 2 - - .. grid-item-card:: PCIE virtual compliance - :padding: 2 2 2 2 - :link: virtual_compliance - :link-type: doc - - .. image:: _static/virtual_compliance_eye.png - :alt: Virtual compliance - :width: 250px - :height: 200px - :align: center - - This example shows how to generate a compliance report in PyAEDT using the VirtualCompliance class. - - .. grid-item-card:: Touchstone files - :padding: 2 2 2 2 - :link: touchstone_file - :link-type: doc - - .. image:: _static/touchstone_skitrf.png - :alt: Touchstone file - :width: 250px - :height: 200px - :align: center - - This example shows how to use objects in a Touchstone file without opening AEDT. - - .. grid-item-card:: Automatic report creation - :padding: 2 2 2 2 - :link: automatic_report - :link-type: doc - - .. image:: _static/automatic_report.png - :alt: Automatic report - :width: 250px - :height: 200px - :align: center - - This example shows how to create reports from a JSON template file. - -.. toctree:: - :hidden: - - virtual_compliance - touchstone_file - automatic_report diff --git a/examples/aedt_general/report/touchstone_file.py b/examples/aedt_general/report/touchstone_file.py deleted file mode 100644 index 240c1b6e3..000000000 --- a/examples/aedt_general/report/touchstone_file.py +++ /dev/null @@ -1,64 +0,0 @@ -# # Touchstone files -# -# This example shows how to use objects in a Touchstone file without opening AEDT. -# -# To provide the advanced postprocessing features needed for this example, Matplotlib and NumPy -# must be installed on your machine. -# -# This example runs only on Windows using CPython. -# -# Keywords: **Touchstone**, **report**. - -# ## Perform imports -# Import the required packages. - -from ansys.aedt.core import downloads -from ansys.aedt.core.visualization.advanced.touchstone_parser import \ - read_touchstone - -# ## Download example data - -example_path = downloads.download_touchstone() - -# ## Read the Touchstone file - -data = read_touchstone(example_path) - -# ## Plot data -# -# Get the curve plot by category. The following code shows how to plot lists of the return losses, -# insertion losses, next, and fext based on a few inputs and port names. - -data.plot_return_losses() -data.plot_insertion_losses() -data.plot_next_xtalk_losses("U1") -data.plot_fext_xtalk_losses(tx_prefix="U1", rx_prefix="U7") - -# ## Identify cross-talk -# -# Identify the worst case cross-talk. - -worst_rl, global_mean = data.get_worst_curve( - freq_min=1, - freq_max=20, - worst_is_higher=True, - curve_list=data.get_return_loss_index(), -) -worst_il, mean2 = data.get_worst_curve( - freq_min=1, - freq_max=20, - worst_is_higher=False, - curve_list=data.get_insertion_loss_index(), -) -worst_fext, mean3 = data.get_worst_curve( - freq_min=1, - freq_max=20, - worst_is_higher=True, - curve_list=data.get_fext_xtalk_index_from_prefix(tx_prefix="U1", rx_prefix="U7"), -) -worst_next, mean4 = data.get_worst_curve( - freq_min=1, - freq_max=20, - worst_is_higher=True, - curve_list=data.get_next_xtalk_index("U1"), -) diff --git a/examples/aedt_general/report/virtual_compliance.py b/examples/aedt_general/report/virtual_compliance.py deleted file mode 100644 index 36ddb958b..000000000 --- a/examples/aedt_general/report/virtual_compliance.py +++ /dev/null @@ -1,220 +0,0 @@ -# # PCIE virtual compliance -# -# This example shows how to generate a compliance report in PyAEDT using -# the ``VirtualCompliance`` class. -# -# Keywords: **Circuit**, **Automatic report**, **virtual compliance**. - - -# ## Perform imports and define constants -# Import the required packages. - -import os.path -import tempfile -import time - -import ansys.aedt.core -from ansys.aedt.core.visualization.post.compliance import VirtualCompliance - -# ## Define constants - -AEDT_VERSION = "2024.2" -NUM_CORES = 4 -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. In this example, the temporary directory -# in where the example is stored and simulation data is saved. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Download example data - -download_folder = ansys.aedt.core.downloads.download_file( - source="pcie_compliance", destination=temp_folder.name -) -project_folder = os.path.join(download_folder, "project") -project_path = os.path.join(project_folder, "PCIE_GEN5_only_layout.aedtz") - -# ## Launch AEDT and solve layout -# -# Open the HFSS 3D Layout project and analyze it using the SIwave solver. -# Before solving, this code ensures that the model is solved from DC to 70GHz and that -# causality and passivity are enforced. - -h3d = ansys.aedt.core.Hfss3dLayout( - project=project_path, version=AEDT_VERSION, non_graphical=NG_MODE -) -h3d.remove_all_unused_definitions() -h3d.edit_cosim_options(simulate_missing_solution=False) -h3d.setups[0].sweeps[0].props["EnforcePassivity"] = True -h3d.setups[0].sweeps[0].props["Sweeps"]["Data"] = "LIN 0MHz 70GHz 0.1GHz" -h3d.setups[0].sweeps[0].props["EnforceCausality"] = True -h3d.setups[0].sweeps[0].update() -h3d.analyze(cores=NUM_CORES) -h3d = ansys.aedt.core.Hfss3dLayout() -touchstone_path = h3d.export_touchstone() - -# ## Create LNA project -# -# Use the LNA (linear network analysis) setup to retrieve Touchstone files -# and generate frequency domain reports. - -circuit = ansys.aedt.core.Circuit(project=h3d.project_name, design="Touchstone") -status, diff_pairs, comm_pairs = circuit.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"], - analyze=True, -) -insertion = circuit.get_all_insertion_loss_list( - drivers=diff_pairs, - receivers=diff_pairs, - drivers_prefix_name="X1", - receivers_prefix_name="U1", - math_formula="dB", - nets=["RX0", "RX1", "RX2", "RX3"], -) -return_diff = circuit.get_all_return_loss_list( - excitations=diff_pairs, - excitation_name_prefix="X1", - math_formula="dB", - nets=["RX0", "RX1", "RX2", "RX3"], -) -return_comm = circuit.get_all_return_loss_list( - excitations=comm_pairs, - excitation_name_prefix="COMMON_X1", - math_formula="dB", - nets=["RX0", "RX1", "RX2", "RX3"], -) - -# ## Create TDR project -# -# Create a TDR project to compute transient simulation and retrieve -# the TDR measurement on a differential pair. -# The original circuit schematic is duplicated and modified to achieve this target. - -result, tdr_probe_name = circuit.create_tdr_schematic_from_snp( - input_file=touchstone_path, - tx_schematic_pins=["X1.A2.PCIe_Gen4_RX0_P"], - tx_schematic_differential_pins=["X1.A3.PCIe_Gen4_RX0_N"], - termination_pins=["U1.AP26.PCIe_Gen4_RX0_P", "U1.AN26.PCIe_Gen4_RX0_N"], - differential=True, - rise_time=35, - use_convolution=True, - analyze=True, - design_name="TDR", -) - -# ## Create AMI project -# -# Create an Ibis AMI project to compute an eye diagram simulation and retrieve -# eye mask violations. - -_, eye_curve_tx, eye_curve_rx = circuit.create_ami_schematic_from_snp( - input_file=touchstone_path, - ibis_tx_file=os.path.join(project_folder, "models", "pcieg5_32gt.ibs"), - tx_buffer_name="1p", - rx_buffer_name="2p", - tx_schematic_pins=["U1.AM25.PCIe_Gen4_TX0_CAP_P"], - rx_schematic_pins=["X1.B2.PCIe_Gen4_TX0_P"], - tx_schematic_differential_pins=["U1.AL25.PCIe_Gen4_TX0_CAP_N"], - rx_schematic_differentialial_pins=["X1.B3.PCIe_Gen4_TX0_N"], - ibis_tx_component_name="Spec_Model", - use_ibis_buffer=False, - differential=True, - bit_pattern="random_bit_count=2.5e3 random_seed=1", - unit_interval="31.25ps", - use_convolution=True, - analyze=True, - design_name="AMI", -) - -circuit.save_project() - -# ## Create virtual compliance report -# -# Initialize the ``VirtualCompliance`` class -# and set up the main project information needed to generate the report. -# - -# - -# - -template = os.path.join(download_folder, "pcie_gen5_templates", "main.json") - -v = VirtualCompliance(circuit.desktop_class, str(template)) - -# ## Customize project and design -# -# Define the path to the project file and the -# design names to be used in each report generation. -# -# - -v.project_file = circuit.project_file -v.reports["insertion losses"].design_name = "LNA" -v.reports["return losses"].design_name = "LNA" -v.reports["common mode return losses"].design_name = "LNA" -v.reports["tdr from circuit"].design_name = "TDR" -v.reports["eye1"].design_name = "AMI" -v.reports["eye3"].design_name = "AMI" -v.parameters["erl"].design_name = "LNA" -v.specs_folder = os.path.join(download_folder, "readme_pictures") - -# ## Define trace names -# -# Change the trace name with projects and users. -# Reuse the compliance template and update traces accordingly. - -v.reports["insertion losses"].traces = insertion - -v.reports["return losses"].traces = return_diff - -v.reports["common mode return losses"].traces = return_comm - -v.reports["eye1"].traces = eye_curve_tx -v.reports["eye3"].traces = eye_curve_tx -v.reports["tdr from circuit"].traces = tdr_probe_name -v.parameters["erl"].trace_pins = [ - [ - "X1.A5.PCIe_Gen4_RX1_P", - "X1.A6.PCIe_Gen4_RX1_N", - "U1.AR25.PCIe_Gen4_RX1_P", - "U1.AP25.PCIe_Gen4_RX1_N", - ], - [7, 8, 18, 17], -] - -# ## Generate PDF report -# -# Generate the reports and produce a PDF report. -# -# -# -# - -v.create_compliance_report() - -# ## Release AEDT - -h3d.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. -# If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell -# removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/basic/_static/logo.png b/examples/basic/_static/logo.png deleted file mode 100644 index e0d706677..000000000 Binary files a/examples/basic/_static/logo.png and /dev/null differ diff --git a/examples/electrothermal/_static/bdf.png b/examples/electrothermal/_static/bdf.png deleted file mode 100644 index ad9a532a3..000000000 Binary files a/examples/electrothermal/_static/bdf.png and /dev/null differ diff --git a/examples/electrothermal/_static/coaxial.png b/examples/electrothermal/_static/coaxial.png deleted file mode 100644 index 4eefdded6..000000000 Binary files a/examples/electrothermal/_static/coaxial.png and /dev/null differ diff --git a/examples/electrothermal/_static/component.png b/examples/electrothermal/_static/component.png deleted file mode 100644 index 7a4e5eed6..000000000 Binary files a/examples/electrothermal/_static/component.png and /dev/null differ diff --git a/examples/electrothermal/_static/ecad.png b/examples/electrothermal/_static/ecad.png deleted file mode 100644 index b561e7622..000000000 Binary files a/examples/electrothermal/_static/ecad.png and /dev/null differ diff --git a/examples/electrothermal/_static/electrothermal.png b/examples/electrothermal/_static/electrothermal.png deleted file mode 100644 index 0f8fc3962..000000000 Binary files a/examples/electrothermal/_static/electrothermal.png and /dev/null differ diff --git a/examples/electrothermal/_static/graphic.png b/examples/electrothermal/_static/graphic.png deleted file mode 100644 index 4b59e22d4..000000000 Binary files a/examples/electrothermal/_static/graphic.png and /dev/null differ diff --git a/examples/electrothermal/_static/icepak_csv.png b/examples/electrothermal/_static/icepak_csv.png deleted file mode 100644 index 24a4df0f5..000000000 Binary files a/examples/electrothermal/_static/icepak_csv.png and /dev/null differ diff --git a/examples/electrothermal/_static/icepak_logo.png b/examples/electrothermal/_static/icepak_logo.png deleted file mode 100644 index 3ccf55fd1..000000000 Binary files a/examples/electrothermal/_static/icepak_logo.png and /dev/null differ diff --git a/examples/electrothermal/_static/ldf.png b/examples/electrothermal/_static/ldf.png deleted file mode 100644 index 43646374e..000000000 Binary files a/examples/electrothermal/_static/ldf.png and /dev/null differ diff --git a/examples/electrothermal/_static/ring.png b/examples/electrothermal/_static/ring.png deleted file mode 100644 index cfb5cc205..000000000 Binary files a/examples/electrothermal/_static/ring.png and /dev/null differ diff --git a/examples/electrothermal/_static/sherlock.png b/examples/electrothermal/_static/sherlock.png deleted file mode 100644 index a3206d226..000000000 Binary files a/examples/electrothermal/_static/sherlock.png and /dev/null differ diff --git a/examples/electrothermal/coaxial_hfss_icepak.py b/examples/electrothermal/coaxial_hfss_icepak.py deleted file mode 100644 index f39c1fb03..000000000 --- a/examples/electrothermal/coaxial_hfss_icepak.py +++ /dev/null @@ -1,422 +0,0 @@ -# # Coaxial -# -# This example shows how to create a project from scratch in HFSS and Icepak. -# This includes creating a setup, solving it, and creating postprocessing outputs. -# -# Keywords: **Multiphysics**, **HFSS**, **Icepak**. - -# ## Perform imports and define constants -# -# Perform required imports. - -import os -import tempfile -import time - -import ansys.aedt.core -from ansys.aedt.core.visualization.plot.pdf import AnsysReport - -# Define constants. - -AEDT_VERSION = "2024.2" -NUM_CORES = 4 -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Launch AEDT and initialize HFSS -# -# Launch AEDT and initialize HFSS. If there is an active HFSS design, the ``hfss`` -# object is linked to it. Otherwise, a new design is created. - -hfss = ansys.aedt.core.Hfss( - project=os.path.join(temp_folder.name, "Icepak_HFSS_Coupling"), - design="RF", - version=AEDT_VERSION, - non_graphical=NG_MODE, - new_desktop=True, - solution_type="Modal", -) - -# ## Define parameters -# -# Parameters can be instantiated by defining them as a key used for the application -# instance as demonstrated in the following code. The prefix ``$`` is used to define -# a project-wide scope for the parameter. Otherwise, the parameter scope is limited to -# the current design. - -hfss["$coax_dimension"] = "100mm" # Project-wide scope. -udp = hfss.modeler.Position(0, 0, 0) -hfss["inner"] = "3mm" # Local "Design" scope. - -# ## Create coaxial and cylinders -# -# Create a coaxial and three cylinders. You can apply parameters -# directly using the `ansys.aedt.core.modeler.Primitives3D.Primitives3D.create_cylinder()` -# method. You can assign a material directly to the object creation action. -# Optionally, you can assign a material using the `assign_material()` method. - -o1 = hfss.modeler.create_cylinder( - orientation=hfss.PLANE.ZX, - origin=udp, - radius="inner", - height="$coax_dimension", - num_sides=0, - name="inner", -) -o2 = hfss.modeler.create_cylinder( - orientation=hfss.PLANE.ZX, - origin=udp, - radius=8, - height="$coax_dimension", - num_sides=0, - name="teflon_based", -) -o3 = hfss.modeler.create_cylinder( - orientation=hfss.PLANE.ZX, - origin=udp, - radius=10, - height="$coax_dimension", - num_sides=0, - name="outer", -) - -# ## Assign colors -# -# Assign colors to each primitive. - -o1.color = (255, 0, 0) -o2.color = (0, 255, 0) -o3.color = (255, 0, 0) -o3.transparency = 0.8 -hfss.modeler.fit_all() - -# ## Assign materials -# -# Assign materials. You can assign materials either directly when creating the primitive, -# which was done for ``id2``, or after the object is created. - -o1.material_name = "Copper" -o3.material_name = "Copper" - -# ## Perform modeler operations -# -# Perform modeler operations. You can subtract, add, and perform other operations -# using either the object ID or object name. - -hfss.modeler.subtract(o3, o2, True) -hfss.modeler.subtract(o2, o1, True) - -# ## Assign mesh operations -# -# Most mesh operations are accessible using the ``mesh`` property, -# which is an instance of the ``ansys.aedt.core.modules.MeshIcepak.IcepakMesh`` class. -# -# This code shows how to use several common mesh operations. - -hfss.mesh.assign_initial_mesh_from_slider(level=6) -hfss.mesh.assign_model_resolution(assignment=[o1.name, o3.name], defeature_length=None) -hfss.mesh.assign_length_mesh( - assignment=o2.faces, inside_selection=False, maximum_length=1, maximum_elements=2000 -) - -# ## Create HFSS sources -# -# The RF power dissipated in the HFSS model acts as the thermal -# source for in Icepak. The ``create_wave_port_between_objects()`` method -# is used to assign the RF ports that inject RF power into the HFSS -# model. If ``add_pec_cap=True``, then the method -# creates a perfectly conducting (lossless) cap covering the port. - -# + -hfss.wave_port( - assignment="inner", - reference="outer", - integration_line=1, - create_port_sheet=True, - create_pec_cap=True, - name="P1", -) - -hfss.wave_port( - assignment="inner", - reference="outer", - integration_line=4, - create_pec_cap=True, - create_port_sheet=True, - name="P2", -) - -port_names = hfss.get_all_sources() -hfss.modeler.fit_all() -# - - -# ## Set up simulation -# -# Create a HFSS setup with default values. After its creation, -# you can change values and update the setup. The ``update()`` method returns a Boolean -# value. - -hfss.set_active_design(hfss.design_name) -setup = hfss.create_setup("MySetup") -setup.props["Frequency"] = "1GHz" -setup.props["BasisOrder"] = 2 -setup.props["MaximumPasses"] = 1 - -# ## Create frequency sweep -# -# The HFSS frequency sweep defines the RF frequency range over which the RF power is -# injected into the structure. - -sweepname = hfss.create_linear_count_sweep( - setup="MySetup", - units="GHz", - start_frequency=0.8, - stop_frequency=1.2, - num_of_freq_points=401, - sweep_type="Interpolating", -) - -# ## Create Icepak model -# -# After an HFSS setup has been defined, the model can be lnked to an Icepak -# design. The coupled physics analysis can then be run. The `FieldAnalysis3D.copy_solid_bodies_from()` -# method imports a model from HFSS into Icepak, including all material definitions. - -ipk = ansys.aedt.core.Icepak(design="CalcTemp", version=AEDT_VERSION) -ipk.copy_solid_bodies_from(hfss) - -# ## Link RF thermal source -# -# The RF loss in HFSS is used as the thermal source in Icepak. - -surfaceobj = ["inner", "outer"] -ipk.assign_em_losses( - design=hfss.design_name, - setup="MySetup", - sweep="LastAdaptive", - map_frequency="1GHz", - surface_objects=surfaceobj, - parameters=["$coax_dimension", "inner"], -) - -# ## Set direction of gravity -# -# Set the direction of gravity for convection in Icepak. Gravity drives a temperature gradient -# due to the dependence of gas density on temperature. - -ipk.edit_design_settings(hfss.GRAVITY.ZNeg) - -# ## Set up Icepak Project -# -# The initial solution setup applies default values that can subsequently -# be modified as shown in the following code. -# The ``props`` property enables access to all solution settings. -# -# The ``update`` function applies the settings to the setup. The setup creation -# process is identical for all tools. - -setup_ipk = ipk.create_setup("SetupIPK") -setup_ipk.props["Convergence Criteria - Max Iterations"] = 3 - -# ### Access Icepak solution properties -# -# Setup properties are accessible through the ``props`` property as -# an ordered dictionary. You can use the ``keys()`` method to retrieve all settings for -# the setup. -# -# Find properties that contain the string ``"Convergence"`` and print the default values. - -conv_props = [k for k in setup_ipk.props.keys() if "Convergence" in k] -print("Here are some default setup properties:") -for p in conv_props: - print('"' + p + '" -> ' + str(setup_ipk.props[p])) - -# ### Edit or review mesh parameters -# -# Edit or review the mesh parameters. After a mesh is created, you can access -# a mesh operation to edit or review parameter values. - -airbox = ipk.modeler.get_obj_id("Region") -ipk.modeler[airbox].display_wireframe = True -airfaces = ipk.modeler.get_object_faces(airbox) -ipk.assign_openings(airfaces) - -# Save the project and attach to the Icepak instance. - -hfss.save_project() -ipk = ansys.aedt.core.Icepak(version=AEDT_VERSION) -ipk.solution_type = ipk.SOLUTIONS.Icepak.SteadyTemperatureAndFlow -ipk.modeler.fit_all() - -# ## Solve models -# -# Solve the Icepak and HFSS models. - -ipk.setups[0].analyze(cores=NUM_CORES, tasks=NUM_CORES) -hfss.save_project() -hfss.modeler.fit_all() -hfss.setups[0].analyze() - -# ### Plot and export results -# -# Generate field plots in the HFSS project and export them as images. - -# + -quantity_name = "ComplexMag_H" -intrinsic = {"Freq": hfss.setups[0].props["Frequency"], "Phase": "0deg"} -surface_list = hfss.modeler.get_object_faces("outer") -plot1 = hfss.post.create_fieldplot_surface( - assignment=surface_list, - quantity=quantity_name, - setup=hfss.nominal_adaptive, - intrinsics=intrinsic, -) - -hfss.post.plot_field_from_fieldplot( - plot1.name, - project_path=temp_folder.name, - mesh_plot=False, - image_format="jpg", - view="isometric", - show=False, - plot_cad_objs=False, - log_scale=False, - file_format="aedtplt", -) -# - - -# ## Generate animation from field plots -# -# Generate an animation from field plots using PyVista. - -# + -start = time.time() -cutlist = ["Global:XY"] -phase_values = [str(i * 5) + "deg" for i in range(18)] - -animated = hfss.post.plot_animated_field( - quantity="Mag_E", - assignment=cutlist, - plot_type="CutPlane", - setup=hfss.nominal_adaptive, - intrinsics=intrinsic, - export_path=temp_folder.name, - variation_variable="Phase", - variations=phase_values, - show=False, - export_gif=False, - log_scale=True, -) -animated.gif_file = os.path.join(temp_folder.name, "animate.gif") - -# Set off_screen to False to visualize the animation. -# animated.off_screen = False - -animated.animate() - -end_time = time.time() - start -print("Total Time", end_time) -# - - -# ## Postprocess -# -# Create Icepak plots and export them as images using the same functions that -# were used early. Only the quantity is different. - -# + -setup_name = ipk.existing_analysis_sweeps[0] -intrinsic = "" -surface_list = ipk.modeler.get_object_faces("inner") + ipk.modeler.get_object_faces( - "outer" -) -plot5 = ipk.post.create_fieldplot_surface(surface_list, quantity="SurfTemperature") - -hfss.save_project() -# - - -# Plot results using Matplotlib. - -trace_names = hfss.get_traces_for_plot(category="S") -context = ["Domain:=", "Sweep"] -families = ["Freq:=", ["All"]] -my_data = hfss.post.get_solution_data(expressions=trace_names) -my_data.plot( - trace_names, - formula="db20", - x_label="Frequency (Ghz)", - y_label="SParameters(dB)", - title="Scattering Chart", - snapshot_path=os.path.join(temp_folder.name, "Touchstone_from_matplotlib.jpg"), -) - -# Create a PDF report summarizig results. - -pdf_report = AnsysReport( - project_name=hfss.project_name, design_name=hfss.design_name, version=AEDT_VERSION -) - -# Create the report. - -pdf_report.create() - -# Add a section for plots. - -pdf_report.add_section() -pdf_report.add_chapter("HFSS Results") -pdf_report.add_sub_chapter("Field plot") -pdf_report.add_text("This section contains field plots of HFSS Coaxial.") -pdf_report.add_image( - os.path.join(temp_folder.name, plot1.name + ".jpg"), caption="Coaxial cable" -) - -# Add a page break and a subchapter for S Parameter results. - -pdf_report.add_page_break() -pdf_report.add_sub_chapter("S Parameters") -pdf_report.add_chart( - x_values=my_data.intrinsics["Freq"], - y_values=my_data.data_db20(), - x_caption="Freq", - y_caption=trace_names[0], - title="S-Parameters", -) -pdf_report.add_image( - path=os.path.join(temp_folder.name, "Touchstone_from_matplotlib.jpg"), - caption="Touchstone from Matplotlib", -) - -# Add a new section for Icepak results. - -pdf_report.add_section() -pdf_report.add_chapter("Icepak Results") -pdf_report.add_sub_chapter("Temperature Plot") -pdf_report.add_text("This section contains Multiphysics temperature plot.") - -# Add table of content and save the PDF. - -pdf_report.add_toc() -pdf_report.save_pdf(file_path=temp_folder.name, file_name="AEDT_Results.pdf") - -# ## Release AEDT -# -# Release AEDT and close the example. - -ipk.save_project() -hfss.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/electrothermal/component_3d.py b/examples/electrothermal/component_3d.py deleted file mode 100644 index 58ef5b26f..000000000 --- a/examples/electrothermal/component_3d.py +++ /dev/null @@ -1,255 +0,0 @@ -# # Thermal analysis with 3D components - -# This example shows how to create a thermal analysis of an electronic package by -# taking advantage of 3D components with advanced features added by PyAEDT. -# -# Keywords: **Icepak**, **3D components**, **mesh regions**, **monitor objects**. - -# ## Perform imports and define constants -# -# Perform required imports. - -import os -import tempfile -import time - -from ansys.aedt.core import Icepak, downloads - -# Define constants. - -AEDT_VERSION = "2024.2" -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Create temporary directory and download files -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") -package_temp_name, qfp_temp_name = downloads.download_icepak_3d_component( - destination=temp_folder.name -) - -# ## Create heatsink -# Create an empty project in non-graphical mode. - -ipk = Icepak( - project=os.path.join(temp_folder.name, "Heatsink.aedt"), - version=AEDT_VERSION, - non_graphical=NG_MODE, - close_on_exit=True, - new_desktop=True, -) - -# Remove the air region, which is present by default. An air region is not needed as the heatsink -# is to be exported as a 3D component. - -ipk.modeler["Region"].delete() - -# Define the heatsink using multiple boxes. - -hs_base = ipk.modeler.create_box( - origin=[0, 0, 0], sizes=[37.5, 37.5, 2], name="HS_Base" -) -hs_base.material_name = "Al-Extruded" -hs_fin = ipk.modeler.create_box(origin=[0, 0, 2], sizes=[37.5, 1, 18], name="HS_Fin1") -hs_fin.material_name = "Al-Extruded" -n_fins = 11 -hs_fins = hs_fin.duplicate_along_line(vector=[0, 3.65, 0], clones=n_fins) - -ipk.plot(show=False, output_file=os.path.join(temp_folder.name, "Heatsink.jpg")) - -# Define a mesh region around the heatsink. - -mesh_region = ipk.mesh.assign_mesh_region( - assignment=[hs_base.name, hs_fin.name] + hs_fins -) -mesh_region.manual_settings = True -mesh_region.settings["MaxElementSizeX"] = "5mm" -mesh_region.settings["MaxElementSizeY"] = "5mm" -mesh_region.settings["MaxElementSizeZ"] = "1mm" -mesh_region.settings["MinElementsInGap"] = 4 -mesh_region.settings["MaxLevels"] = 2 -mesh_region.settings["BufferLayers"] = 2 -mesh_region.settings["EnableMLM"] = True -mesh_region.settings["UniformMeshParametersType"] = "Average" -mesh_region.update() - -# Assign monitor objects. - -hs_middle_fin = ipk.modeler.get_object_from_name(assignment=hs_fins[n_fins // 2]) -point_monitor_position = [ - 0.5 * (hs_base.bounding_box[i] + hs_base.bounding_box[i + 3]) for i in range(2) -] + [ - hs_middle_fin.bounding_box[-1] -] # average x,y, top z -ipk.monitor.assign_point_monitor( - point_position=point_monitor_position, - monitor_quantity=["Temperature", "HeatFlux"], - monitor_name="TopPoint", -) -ipk.monitor.assign_face_monitor( - face_id=hs_base.bottom_face_z.id, - monitor_quantity="Temperature", - monitor_name="Bottom", -) -ipk.monitor.assign_point_monitor_in_object( - name=hs_middle_fin.name, - monitor_quantity="Temperature", - monitor_name="MiddleFinCenter", -) - -# Export the heatsink 3D component to a ``"componentLibrary"`` folder. -# The ``auxiliary_dict`` parameter is set to ``True`` to export the monitor objects -# along with the A3DCOMP file. - -os.mkdir(os.path.join(temp_folder.name, "componentLibrary")) -ipk.modeler.create_3dcomponent( - input_file=os.path.join(temp_folder.name, "componentLibrary", "Heatsink.a3dcomp"), - name="Heatsink", - export_auxiliary=True, -) -ipk.close_project(save=False) - -# ## Create QFP -# Open the previously downloaded project containing a QPF. - -ipk = Icepak(project=qfp_temp_name, version=AEDT_VERSION) -ipk.plot(show=False, output_file=os.path.join(temp_folder.name, "QFP2.jpg")) - -# Create a dataset for power dissipation. - -x_datalist = [45, 53, 60, 70] -y_datalist = [0.5, 3, 6, 9] -ipk.create_dataset( - name="PowerDissipationDataset", - x=x_datalist, - y=y_datalist, - is_project_dataset=False, - x_unit="cel", - y_unit="W", -) - -# Assign a source power condition to the die. - -ipk.create_source_power( - face_id="DieSource", - thermal_dependent_dataset="PowerDissipationDataset", - source_name="DieSource", -) - -# Assign thickness to the die attach surface. - -ipk.assign_conducting_plate_with_thickness( - obj_plate="Die_Attach", - shell_conduction=True, - thickness="0.05mm", - solid_material="Epoxy Resin-Typical", - boundary_name="Die_Attach", -) - -# Assign monitor objects. - -ipk.monitor.assign_point_monitor_in_object( - name="QFP2_die", monitor_quantity="Temperature", monitor_name="DieCenter" -) -ipk.monitor.assign_surface_monitor( - surface_name="Die_Attach", monitor_quantity="Temperature", monitor_name="DieAttach" -) - -# Export the QFP 3D component in the ``"componentLibrary"`` folder and close the project. -# Here the auxiliary dictionary allows exporting not only the monitor objects but also the dataset -# used for the power source assignment. - -ipk.modeler.create_3dcomponent( - input_file=os.path.join(temp_folder.name, "componentLibrary", "QFP.a3dcomp"), - name="QFP", - export_auxiliary=True, - datasets=["PowerDissipationDataset"], -) -ipk.release_desktop(close_projects=False, close_desktop=False) - -# ## Create complete electronic package -# Download and open a project containing the electronic package. - -ipk = Icepak( - project=package_temp_name, - version=AEDT_VERSION, - non_graphical=NG_MODE, -) -ipk.plot( - assignment=[o for o in ipk.modeler.object_names if not o.startswith("DomainBox")], - show=False, - output_file=os.path.join(temp_folder.name, "electronic_package_missing_obj.jpg"), -) - -# The heatsink and the QFP are missing. They can be inserted as 3D components. -# The auxiliary files are needed because the goal is to also import monitor objects and datasets. - -# Create a coordinate system for the heatsink so that it is placed on top of the AGP. - -# + -agp = ipk.modeler.get_object_from_name(assignment="AGP_IDF") -cs = ipk.modeler.create_coordinate_system( - origin=[agp.bounding_box[0], agp.bounding_box[1], agp.bounding_box[-1]], - name="HeatsinkCS", - reference_cs="Global", - x_pointing=[1, 0, 0], - y_pointing=[0, 1, 0], -) -heatsink_obj = ipk.modeler.insert_3d_component( - input_file=os.path.join(temp_folder.name, "componentLibrary", "Heatsink.a3dcomp"), - coordinate_system="HeatsinkCS", - auxiliary_parameters=True, -) - -QFP2_obj = ipk.modeler.insert_3d_component( - input_file=os.path.join(temp_folder.name, "componentLibrary", "QFP.a3dcomp"), - coordinate_system="Global", - auxiliary_parameters=True, -) - -ipk.plot( - assignment=[o for o in ipk.modeler.object_names if not o.startswith("DomainBox")], - show=False, - plot_air_objects=False, - output_file=os.path.join(temp_folder.name, "electronic_package.jpg"), - force_opacity_value=0.5, -) -# - - -# Create a coordinate system at the xmin, ymin, and zmin of the model. - -bounding_box = ipk.modeler.get_model_bounding_box() -cs_pcb_assembly = ipk.modeler.create_coordinate_system( - origin=[bounding_box[0], bounding_box[1], bounding_box[2]], - name="PCB_Assembly", - reference_cs="Global", - x_pointing=[1, 0, 0], - y_pointing=[0, 1, 0], -) - -# Export the entire assembly as a 3D component and close the project. First, the nested -# hierarchy must be flattened because nested 3D components are currently not supported. Subsequently, -# the whole package can be exported as a 3D component. The auxiliary dictionary is needed -# to export monitor objects, datasets, and native components. - -ipk.flatten_3d_components() - -# ## Release AEDT - -ipk.save_project() -ipk.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. -# If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell -# removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/electrothermal/components_csv.py b/examples/electrothermal/components_csv.py deleted file mode 100644 index fb4c69848..000000000 --- a/examples/electrothermal/components_csv.py +++ /dev/null @@ -1,244 +0,0 @@ -# # PCB component definition from CSV file and model image exports - -# This example shows how to create different types of blocks and assign power -# and material to them using a CSV input file -# -# Keywords: **Icepak**, **boundaries**, **PyVista**, **CSV**, **PCB**, **components**. - -# ## Perform imports and define constants - -# + -import csv -import os -import tempfile -import time -from pathlib import Path - -import ansys.aedt.core -import matplotlib as mpl -import numpy as np -import pyvista as pv -from IPython.display import Image -from matplotlib import cm -from matplotlib import pyplot as plt - -# - - -# Define constants. - -AEDT_VERSION = "2024.2" -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Download and open project -# -# Download the project and open it in non-graphical mode, using a temporary folder. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") -project_name = os.path.join(temp_folder.name, "Icepak_CSV_Import.aedt") -ipk = ansys.aedt.core.Icepak( - project=project_name, - version=AEDT_VERSION, - new_desktop=True, - non_graphical=NG_MODE, -) - -# Create the PCB as a simple block with lumped material properties. - -board = ipk.modeler.create_box( - origin=[-30.48, -27.305, 0], - sizes=[146.685, 71.755, 0.4064], - name="board_outline", - material="FR-4_Ref", -) - -# ## Create components from CSV file -# -# Components are represented as simple cubes with dimensions and properties specified in a CSV file. - -filename = ansys.aedt.core.downloads.download_file( - "icepak", "blocks-list.csv", destination=temp_folder.name -) - -# The CSV file lists block properties: -# -# - Type (solid, network, hollow) -# - Name -# - Dtart point (xs, ys, zs) and end point (xd, yd, zd) -# - Material properties (for solid blocks) -# - Power assignment -# - Resistances to the board and to the case (for network blocks) -# - Whether to add a monitor point to the block (0 or 1) -# -# The following table does not show entire rows and dat. It provides only a sample. -# -# -# | block_type | name | xs | ys | zs | xd | yd | zd | matname | power | Rjb | Rjc | Monitor_point | -# |------------|------|--------|--------|------|-------|-------|------|------------------|-------|-----|-----|---------------| -# | hollow | R8 | 31.75 | -20.32 | 0.40 | 15.24 | 2.54 | 2.54 | | 1 | | | 0 | -# | solid | U1 | 16.55 | 10.20 | 0.40 | 10.16 | 20.32 | 5.08 | Ceramic_material | 0.2 | | | 1 | -# | solid | U2 | -51 | 10.16 | 0.40 | 10.16 | 27.94 | 5.08 | Ceramic_material | 0.1 | | | 1 | -# | network | C180 | 47.62 | 19.05 | 0.40 | 3.81 | 2.54 | 2.43 | | 1.13 | 2 | 3 | 0 | -# | network | C10 | 65.40 | -1.27 | 0.40 | 3.81 | 2.54 | 2.43 | | 0.562 | 2 | 3 | 0 | -# | network | C20 | 113.03 | -0.63 | 0.40 | 2.54 | 3.81 | 2.43 | | 0.445 | 2 | 3 | 0 | -# -# The following code loops over each line of the CSV file, creating solid blocks -# and assigning boundary conditions. -# -# Every row of the CSV file has information on a particular block. - -# + -with open(filename, "r") as csv_file: - csv_reader = csv.DictReader(csv_file) - for row in csv_reader: - origin = [ - float(row["xs"]), - float(row["ys"]), - float(row["zs"]), - ] # block starting point - dimensions = [ - float(row["xd"]), - float(row["yd"]), - float(row["zd"]), - ] # block lengths in 3 dimensions - block_name = row["name"] # block name - - # Define material name - if row["matname"]: - material_name = row["matname"] - else: - material_name = "copper" - - # Creates the block with the given name, coordinates, material, and type - block = ipk.modeler.create_box( - origin=origin, sizes=dimensions, name=block_name, material=material_name - ) - - # Assign boundary conditions - if row["block_type"] == "solid": - ipk.assign_solid_block( - object_name=block_name, - power_assignment=row["power"] + "W", - boundary_name=block_name, - ) - elif row["block_type"] == "network": - ipk.create_two_resistor_network_block( - object_name=block_name, - pcb=board.name, - power=row["power"] + "W", - rjb=row["Rjb"], - rjc=row["Rjc"], - ) - else: - ipk.modeler[block.name].solve_inside = False - ipk.assign_hollow_block( - object_name=block_name, - assignment_type="Total Power", - assignment_value=row["power"] + "W", - boundary_name=block_name, - ) - - # Create temperature monitor points if assigned value is 1 in the last - # column of the CSV file - if row["Monitor_point"] == "1": - ipk.monitor.assign_point_monitor_in_object( - name=row["name"], - monitor_quantity="Temperature", - monitor_name=row["name"], - ) -# - - - -# ## Calculate the power assigned to all components - -power_budget, total_power = ipk.post.power_budget(units="W") - -# ## Plot model using AEDT -# -# Set the colormap to use. You can use the previously computed power budget to set the minimum and maximum values. - -cmap = plt.get_cmap("plasma") -norm = mpl.colors.Normalize( - vmin=min(power_budget.values()), vmax=max(power_budget.values()) -) -scalarMap = cm.ScalarMappable(norm=norm, cmap=cmap) - -# Color the objects depending -for obj in ipk.modeler.objects.values(): - if obj.name in power_budget: - obj.color = [ - int(i * 255) for i in scalarMap.to_rgba(power_budget[obj.name])[0:3] - ] - obj.transparency = 0 - else: - obj.color = [0, 0, 0] - obj.transparency = 0.9 - -# Export the model image by creating a list of all objects that excludes ``Region``. -# This list is then passed to the `export_model_picture()` function. -# This approach ensures that the exported image is fitted to the PCB and its components. - -obj_list_noregion = list(ipk.modeler.object_names) -obj_list_noregion.remove("Region") -export_file = os.path.join(temp_folder.name, "object_power_AEDTExport.jpg") -ipk.post.export_model_picture( - export_file, selections=obj_list_noregion, width=1920, height=1080 -) -Image(export_file) - -# ### Plot model using PyAEDT -# -# Initialize a PyVista plotter -plotter = pv.Plotter(off_screen=True, window_size=[2048, 1536]) - -# Export all models objects to OBJ files. - -f = ipk.post.export_model_obj( - export_path=temp_folder.name, export_as_single_objects=True, air_objects=False -) - -# Add objects to the PyVista plotter. These objects are either set to a black color or assigned scalar values, -# allowing them to be visualized with a colormap. - -for file, color, opacity in f: - if color == (0, 0, 0): - plotter.add_mesh(mesh=pv.read(file), color="black", opacity=opacity) - else: - mesh = pv.read(filename=file) - mesh["Power"] = np.full( - shape=mesh.n_points, fill_value=power_budget[Path(file).stem] - ) - plotter.add_mesh(mesh=mesh, scalars="Power", cmap="viridis", opacity=opacity) - -# Add a label to the object with the maximum temperature. - -max_pow_obj = "MP1" -plotter.add_point_labels( - points=[ipk.modeler[max_pow_obj].top_face_z.center], - labels=[f"{max_pow_obj}, {power_budget[max_pow_obj]}W"], - point_size=20, - font_size=30, - text_color="red", -) - -# Export the file. - -export_file = os.path.join(temp_folder.name, "object_power_pyVista.png") -plotter.screenshot(filename=export_file, scale=1) -Image(export_file) - -# ## Release AEDT - -ipk.save_project() -ipk.release_desktop() -time.sleep( - 3 -) # Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. -# If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell -# removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/electrothermal/ecad_import.py b/examples/electrothermal/ecad_import.py deleted file mode 100644 index 9abb22dd2..000000000 --- a/examples/electrothermal/ecad_import.py +++ /dev/null @@ -1,117 +0,0 @@ -# # Import of a PCB and its components via IDF and EDB - -# This example shows how to import a PCB and its components using IDF files (LDB and BDF). -# You can also use a combination of EMN and EMP files in a similar way. -# -# Keywords: **Icepak**, **PCB**, **IDF**. - -# ## Perform imports and define constants -# -# Perform required imports. - -import os -import tempfile -import time - -import ansys.aedt.core -from ansys.aedt.core import Hfss3dLayout, Icepak - -# Define constants. - -AEDT_VERSION = "2024.2" -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Open project -# -# Open an empty project in non-graphical mode, using a temporary folder. - -# + -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -ipk = Icepak( - project=os.path.join(temp_folder.name, "Icepak_ECAD_Import.aedt"), - version=AEDT_VERSION, - new_desktop=True, - non_graphical=NG_MODE, -) -# - - -# ## Import the IDF files -# -# Import the BDF and LDF files. Sample files are shown here. -# -# -# -# -# -# You can import the IDF files with several filtering options, including caps, resistors, -# inductors, power, specific power, and size. -# There are also options for PCB creation, including number of layers, copper percentages, and layer sizes. -# -# This example uses the default values for the PCB. -# The imported PCB (from the IDF files) are deleted later and replaced by a PCB that has the trace -# information (from ECAD) for higher accuracy. - -# Download ECAD and IDF files. - -def_path = ansys.aedt.core.downloads.download_file( - source="icepak/Icepak_ECAD_Import/A1_uprev.aedb", - name="edb.def", - destination=temp_folder.name, -) -board_path = ansys.aedt.core.downloads.download_file( - source="icepak/Icepak_ECAD_Import/", name="A1.bdf", destination=temp_folder.name -) -library_path = ansys.aedt.core.downloads.download_file( - source="icepak/Icepak_ECAD_Import/", name="A1.ldf", destination=temp_folder.name -) - -# Import IDF file. - -ipk.import_idf(board_path=board_path) - -# Save the project - -ipk.save_project() - -# ## Import ECAD -# Add an HFSS 3D Layout design with the layout information of the PCB. - -hfss3d_lo = Hfss3dLayout(project=def_path, version=AEDT_VERSION) -hfss3d_lo.save_project() - -# Create a PCB component in Icepak linked to the HFSS 3D Layout project. The polygon ``"poly_0"`` -# is used as the outline of the PCB, and a dissipation of ``"1W"`` is applied to the PCB. - -project_file = hfss3d_lo.project_file -design_name = hfss3d_lo.design_name - -ipk.create_pcb_from_3dlayout( - component_name="PCB_pyAEDT", - project_name=project_file, - design_name=design_name, - extent_type="Polygon", - outline_polygon="poly_0", - power_in=1, - close_linked_project_after_import=False, -) - -# Delete the simplified PCB object coming from the IDF import. - -ipk.modeler.delete_objects_containing("IDF_BoardOutline", False) - -# ## Release AEDT - -ipk.save_project() -ipk.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. -# If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell -# removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/electrothermal/electrothermal.py b/examples/electrothermal/electrothermal.py deleted file mode 100644 index 5cc8baf42..000000000 --- a/examples/electrothermal/electrothermal.py +++ /dev/null @@ -1,218 +0,0 @@ -# # Electrothermal analysis -# -# This example shows how to use the EDB for DC IR analysis and -# electrothermal analysis. The EDB is loaded into SIwave for analysis and postprocessing. -# In the end, an Icepak project is exported from SIwave. -# -# - Set up EDB: -# - Assign package and heatsink model to components. -# - Create voltage and current sources. -# - Create SIwave DC analysis. -# - Define cutout. -# - Import EDB into SIwave: -# - Analyze DC IR. -# - Export Icepak project. - - -# ## Perform imports and define constants -# -# Perform required imports. - -import json -import os -import sys -import tempfile -import time - -from ansys.aedt.core.downloads import download_file -from pyedb import Edb, Siwave - -# Define constants. - -AEDT_VERSION = "2024.2" -NUM_CORES = 4 -NG_MODE = True # Open AEDT UI when it is launched. - -# Check if AEDT is launched in graphical mode. - -if not NG_MODE: - print("Warning: this example requires graphical mode enabled.") - sys.exit() - -# ## Create temporary directory and download files -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# Download the example PCB data. - -aedb = download_file(source="edb/ANSYS-HSD_V1.aedb", destination=temp_folder.name) - -# ## Create configuration file -# -# This example uses a configuration file to set up the layout for analysis. -# Create an empty dictionary to host all configurations. - -cfg = dict() - -# ## Add component thermal information and heatsink definition - -cfg["package_definitions"] = [ - { - "name": "package_1", - "component_definition": "SMTC-MECT-110-01-M-D-RA1_V", - "maximum_power": 1, - "therm_cond": 1, - "theta_jb": 1, - "theta_jc": 1, - "height": "2mm", - "heatsink": { - "fin_base_height": "2mm", - "fin_height": "4mm", - "fin_orientation": "x_oriented", - "fin_spacing": "1mm", - "fin_thickness": "1mm", - }, - "apply_to_all": False, - "components": ["J5"], - } -] - -# ## Create pin groups -# -# Group all pins on the "GND" net on the ``J5`` component into one group. -# Pin groups are assigned by net name using the ``net`` key. - -cfg["pin_groups"] = [{"name": "J5_GND", "reference_designator": "J5", "net": "GND"}] - -# ## Create current sources -# -# Create two current sources on the ``J5`` component. -# A current source is placed between positive and negative terminals. -# When the ``net`` keyword is used, all pins on the specified net are grouped into a -# new pin group that is assigned as the positive terminal. -# -# Negative terminal can be assigned by pin group name by using the ``pin_group`` keyword. -# The two current sources share the same ``J5_GND`` pin group as the negative terminal. - -i_src_1 = { - "name": "J5_VCCR", - "reference_designator": "J5", - "type": "current", - "magnitude": 0.5, - "positive_terminal": {"net": "SFPA_VCCR"}, - "negative_terminal": {"pin_group": "J5_GND"}, # Defined in "pin_groups" section. -} -i_src_2 = { - "name": "J5_VCCT", - "reference_designator": "J5", - "type": "current", - "magnitude": 0.5, - "positive_terminal": {"net": "SFPA_VCCT"}, - "negative_terminal": {"pin_group": "J5_GND"}, # Defined in "pin_groups" section. -} - -# ## Create a voltage source -# -# Create a voltage source on the ``U4`` componebt between two nets using the ``net`` keyword. - -# + -v_src = { - "name": "VSOURCE_5V", - "reference_designator": "U4", - "type": "voltage", - "magnitude": 5, - "positive_terminal": {"net": "5V"}, - "negative_terminal": {"net": "GND"}, -} - -cfg["sources"] = [v_src, i_src_1, i_src_2] -# - - -# ## Define cutout -# -# The following assignments define the region of the PCB to be cut out for analysis. - -cfg["operations"] = { - "cutout": { - "signal_list": ["SFPA_VCCR", "SFPA_VCCT", "5V"], - "reference_list": ["GND"], - "extent_type": "Bounding", - } -} - -# ## Create SIwave DC analysis - -cfg["setups"] = [ - { - "name": "siwave_dc", - "type": "siwave_dc", - "dc_slider_position": 0, - "dc_ir_settings": {"export_dc_thermal_data": True}, - } -] - -# ## Save configuration to a JSON file -# -# The configuration file can be saved in JSON format and applied to layout data using the EDB. - -# + -pi_json = os.path.join(temp_folder.name, "pi.json") - -with open(pi_json, "w") as f: - json.dump(cfg, f, indent=4, ensure_ascii=False) -# - - -# ## Load configuration into EDB -# -# Load the configuration from the JSON file. - -edbapp = Edb(aedb, edbversion=AEDT_VERSION) -edbapp.configuration.load(config_file=pi_json) -edbapp.configuration.run() -edbapp.save() -edbapp.close() -time.sleep(3) - -# The configured EDB file is saved in the temporary folder. - -print(temp_folder.name) - -# ## Analyze in SIwave -# -# Load EDB into SIwave. - -siwave = Siwave(specified_version=AEDT_VERSION) -time.sleep(10) -siwave.open_project(proj_path=aedb) -siwave.save_project(projectpath=temp_folder.name, projectName="ansys") - -# ## Analyze - -siwave.run_dc_simulation() - -# ## Export Icepak project - -siwave.export_icepak_project( - os.path.join(temp_folder.name, "from_siwave.aedt"), "siwave_dc" -) - -# ## Close SIWave project - -siwave.close_project() - -# ## Shut down SIwave - -siwave.quit_application() - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.dir``. If you've run this example as a Jupyter notbook, you -# can retrieve those project files. The following cell removes all temporary files, including the project folder. - -time.sleep(3) -temp_folder.cleanup() diff --git a/examples/electrothermal/graphic_card.py b/examples/electrothermal/graphic_card.py deleted file mode 100644 index fa0463e85..000000000 --- a/examples/electrothermal/graphic_card.py +++ /dev/null @@ -1,311 +0,0 @@ -# # Graphic card thermal analysis - -# This example shows how to use pyAEDT to create a graphic card setup in -# Icepak and postprocess the results. -# The example file is an Icepak project with a model that is already created and -# has materials assigned. -# -# Keywords: **Icepak**, **boundary conditions**, **postprocessing**, **monitors**. - -# ## Perform imports and define constants -# -# Perform required imports. - -import os -import tempfile -import time - -import ansys.aedt.core -import pandas as pd -from IPython.display import Image - -# Define constants. - -AEDT_VERSION = "2024.2" -NUM_CORES = 4 -NG_MODE = False # Do not show the graphical user interface. - -# ## Create temporary directory and download project -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") -project_temp_name = ansys.aedt.core.downloads.download_icepak( - destination=temp_folder.name -) -# ## Open project -# -# Open the project without the GUI. - -ipk = ansys.aedt.core.Icepak( - project=project_temp_name, - version=AEDT_VERSION, - new_desktop=True, - non_graphical=NG_MODE, -) - -# ## Plot model and rotate -# -# Plot the model using the pyAEDT-PyVista integration and save the result to a file. -# Rotate the model and plot the rotated model again. - -# + -plot1 = ipk.plot( - show=False, - output_file=os.path.join(temp_folder.name, "Graphics_card_1.jpg"), - plot_air_objects=False, -) - -ipk.modeler.rotate(ipk.modeler.object_names, "X") - -plot2 = ipk.plot( - show=False, - output_file=os.path.join(temp_folder.name, "Graphics_card_2.jpg"), - plot_air_objects=False, -) -# - - -# ## Define boundary conditions -# -# Create source blocks on the CPU and memories. - -ipk.create_source_block(object_name="CPU", input_power="25W") -ipk.create_source_block(object_name=["MEMORY1", "MEMORY1_1"], input_power="5W") - -# The air region object handler is used to specify the inlet (fixed velocity condition) and outlet -# (fixed pressure condition) at x_max and x_min. - -region = ipk.modeler["Region"] -ipk.assign_pressure_free_opening( - assignment=region.top_face_x.id, boundary_name="Outlet" -) -ipk.assign_velocity_free_opening( - assignment=region.bottom_face_x.id, - boundary_name="Inlet", - velocity=["1m_per_sec", "0m_per_sec", "0m_per_sec"], -) - -# ## Assign mesh settings -# -# ### Assign mesh region -# Assign a mesh region around the heat sink and CPU. - -mesh_region = ipk.mesh.assign_mesh_region(assignment=["HEAT_SINK", "CPU"]) - -# Print the available settings for the mesh region - -mesh_region.settings - -# Set the mesh region settings to manual and see newly available settings. - -mesh_region.manual_settings = True -mesh_region.settings - -# Modify settings and update. - -mesh_region.settings["MaxElementSizeX"] = "2mm" -mesh_region.settings["MaxElementSizeY"] = "2mm" -mesh_region.settings["MaxElementSizeZ"] = "2mm" -mesh_region.settings["EnableMLM"] = True -mesh_region.settings["MaxLevels"] = "2" -mesh_region.settings["MinElementsInGap"] = 4 -mesh_region.update() - -# Modify the slack of the subregion around the objects. - -subregion = mesh_region.assignment -subregion.positive_x_padding = "20mm" -subregion.positive_y_padding = "5mm" -subregion.positive_z_padding = "5mm" -subregion.negative_x_padding = "5mm" -subregion.negative_y_padding = "5mm" -subregion.negative_z_padding = "10mm" - - -# ## Assign monitors -# -# Assign a temperature face monitor to the CPU face in contact with the heatsink. - -cpu = ipk.modeler["CPU"] -m1 = ipk.monitor.assign_face_monitor( - face_id=cpu.top_face_z.id, - monitor_quantity="Temperature", - monitor_name="TemperatureMonitor1", -) - -# Assign multiple speed point monitors downstream of the assembly. - -speed_monitors = [] -for x_pos in range(0, 10, 2): - m = ipk.monitor.assign_point_monitor( - point_position=[f"{x_pos}mm", "40mm", "15mm"], monitor_quantity="Speed" - ) - speed_monitors.append(m) - -# ## Solve project -# -# Create a setup, modify solver settings, and run the simulation. - -setup1 = ipk.create_setup() -setup1.props["Flow Regime"] = "Turbulent" -setup1.props["Convergence Criteria - Max Iterations"] = 5 -setup1.props["Linear Solver Type - Pressure"] = "flex" -setup1.props["Linear Solver Type - Temperature"] = "flex" -ipk.save_project() -ipk.analyze(setup=setup1.name, cores=NUM_CORES, tasks=NUM_CORES) - -# ## Postprocess -# -# ### Perform quantitative postprocessing - -# Get the point monitor data. A dictionary is returned with ``'Min'``, ``'Max'``, and ``'Mean'`` keys. - -temperature_data = ipk.post.evaluate_monitor_quantity( - monitor=m1, quantity="Temperature" -) -temperature_data - -# It is also possible to get the data as a Pandas dataframe for advanced postprocessing. - -speed_fs = ipk.post.create_field_summary() -for m_name in speed_monitors: - speed_fs.add_calculation( - entity="Monitor", geometry="Volume", geometry_name=m_name, quantity="Speed" - ) -speed_data = speed_fs.get_field_summary_data(pandas_output=True) - -# All the data is now in a dataframe, making it easy to visualize and manipulate. - -speed_data.head() - -# The ``speed_data`` dataframe contains data from monitors, so it can be expanded with information -# of their position. - -for i in range(3): - direction = ["X", "Y", "Z"][i] - speed_data["Position" + direction] = [ - ipk.monitor.all_monitors[entity].location[i] for entity in speed_data["Entity"] - ] - -# Plot the velocity profile at different X positions - -speed_data.plot( - x="PositionX", - y="Mean", - kind="line", - marker="o", - ylabel=speed_data.at[0, "Quantity"], - xlabel=f"x [{ipk.modeler.model_units}]", - grid=True, -) - -# Extract temperature data at those same locations (so the ``speed_monitors`` list is used). - -temperature_fs = ipk.post.create_field_summary() -for m_name in speed_monitors: - temperature_fs.add_calculation( - entity="Monitor", - geometry="Volume", - geometry_name=m_name, - quantity="Temperature", - ) -temperature_fs = temperature_fs.get_field_summary_data(pandas_output=True) -temperature_fs.head() - -# The two dataframes can be merged using the `pd.merge()` function. With the merge, suffixes are -# added to the column names to differentiate between the columns from each original dataframe. - -merged_df = pd.merge( - temperature_fs, speed_data, on="Entity", suffixes=("_temperature", "_speed") -) -merged_df.head() - -# The column names are renamed based on the ``Quantity`` column of the original dataframes. -# Finally, only the ``'Entity'``, ``'Mean_temperature'``, and ``'Mean_speed'`` columns are selected and -# assigned to the merged dataframe. - -temperature_quantity = temperature_fs["Quantity"].iloc[0] -velocity_quantity = speed_data["Quantity"].iloc[0] -merged_df.rename( - columns={"Mean_temperature": temperature_quantity, "Mean_speed": velocity_quantity}, - inplace=True, -) -merged_df = merged_df[ - [ - "Entity", - temperature_quantity, - velocity_quantity, - "PositionX", - "PositionY", - "PositionZ", - ] -] -merged_df.head() - -# Compute the correlation coefficient between velocity and temperature from the merged dataframe -# and plot a scatter plot to visualize their relationship. - -correlation = merged_df[velocity_quantity].corr(merged_df[temperature_quantity]) -ax = merged_df.plot.scatter(x=velocity_quantity, y=temperature_quantity) -ax.set_xlabel(velocity_quantity) -ax.set_ylabel(temperature_quantity) -ax.set_title(f"Correlation between Temperature and Velocity: {correlation:.2f}") - -# The further away from the assembly, the faster and colder the air due to mixing. -# Despite being extremely simple, this example demonstrates the potential of importing field -# summary data into Pandas. - -# ### Perform qualitative Postprocessing -# Create a temperature plot on main components and export it to a PNG file. - -surflist = [i.id for i in ipk.modeler["CPU"].faces] -surflist += [i.id for i in ipk.modeler["MEMORY1"].faces] -surflist += [i.id for i in ipk.modeler["MEMORY1_1"].faces] -plot3 = ipk.post.create_fieldplot_surface( - assignment=surflist, quantity="SurfTemperature" -) -path = plot3.export_image( - full_path=os.path.join(temp_folder.name, "temperature.png"), - orientation="top", - show_region=False, -) -Image(filename=path) # Display the image - -# Use PyVista to display the temperature map. - -plot4 = ipk.post.plot_field( - quantity="Temperature", - assignment=[ - "SERIAL_PORT", - "MEMORY1", - "MEMORY1_1", - "CAPACITOR", - "CAPACITOR_1", - "KB", - "HEAT_SINK", - "CPU", - "ALPHA_MAIN_PCB", - ], - plot_cad_objs=False, - show=False, - export_path=temp_folder.name, -) - -# ## Release AEDT - -ipk.save_project() -ipk.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. -# If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell -# removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/electrothermal/icepak_circuit_hfss_coupling.py b/examples/electrothermal/icepak_circuit_hfss_coupling.py deleted file mode 100644 index a8b073c94..000000000 --- a/examples/electrothermal/icepak_circuit_hfss_coupling.py +++ /dev/null @@ -1,353 +0,0 @@ -# # Circuit-HFSS-Icepak coupling workflow -# -# This example shows how to create a two-way coupling -# between HFSS and Icepak. -# -# Consider a design where some components are simulated in -# HFSS with a full 3D model, while others are simulated in Circuit as lumped elements. -# The electrical simulation is done by placing the HFSS design into a Circuit design as -# a subcomponent and connecting the lumped components to its ports. -# -# The purpose of the workflow is to perform a thermal simulation -# of the Circuit-HFSS design, creating a two-way coupling with Icepak -# that allows running multiple iterations. The losses from both designs -# are accounted for. -# - EM losses are evaluated by the HFSS solver and fed into Icepak via a direct link. -# - Losses from the lumped components in the Circuit design are evaluated -# analytically and must be manually set into the Icepak boundary. -# -# On the back of the coupling, temperature information -# is handled differently for HFSS and Circuit. -# -# - For HFSS, a temperature map is exported from the Icepak design and used to create a -# 3D dataset. Then, the material properties in the HFSS design are updated based on this -# dataset. -# - For Circuit, the average temperature of the lumped components is extracted from the -# Icepak design and used to update the temperature-dependent characteristics of the -# lumped components in Circuit. -# -# The Circuit design in this example contains only a -# resistor component, with temperature-dependent resistance -# described by this formula: ``0.162*(1+0.004*(TempE-TempE0))``, -# where TempE is the current temperature and TempE0 is the -# ambient temperature. The HFSS design includes only a cylinder -# with temperature-dependent material conductivity, defined by -# a 2D dataset. The resistor and the cylinder have -# matching resistances. -# -# Keywords: **Multiphysics**, **HFSS**, **Icepak**, **Circuit**. - -# ## Perform imports and define constants -# -# Perform required imports. - -import os -import tempfile -import time - -import ansys.aedt.core as aedt - -# Define constants. - -AEDT_VERSION = "2024.2" -NUM_CORES = 4 -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Download and open project -# -# Download and open the project. Save it to the temporary folder. - -project_name = aedt.downloads.download_file( - "circuit_hfss_icepak", "Circuit-HFSS-Icepak-workflow.aedtz", temp_folder.name -) - -# ## Launch AEDT and initialize HFSS -# -# Launch AEDT and initialize HFSS. If there is an active HFSS design, the ``hfss`` -# object is linked to it. Otherwise, a new design is created. - -circuit = aedt.Circuit( - project=project_name, - new_desktop=True, - version=AEDT_VERSION, - non_graphical=NG_MODE, -) - -# ## Set variable names -# -# Set the name of the resistor in Circuit. - -resistor_body_name = "Circuit_Component" - -# Set the name of the cylinder body in HFSS. - -device3D_body_name = "Device_3D" - -# ## Get HFSS design -# -# Get the HFSS design and prepare the material for the thermal link. - -hfss = aedt.Hfss(project=circuit.project_name) - -# ## Create a material -# -# Create a material to be used to set the temperature map on it. -# The material is created by duplicating the material assigned to the cylinder. - -material_name = hfss.modeler.objects_by_name[device3D_body_name].material_name -new_material_name = material_name + "_dataset" -new_material = hfss.materials.duplicate_material( - material=material_name, name=new_material_name -) - -# ## Modify material properties -# -# Save the conductivity value. It is used later in the iterations. - -old_conductivity = new_material.conductivity.value - -# Assign the new material to the cylinder object in HFSS. - -hfss.modeler.objects_by_name[device3D_body_name].material_name = new_material_name - -# Because this material has a high conductivity, HFSS automatically deactivates ``solve_inside``. -# It must be turned back on to evaluate the losses inside the cylinder. - -hfss.modeler.objects_by_name[device3D_body_name].solve_inside = True - -# ## Get Icepak design - -icepak = aedt.Icepak(project=circuit.project_name) - -# ## Set parameters for iterations -# -# Set the initial temperature to a value closer to the final one, to speed up the convergence. - -circuit["TempE"] = "300cel" - -# Set the maximum number of iterations. - -max_iter = 2 - -# Set the residual convergence criteria to stop the iterations. - -temp_residual_limit = 0.02 -loss_residual_limit = 0.02 - -# This variable is to contain iteration statistics. - -stats = {} - -# ## Start iterations -# -# Each ``for`` loop is a complete two-way iteration. -# The code is thoroughly commented. -# For a full understanding, read the inline comments carefully. - -for cp_iter in range(1, max_iter + 1): - stats[cp_iter] = {} - - # Step 1: Solve the HFSS design. - # - # Solve the HFSS design. - hfss.analyze(cores=NUM_CORES) - - # Step 2: Refresh the dynamic link and solve the Circuit design. - # - # Find the HFSS subcomponent in Circuit. - # This information is required by the ``refresh_dynamic_link()`` and ``push_excitations()`` methods. - hfss_component_name = "" - hfss_instance_name = "" - for component in circuit.modeler.components.components.values(): - if ( - component.model_name is not None - and hfss.design_name in component.model_name - ): - hfss_component_name = component.model_name - hfss_instance_name = component.refdes - break - if not hfss_component_name or not hfss_instance_name: - raise "Hfss component not found in Circuit design" - - # Refresh the dynamic link. - circuit.modeler.schematic.refresh_dynamic_link(name=hfss_component_name) - - # Solve the Circuit design. - circuit.analyze() - - # Step 3: Push the excitations. (HFSS design results are scaled automatically.) - # - # Push the excitations. - circuit.push_excitations(instance=hfss_instance_name) - - # Step 4: Extract the resistor's power loss value from the Circuit design. - # - # Evaluate the power loss on the resistor. - r_losses = circuit.post.get_solution_data( - expressions="0.5*mag(I(I1)*V(V1))" - ).data_magnitude()[0] - - # Save the losses in the stats. - stats[cp_iter]["losses"] = r_losses - - # Step 5: Set the resistor's power loss value in the Icepak design (block thermal condition) - # - # Find the solid block boundary in Icepak. - boundaries = icepak.boundaries - boundary = None - for bb in boundaries: - if bb.name == "Block1": - boundary = bb - break - if not boundary: - raise "Block boundary not defined in Icepak design." - - # Set the resistor's power loss in the Block Boundary. - boundary.props["Total Power"] = str(r_losses) + "W" - - # Step 6: Solve the Icepak design. - # - # Clear linked data. Otherwise, Icepak continues to run the simulation with the initial losses. - icepak.clear_linked_data() - - # Solve the Icepak design. - icepak.analyze(cores=NUM_CORES) - - # Step 7: Export the temperature map from the Icepak design and create a new 3D dataset with it. - # - # Export the temperature map to a file. - fld_filename = os.path.join( - icepak.working_directory, f"temperature_map_{cp_iter}.fld" - ) - icepak.post.export_field_file( - quantity="Temp", - output_file=fld_filename, - assignment="AllObjects", - objects_type="Vol", - ) - - # Convert the FLD file into a dataset tab file compatible with the dataset import. - # The existing header lines must be removed and replaced with a single header line - # containing the value unit. - with open(fld_filename, "r") as f: - lines = f.readlines() - - _ = lines.pop(0) - _ = lines.pop(0) - lines.insert(0, '"X" "Y" "Z" "cel"\n') - - basename, _ = os.path.splitext(fld_filename) - tab_filename = basename + "_dataset.tab" - - with open(tab_filename, "w") as f: - f.writelines(lines) - - # Import the 3D dataset. - dataset_name = f"temp_map_step_{cp_iter}" - hfss.import_dataset3d( - input_file=tab_filename, name=dataset_name, is_project_dataset=True - ) - - # Step 8: Update material properties in the HFSS design based on the new dataset. - # - # Set the new conductivity value. - new_material.conductivity.value = ( - f"{old_conductivity}*Pwl($TempDepCond,clp(${dataset_name},X,Y,Z))" - ) - - # Switch off the thermal modifier of the material, if any. - new_material.conductivity.thermalmodifier = None - - # Step 9: Extract the average temperature of the resistor from the Icepak design. - # - # Get the mean temperature value on the high-resistivity object. - mean_temp = icepak.post.get_scalar_field_value( - quantity="Temp", scalar_function="Mean", object_name=resistor_body_name - ) - - # Save the temperature in the iteration statistics. - stats[cp_iter]["temp"] = mean_temp - - # Step 10: Update the resistance value in the Circuit design. - # - # Set this temperature in Circuit in the ``TempE`` variable. - circuit["TempE"] = f"{mean_temp}cel" - - # Save the project - circuit.save_project() - - # Check the convergence of the iteration - # - # Evaluate the relative residuals on temperature and losses. - # If the residuals are smaller than the threshold, set the convergence flag to ``True```. - # Residuals are calculated starting from the second iteration. - converged = False - stats[cp_iter]["converged"] = converged - if cp_iter > 1: - delta_temp = abs(stats[cp_iter]["temp"] - stats[cp_iter - 1]["temp"]) / abs( - stats[cp_iter - 1]["temp"] - ) - delta_losses = abs( - stats[cp_iter]["losses"] - stats[cp_iter - 1]["losses"] - ) / abs(stats[cp_iter - 1]["losses"]) - if delta_temp <= temp_residual_limit and delta_losses <= loss_residual_limit: - converged = True - stats[cp_iter]["converged"] = converged - else: - delta_temp = None - delta_losses = None - - # Save the relative residuals in the iteration stats. - stats[cp_iter]["delta_temp"] = delta_temp - stats[cp_iter]["delta_losses"] = delta_losses - - # Exit from the loop if the convergence is reached. - if converged: - break - -# ## Print overall statistics -# -# Print the overall statistics for the multiphysics loop. - -for i in stats: - txt = "yes" if stats[i]["converged"] else "no" - delta_temp = ( - f"{stats[i]['delta_temp']:.4f}" - if stats[i]["delta_temp"] is not None - else "None" - ) - delta_losses = ( - f"{stats[i]['delta_losses']:.4f}" - if stats[i]["delta_losses"] is not None - else "None" - ) - print( - f"Step {i}: temp={stats[i]['temp']:.3f}, losses={stats[i]['losses']:.3f}, " - f"delta_temp={delta_temp}, delta_losses={delta_losses}, " - f"converged={txt}" - ) - -# ## Release AEDT -# -# Release AEDT and close the example. - -icepak.save_project() -icepak.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/electrothermal/index.rst b/examples/electrothermal/index.rst deleted file mode 100644 index 7cd18edf2..000000000 --- a/examples/electrothermal/index.rst +++ /dev/null @@ -1,146 +0,0 @@ -Electrothermal -~~~~~~~~~~~~~~ - -These examples use PyAEDT to show electrothermal capabilities of AEDT - -.. grid:: 2 - - .. grid-item-card:: PCB component definition from CSV file and model image exports - :padding: 2 2 2 2 - :link: components_csv - :link-type: doc - - .. image:: _static/icepak_csv.png - :alt: Icepak CSV - :width: 250px - :height: 200px - :align: center - - This example shows how to create different types of blocks and assign power and material to them using a CSV input file. - - - .. grid-item-card:: Import of a PCB and its components via IDF and EDB - :padding: 2 2 2 2 - :link: ecad_import - :link-type: doc - - .. image:: _static/ecad.png - :alt: Icepak ECAD - :width: 250px - :height: 200px - :align: center - - This example shows how to import a PCB and its components using IDF files (LDB and BDF). - You can also use a combination of EMN and EMP files in a similar way. - - - .. grid-item-card:: Thermal analysis with 3D components - :padding: 2 2 2 2 - :link: component_3d - :link-type: doc - - .. image:: _static/component.png - :alt: Thermal component - :width: 250px - :height: 200px - :align: center - - This example shows how to create a thermal analysis of an electronic package by taking advantage of 3D components with advanced features added by PyAEDT. - - - .. grid-item-card:: Graphic card thermal analysis - :padding: 2 2 2 2 - :link: graphic_card - :link-type: doc - - .. image:: _static/graphic.png - :alt: Graphic card - :width: 250px - :height: 200px - :align: center - - This example shows how to use pyAEDT to create a graphic card setup in Icepak and postprocess the results. - The example file is an Icepak project with a model that is already created and has materials assigned. - - - .. grid-item-card:: Coaxial - :padding: 2 2 2 2 - :link: coaxial_hfss_icepak - :link-type: doc - - .. image:: _static/coaxial.png - :alt: Coaxial - :width: 250px - :height: 200px - :align: center - - This example shows how to create a project from scratch in HFSS and Icepak. - - - .. grid-item-card:: Setup from Sherlock inputs - :padding: 2 2 2 2 - :link: sherlock - :link-type: doc - - .. image:: _static/sherlock.png - :alt: Sherlock PCB - :width: 250px - :height: 200px - :align: center - - This example shows how to create an Icepak project from Sherlock files (STEP and CSV) and an AEDB board. - - .. grid-item-card:: Circuit-HFSS-Icepak coupling workflow - :padding: 2 2 2 2 - :link: icepak_circuit_hfss_coupling - :link-type: doc - - .. image:: _static/ring.png - :alt: Ring - :width: 250px - :height: 200px - :align: center - - This example shows how to create a two-way coupling between HFSS and Icepak. - - - .. grid-item-card:: Electrothermal analysis - :padding: 2 2 2 2 - :link: electrothermal - :link-type: doc - - .. image:: _static/electrothermal.png - :alt: Electrothermal - :width: 250px - :height: 200px - :align: center - - This example shows how to use the EDB for DC IR analysis and electrothermal analysis. - The EDB is loaded into SIwave for analysis and postprocessing. - In the end, an Icepak project is exported from SIwave. - - - .. grid-item-card:: Maxwell 3D-Icepak electrothermal analysis - :padding: 2 2 2 2 - :link: ../low_frequency/multiphysics/maxwell_icepak - :link-type: doc - - .. image:: ../low_frequency/multiphysics/_static/charging.png - :alt: Charging - :width: 250px - :height: 200px - :align: center - - This example uses PyAEDT to set up a simple Maxwell design consisting of a coil and a ferrite core. - -.. toctree:: - :hidden: - - components_csv - ecad_import - graphic_card - coaxial_hfss_icepak - sherlock - icepak_circuit_hfss_coupling - electrothermal - ../low_frequency/multiphysics/maxwell_icepak diff --git a/examples/electrothermal/sherlock.py b/examples/electrothermal/sherlock.py deleted file mode 100644 index 97653aa5f..000000000 --- a/examples/electrothermal/sherlock.py +++ /dev/null @@ -1,175 +0,0 @@ -# # Setup from Sherlock inputs - -# This example shows how to create an Icepak project from Sherlock -# files (STEP and CSV) and an AEDB board. -# -# Keywords: **Icepak**, **Sherlock**. - -# ## Perform imports and define constants -# -# Perform required imports. - -# + -import os -import tempfile -import time - -import ansys.aedt.core - -# - - -# Define constants - -AEDT_VERSION = "2024.2" -NUM_CORES = 4 -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Set paths and define input files and variables -# -# Set paths. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") -input_dir = ansys.aedt.core.downloads.download_sherlock(destination=temp_folder.name) - -# Define input files. - -material_name = "MaterialExport.csv" -component_properties = "TutorialBoardPartsList.csv" -component_step = "TutorialBoard.stp" -aedt_odb_project = "SherlockTutorial.aedt" - -# Define variables that are needed later. - -aedt_odb_design_name = "PCB" -outline_polygon_name = "poly_14188" - -# Define input files with paths. - -material_list = os.path.join(input_dir, material_name) -component_list = os.path.join(input_dir, component_properties) -validation = os.path.join(temp_folder.name, "validation.log") -file_path = os.path.join(input_dir, component_step) -project_name = os.path.join(temp_folder.name, component_step[:-3] + "aedt") - -# ## Create Icepak model - -ipk = ansys.aedt.core.Icepak( - project=project_name, version=AEDT_VERSION, non_graphical=NG_MODE -) - -# Disable autosave to speed up the import. - -ipk.autosave_disable() - -# Import a PCB from an AEDB file. - -odb_path = os.path.join(input_dir, aedt_odb_project) -ipk.create_pcb_from_3dlayout( - component_name="Board", project_name=odb_path, design_name=aedt_odb_design_name -) - -# Create an offset coordinate system to match ODB++ with the Sherlock STEP file. -# The thickness is computed from the ``"Board"`` component. (``"Board1"`` is the -# instance name of the ``"Board"`` native component and is used to offset the coordinate system.) - -bb = ipk.modeler.user_defined_components["Board1"].bounding_box -stackup_thickness = bb[-1] - bb[2] -ipk.modeler.create_coordinate_system( - origin=[0, 0, stackup_thickness / 2], mode="view", view="XY" -) - -# Import the board components from an MCAD file and remove the PCB object as it is already -# imported with the ECAD. - -ipk.modeler.import_3d_cad(file_path, refresh_all_ids=False) -ipk.modeler.delete_objects_containing("pcb", False) - -# Modify the air region. Padding values are passed in this order: [+X, -X, +Y, -Y, +Z, -Z] - -ipk.mesh.global_mesh_region.global_region.padding_values = [20, 20, 20, 20, 300, 300] - -# ## Assign materials and power dissipation conditions from Sherlock -# -# Use the Sherlock file to assign materials. - -ipk.assignmaterial_from_sherlock_files( - component_file=component_list, material_file=material_list -) - -# Delete objects with no material assignments. - -no_material_objs = ipk.modeler.get_objects_by_material(material="") -ipk.modeler.delete(assignment=no_material_objs) -ipk.save_project() - -# Assign power blocks from the Sherlock file. - -total_power = ipk.assign_block_from_sherlock_file(csv_name=component_list) - -# ## Assign openings -# -# Assign opening boundary condition to all the faces of the region. -ipk.assign_openings(ipk.modeler.get_object_faces("Region")) - -# ## Create simulation setup -# ### Set global mesh settings - -ipk.globalMeshSettings( - 3, - gap_min_elements="1", - noOgrids=True, - MLM_en=True, - MLM_Type="2D", - edge_min_elements="2", - object="Region", -) - - -# ### Add postprocessing object -# Create the point monitor. - -point1 = ipk.monitor.assign_point_monitor( - point_position=ipk.modeler["COMP_U10"].top_face_z.center, monitor_name="Point1" -) - -# Create a line for reporting after the simulation. - -line = ipk.modeler.create_polyline( - points=[ - ipk.modeler["COMP_U10"].top_face_z.vertices[0].position, - ipk.modeler["COMP_U10"].top_face_z.vertices[2].position, - ], - non_model=True, -) - -# ### Solve -# To solve quickly, the maximum iterations are set to 20. For better accuracy, you -# can increase the maximum to at least 100. - -setup1 = ipk.create_setup() -setup1.props["Solution Initialization - Y Velocity"] = "1m_per_sec" -setup1.props["Radiation Model"] = "Discrete Ordinates Model" -setup1.props["Include Gravity"] = True -setup1.props["Secondary Gradient"] = True -setup1.props["Convergence Criteria - Max Iterations"] = 100 - -# Check for intersections using validation and fix them by -# assigning priorities. - -ipk.assign_priority_on_intersections() - -# ## Release AEDT - -ipk.save_project() -ipk.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. -# If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell -# removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/high_frequency/_static/emc.png b/examples/high_frequency/_static/emc.png deleted file mode 100644 index 1e24c4500..000000000 Binary files a/examples/high_frequency/_static/emc.png and /dev/null differ diff --git a/examples/high_frequency/_static/hf.png b/examples/high_frequency/_static/hf.png deleted file mode 100644 index 556c30831..000000000 Binary files a/examples/high_frequency/_static/hf.png and /dev/null differ diff --git a/examples/high_frequency/_static/layout.png b/examples/high_frequency/_static/layout.png deleted file mode 100644 index bae41c445..000000000 Binary files a/examples/high_frequency/_static/layout.png and /dev/null differ diff --git a/examples/high_frequency/_static/pcb_stress.png b/examples/high_frequency/_static/pcb_stress.png deleted file mode 100644 index 5b1e260c4..000000000 Binary files a/examples/high_frequency/_static/pcb_stress.png and /dev/null differ diff --git a/examples/high_frequency/_static/wgf.png b/examples/high_frequency/_static/wgf.png deleted file mode 100644 index 0f3d78bf9..000000000 Binary files a/examples/high_frequency/_static/wgf.png and /dev/null differ diff --git a/examples/high_frequency/antenna/_static/array.png b/examples/high_frequency/antenna/_static/array.png deleted file mode 100644 index 607705a5c..000000000 Binary files a/examples/high_frequency/antenna/_static/array.png and /dev/null differ diff --git a/examples/high_frequency/antenna/_static/car_w_pedestrians.png b/examples/high_frequency/antenna/_static/car_w_pedestrians.png deleted file mode 100644 index ae55f7de1..000000000 Binary files a/examples/high_frequency/antenna/_static/car_w_pedestrians.png and /dev/null differ diff --git a/examples/high_frequency/antenna/_static/dipole.png b/examples/high_frequency/antenna/_static/dipole.png deleted file mode 100644 index c8f469769..000000000 Binary files a/examples/high_frequency/antenna/_static/dipole.png and /dev/null differ diff --git a/examples/high_frequency/antenna/_static/emit_simple_cosite.png b/examples/high_frequency/antenna/_static/emit_simple_cosite.png deleted file mode 100644 index a136180ae..000000000 Binary files a/examples/high_frequency/antenna/_static/emit_simple_cosite.png and /dev/null differ diff --git a/examples/high_frequency/antenna/_static/patch.png b/examples/high_frequency/antenna/_static/patch.png deleted file mode 100644 index c3a48eb31..000000000 Binary files a/examples/high_frequency/antenna/_static/patch.png and /dev/null differ diff --git a/examples/high_frequency/antenna/_static/unitcell.png b/examples/high_frequency/antenna/_static/unitcell.png deleted file mode 100644 index 0e214dc77..000000000 Binary files a/examples/high_frequency/antenna/_static/unitcell.png and /dev/null differ diff --git a/examples/high_frequency/antenna/array.py b/examples/high_frequency/antenna/array.py deleted file mode 100644 index f900da8a0..000000000 --- a/examples/high_frequency/antenna/array.py +++ /dev/null @@ -1,185 +0,0 @@ -# # Component antenna array - -# This example shows how to use PyAEDT to create an example using a 3D component file. It sets -# up the analysis, solves it, and uses postprocessing functions to create plots using Matplotlib and -# PyVista without opening the HFSS user interface. This example runs only on Windows using CPython. -# -# Keywords: **HFSS**, **antenna array**, **3D components**, **far field**. - -# ## Perform imports and define constants -# -# Perform required imports. - -import os -import tempfile -import time - -import ansys.aedt.core -from ansys.aedt.core.visualization.advanced.farfield_visualization import \ - FfdSolutionData - -# Define constants - -AEDT_VERSION = "2024.2" -NUM_CORES = 4 -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Download 3D component -# Download the 3D component that is needed to run the example. - -example_path = ansys.aedt.core.downloads.download_3dcomponent( - destination=temp_folder.name -) - -# ## Launch HFSS and open project -# -# Launch HFSS and open the project. - -# + -project_name = os.path.join(temp_folder.name, "array.aedt") -hfss = ansys.aedt.core.Hfss( - project=project_name, - version=AEDT_VERSION, - design="Array_Simple", - non_graphical=NG_MODE, - new_desktop=True, -) - -print("Project name " + project_name) -# - - -# ## Read array definition -# -# Read array definition from the JSON file. - -dict_in = ansys.aedt.core.general_methods.read_json( - os.path.join(example_path, "array_simple.json") -) - -# ## Define 3D component -# -# Define the 3D component cell. - -dict_in["Circ_Patch_5GHz1"] = os.path.join(example_path, "Circ_Patch_5GHz.a3dcomp") - -# ## Add 3D component array -# -# A 3D component array is created from the previous dictionary. -# If a 3D component is not available in the design, it is loaded -# into the dictionary from the path that you specify. The following -# code edits the dictionary to point to the location of the A3DCOMP file. - -array = hfss.add_3d_component_array_from_json(dict_in) - -# ## Modify cells -# -# Make the center element passive and rotate the corner elements. - -array.cells[1][1].is_active = False -array.cells[0][0].rotation = 90 -array.cells[0][2].rotation = 90 -array.cells[2][0].rotation = 90 -array.cells[2][2].rotation = 90 - -# ## Set up simulation and analyze -# -# Set up a simulation and analyze it. - -setup = hfss.create_setup() -setup.props["Frequency"] = "5GHz" -setup.props["MaximumPasses"] = 3 -hfss.analyze(cores=NUM_CORES) - - -# ## Get far field data -# -# Get far field data. After the simulation completes, the far -# field data is generated port by port and stored in a data class. - -ffdata = hfss.get_antenna_data(setup=hfss.nominal_adaptive, sphere="Infinite Sphere1") - -# ## Generate contour plot -# -# Generate a contour plot. You can define the Theta scan and Phi scan. - -ffdata.farfield_data.plot_contour( - quantity="RealizedGain", - title="Contour at {}Hz".format(ffdata.farfield_data.frequency), -) - -# ## Release AEDT -# -# Release AEDT. -# You can perform far field postprocessing without AEDT because the data is stored. - -metadata_file = ffdata.metadata_file -working_directory = hfss.working_directory - -hfss.save_project() -hfss.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Load far field data -# -# Load the stored far field data. - -ffdata = FfdSolutionData(input_file=metadata_file) - -# ## Generate contour plot -# -# Generate a contour plot. You can define the Theta scan -# and Phi scan. - -ffdata.plot_contour( - quantity="RealizedGain", title="Contour at {}Hz".format(ffdata.frequency) -) - -# ## Generate 2D cutout plots -# -# Generate 2D cutout plots. You can define the Theta scan -# and Phi scan. - -ffdata.plot_cut( - quantity="RealizedGain", - primary_sweep="theta", - secondary_sweep_value=[-180, -75, 75], - title="Azimuth at {}Hz".format(ffdata.frequency), - quantity_format="dB10", -) - -ffdata.plot_cut( - quantity="RealizedGain", - primary_sweep="phi", - secondary_sweep_value=30, - title="Elevation", - quantity_format="dB10", -) - -# ## Generate 3D plot -# -# Generate 3D plots. You can define the Theta scan and Phi scan. - -ffdata.plot_3d( - quantity="RealizedGain", - output_file=os.path.join(working_directory, "Image.jpg"), - show=False, -) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. -# If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell -# removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/high_frequency/antenna/dipole.py b/examples/high_frequency/antenna/dipole.py deleted file mode 100644 index a30f1da00..000000000 --- a/examples/high_frequency/antenna/dipole.py +++ /dev/null @@ -1,211 +0,0 @@ -# # Dipole antenna -# -# This example shows how to use PyAEDT to create a dipole antenna in HFSS -# and postprocess results. -# -# Keywords: **HFSS**, **modal**, **antenna**, **3D components**, **far field**. - -# ## Perform imports and define constants -# -# Perform required imports. - -import os -import tempfile -import time - -import ansys.aedt.core - -# Define constants. - -AEDT_VERSION = "2024.2" -NUM_CORES = 4 -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Launch AEDT - -d = ansys.aedt.core.launch_desktop( - AEDT_VERSION, non_graphical=NG_MODE, new_desktop=True -) - -# ## Launch HFSS -# -# Create an HFSS design. - -project_name = os.path.join(temp_folder.name, "dipole.aedt") -hfss = ansys.aedt.core.Hfss( - version=AEDT_VERSION, project=project_name, solution_type="Modal" -) - -# ## Define variable -# -# Define a variable for the dipole length. - -hfss["l_dipole"] = "13.5cm" - -# ## Get 3D component from system library -# -# Get a 3D component from the ``syslib`` directory. For this example to run -# correctly, you must get all geometry parameters of the 3D component or, in -# case of an encrypted 3D component, create a dictionary of the parameters. - -compfile = hfss.components3d["Dipole_Antenna_DM"] -geometryparams = hfss.get_components3d_vars("Dipole_Antenna_DM") -geometryparams["dipole_length"] = "l_dipole" -hfss.modeler.insert_3d_component(compfile, geometryparams) - -# ## Create boundaries -# -# Create an open region. - -hfss.create_open_region(frequency="1GHz") - -# ## Create setup -# -# Create a setup with a sweep to run the simulation. - -setup = hfss.create_setup("MySetup") -setup.props["Frequency"] = "1GHz" -setup.props["MaximumPasses"] = 1 -hfss.create_linear_count_sweep( - setup=setup.name, - units="GHz", - start_frequency=0.5, - stop_frequency=1.5, - num_of_freq_points=101, - name="sweep1", - sweep_type="Interpolating", - interpolation_tol=3, - interpolation_max_solutions=255, - save_fields=False, -) - -# ## Run simulation - -hfss.analyze_setup(name="MySetup", cores=NUM_CORES) - -# ### Postprocess -# -# Plot s-parameters and far field. - -hfss.create_scattering("MyScattering") -variations = hfss.available_variations.nominal_w_values_dict -variations["Freq"] = ["1GHz"] -variations["Theta"] = ["All"] -variations["Phi"] = ["All"] -hfss.post.create_report( - "db(GainTotal)", - hfss.nominal_adaptive, - variations, - primary_sweep_variable="Theta", - context="3D", - report_category="Far Fields", -) - -# Create a far fields report using the ``report_by_category.far field()`` method. - -new_report = hfss.post.reports_by_category.far_field( - "db(RealizedGainTotal)", hfss.nominal_adaptive, "3D" -) -new_report.variations = variations -new_report.primary_sweep = "Theta" -new_report.create("Realized2D") - -# Generate multiple plots using the ``new_report`` object. This code generates -# 2D and 3D polar plots. - -new_report.report_type = "3D Polar Plot" -new_report.secondary_sweep = "Phi" -new_report.create("Realized3D") - -# Get solution data using the ``new_report`` object and postprocess or plot the -# data outside AEDT. - -solution_data = new_report.get_solution_data() -solution_data.plot() - -# Generate a far field plot by creating a postprocessing variable and assigning -# it to a new coordinate system. You can use the ``post`` prefix to create a -# postprocessing variable directly from a setter, or you can use the ``set_variable()`` -# method with an arbitrary name. - -hfss["post_x"] = 2 -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") - -# ## Retrieve solution data -# -# You can also process solution data using Python libraries like Matplotlib. - -new_report = hfss.post.reports_by_category.far_field( - "GainTotal", hfss.nominal_adaptive, "3D" -) -new_report.primary_sweep = "Theta" -new_report.far_field_sphere = "3D" -solutions = new_report.get_solution_data() - -# Generate a 3D plot using Matplotlib. - -solutions.plot_3d() - -# Generate a far fields plot using Matplotlib. - -new_report.far_field_sphere = "Sphere_Custom" -solutions_custom = new_report.get_solution_data() -solutions_custom.plot_3d() - -# Generate a 2D plot using Matplotlib where you specify whether it is a polar -# plot or a rectangular plot. - -solutions.plot(formula="db20", is_polar=True) - -# ## Retrieve far-field data -# -# After the simulation completes, the far -# field data is generated port by port and stored in a data class. You can use this data -# once AEDT is released. - -ffdata = hfss.get_antenna_data( - sphere="Sphere_Custom", - setup=hfss.nominal_adaptive, - frequencies=["1000MHz"], -) - -# ## Generate 2D cutout plot -# -# Generate a 2D cutout plot. You can define the Theta scan -# and Phi scan. - -ffdata.farfield_data.plot_cut( - primary_sweep="theta", - secondary_sweep_value=0, - quantity="RealizedGain", - title="FarField", - quantity_format="dB20", - is_polar=True, -) - -# ## Release AEDT - -hfss.save_project() -d.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. -# If you've run this example as a Jupyter notebook, you -# can retrieve those project files. -# The following cell removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/high_frequency/antenna/fss_unitcell.py b/examples/high_frequency/antenna/fss_unitcell.py deleted file mode 100644 index e28f4953b..000000000 --- a/examples/high_frequency/antenna/fss_unitcell.py +++ /dev/null @@ -1,166 +0,0 @@ -# # FSS unit cell simulation -# -# This example shows how to use PyAEDT to model and simulate a unit cell -# for a frequency-selective surface in HFSS. -# -# Keywords: **HFSS**, **FSS**, **Floquet**. - -# ## Perform imports and define constants -# -# Perform required imports. - -import os -import tempfile -import time - -import ansys.aedt.core - -# Define constants. - -AEDT_VERSION = "2024.2" -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Launch AEDT - -project_name = os.path.join(temp_folder.name, "FSS.aedt") -d = ansys.aedt.core.launch_desktop( - AEDT_VERSION, - non_graphical=NG_MODE, - new_desktop=True, -) - -# ## Launch HFSS -# -# Create an HFSS design. - -hfss = ansys.aedt.core.Hfss( - version=AEDT_VERSION, project=project_name, solution_type="Modal" -) - -# ## Define variable -# -# Define a variable for the 3D component. - -hfss["patch_dim"] = "10mm" - -# ## Set up model -# -# Download the 3D component from the example data and insert the 3D component. - -unitcell_3d_component_path = ansys.aedt.core.downloads.download_FSS_3dcomponent( - destination=temp_folder.name -) -unitcell_path = os.path.join(unitcell_3d_component_path, "FSS_unitcell_23R2.a3dcomp") -comp = hfss.modeler.insert_3d_component(unitcell_path) - -# Assign the parameter to the 3D component. - -component_name = hfss.modeler.user_defined_component_names -comp.parameters["a"] = "patch_dim" - -# Create an open region along +Z direction for unit cell analysis. - -# + -bounding_dimensions = hfss.modeler.get_bounding_dimension() - -periodicity_x = bounding_dimensions[0] -periodicity_y = bounding_dimensions[1] - -region = hfss.modeler.create_air_region( - z_pos=10 * bounding_dimensions[2], - is_percentage=False, -) - -[x_min, y_min, z_min, x_max, y_max, z_max] = region.bounding_box -# - - -# Assign the lattice pair boundary condition. - -hfss.auto_assign_lattice_pairs(assignment=region.name) - -# Define the Floquet port. - -id_z_pos = region.top_face_z -hfss.create_floquet_port( - assignment=id_z_pos, - lattice_origin=[0, 0, z_max], - lattice_a_end=[0, y_max, z_max], - lattice_b_end=[x_max, 0, z_max], - name="port_z_max", - deembed_distance=10 * bounding_dimensions[2], -) - -# Create a solution setup, including the frequency sweep. - -setup = hfss.create_setup("MySetup") -setup.props["Frequency"] = "10GHz" -setup.props["MaximumPasses"] = 10 -hfss.create_linear_count_sweep( - setup=setup.name, - units="GHz", - start_frequency=6, - stop_frequency=15, - num_of_freq_points=51, - name="sweep1", - sweep_type="Interpolating", - interpolation_tol=6, - save_fields=False, -) - -# ## Postprocess -# -# Create S-parameter reports. - -# + -all_quantities = hfss.post.available_report_quantities() -str_mag = [] -str_ang = [] - -variation = {"Freq": ["All"]} - -for i in all_quantities: - str_mag.append("mag(" + i + ")") - str_ang.append("ang_deg(" + i + ")") - -hfss.post.create_report( - expressions=str_mag, - variations=variation, - plot_name="magnitude_plot", -) -hfss.post.create_report( - expressions=str_ang, - variations=variation, - plot_name="phase_plot", -) -# - - -# ## Save and run simulation -# -# Save and run the simulation. Uncomment the following line to run the analysis. - -# hfss.analyze() -hfss.save_project() - -# ## Release AEDT - -hfss.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. -# If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell removes -# all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/high_frequency/antenna/index.rst b/examples/high_frequency/antenna/index.rst deleted file mode 100644 index 779ff1df1..000000000 --- a/examples/high_frequency/antenna/index.rst +++ /dev/null @@ -1,107 +0,0 @@ -Antenna -~~~~~~~ -These examples use PyAEDT to show some antenna applications. - -.. grid:: 2 - - .. grid-item-card:: Dipole antenna - :padding: 2 2 2 2 - :link: dipole - :link-type: doc - - .. image:: _static/dipole.png - :alt: Antenna - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create a dipole antenna in HFSS and postprocess results. - - .. grid-item-card:: Component antenna array - :padding: 2 2 2 2 - :link: array - :link-type: doc - - .. image:: _static/array.png - :alt: Antenna - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create an antenna array. - - .. grid-item-card:: Probe-fed patch antenna - :padding: 2 2 2 2 - :link: patch - :link-type: doc - - .. image:: _static/patch.png - :alt: Patch - :width: 250px - :height: 200px - :align: center - - This example shows how to use the Stackup3D class to create and analyze a patch antenna in HFSS. - - .. grid-item-card:: FSS unit cell simulation - :padding: 2 2 2 2 - :link: fss_unitcell - :link-type: doc - - .. image:: _static/unitcell.png - :alt: FSS - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to model and simulate a unit cell for a frequency-selective surface in HFSS. - - .. grid-item-card:: Circuit schematic creation and analysis - :padding: 2 2 2 2 - :link: ../../aedt_general/modeler/circuit_schematic - :link-type: doc - - .. image:: ../../aedt_general/modeler/_static/circuit.png - :alt: Circuit - :width: 250px - :height: 200px - :align: center - - This example shows how to build a circuit schematic and run a transient circuit simulation. - - .. grid-item-card:: Large scenarios - :padding: 2 2 2 2 - :link: large_scenarios/index - :link-type: doc - - .. image:: _static/car_w_pedestrians.png - :alt: FSS - :width: 250px - :height: 200px - :align: center - - These examples use PyAEDT to show some general capabilities of HFSS SBR+ for large scenarios. - - .. grid-item-card:: RF interference - :padding: 2 2 2 2 - :link: interferences/index - :link-type: doc - - .. image:: _static/emit_simple_cosite.png - :alt: EMIT logo - :width: 250px - :height: 200px - :align: center - - These examples use PyAEDT to show some general capabilities of EMIT for RF interference. - - .. toctree:: - :hidden: - - dipole - array - patch - fss_unitcell - ../../aedt_general/modeler/circuit_schematic - large_scenarios/index - interferences/index diff --git a/examples/high_frequency/antenna/interferences/_static/coupling.png b/examples/high_frequency/antenna/interferences/_static/coupling.png deleted file mode 100644 index 865600ccd..000000000 Binary files a/examples/high_frequency/antenna/interferences/_static/coupling.png and /dev/null differ diff --git a/examples/high_frequency/antenna/interferences/_static/emit.png b/examples/high_frequency/antenna/interferences/_static/emit.png deleted file mode 100644 index 685796f51..000000000 Binary files a/examples/high_frequency/antenna/interferences/_static/emit.png and /dev/null differ diff --git a/examples/high_frequency/antenna/interferences/_static/emit_hfss.png b/examples/high_frequency/antenna/interferences/_static/emit_hfss.png deleted file mode 100644 index 5c771902a..000000000 Binary files a/examples/high_frequency/antenna/interferences/_static/emit_hfss.png and /dev/null differ diff --git a/examples/high_frequency/antenna/interferences/_static/emit_simple_cosite.png b/examples/high_frequency/antenna/interferences/_static/emit_simple_cosite.png deleted file mode 100644 index a136180ae..000000000 Binary files a/examples/high_frequency/antenna/interferences/_static/emit_simple_cosite.png and /dev/null differ diff --git a/examples/high_frequency/antenna/interferences/_static/interference.png b/examples/high_frequency/antenna/interferences/_static/interference.png deleted file mode 100644 index 797199e23..000000000 Binary files a/examples/high_frequency/antenna/interferences/_static/interference.png and /dev/null differ diff --git a/examples/high_frequency/antenna/interferences/_static/interference_type.png b/examples/high_frequency/antenna/interferences/_static/interference_type.png deleted file mode 100644 index 0e38b4d59..000000000 Binary files a/examples/high_frequency/antenna/interferences/_static/interference_type.png and /dev/null differ diff --git a/examples/high_frequency/antenna/interferences/_static/protection.png b/examples/high_frequency/antenna/interferences/_static/protection.png deleted file mode 100644 index 1c69ad1f0..000000000 Binary files a/examples/high_frequency/antenna/interferences/_static/protection.png and /dev/null differ diff --git a/examples/high_frequency/antenna/interferences/antenna.py b/examples/high_frequency/antenna/interferences/antenna.py deleted file mode 100644 index cfd57efc4..000000000 --- a/examples/high_frequency/antenna/interferences/antenna.py +++ /dev/null @@ -1,111 +0,0 @@ -# # Antenna -# -# This example shows how to create a project in EMIT for -# the simulation of an antenna using HFSS. -# -# -# -# Keywords: **EMIT**, **Antenna**. - -# ## Perform imports and define constants -# -# Perform required imports. - - -import tempfile -import time - -import ansys.aedt.core - -# from ansys.aedt.core.emit_core.emit_constants import ResultType, TxRxMode - -# Define constants. - -AEDT_VERSION = "2024.2" -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Launch AEDT with EMIT -# -# Launch AEDT with EMIT. The ``launch_desktop()`` method initializes AEDT -# using the specified version. The second argument can be set to ``True`` to -# run AEDT in non-graphical mode. - -project_name = ansys.aedt.core.generate_unique_project_name( - root_name=temp_folder.name, project_name="antenna_cosite" -) -d = ansys.aedt.core.launch_desktop(AEDT_VERSION, NG_MODE, new_desktop=True) -aedtapp = ansys.aedt.core.Emit(project_name, version=AEDT_VERSION) - -# ## Create and connect EMIT components -# -# Create three radios and connect an antenna to each one. - -rad1 = aedtapp.modeler.components.create_component("New Radio") -ant1 = aedtapp.modeler.components.create_component("Antenna") -if rad1 and ant1: - ant1.move_and_connect_to(rad1) - -# ## Place radio/antenna pair -# -# Use the ``create_radio_antenna()`` method to place the radio/antenna pair. The first -# argument is the type of radio. The second argument is the name to -# assign to the radio. - -rad2, ant2 = aedtapp.modeler.components.create_radio_antenna("GPS Receiver") -rad3, ant3 = aedtapp.modeler.components.create_radio_antenna( - "Bluetooth Low Energy (LE)", "Bluetooth" -) - -# ## Define the RF environment -# -# Specify the RF coupling among antennas. -# This functionality is not yet implemented in the API, but it can be entered from the UI. -# -# - - -# ## Run EMIT simulation -# -# Run the EMIT simulation. -# -# This part of the example requires Ansys AEDT 2023 R2. - -# > **Note:** You can uncomment the following code. -# -# if AEDT_VERSION > "2023.1": -# rev = aedtapp.results.analyze() -# rx_bands = rev.get_band_names(rad2.name, TxRxMode.RX) -# tx_bands = rev.get_band_names(rad3.name, TxRxMode.TX) -# domain = aedtapp.results.interaction_domain() -# domain.set_receiver(rad2.name, rx_bands[0], -1) -# domain.set_interferer(rad3.name, tx_bands[0]) -# interaction = rev.run(domain) -# worst = interaction.get_worst_instance(ResultType.EMI) -# if worst.has_valid_values(): -# emi = worst.get_value(ResultType.EMI) -# print("Worst case interference is: {} dB".format(emi)) - -# ## Release AEDT -# -# Release AEDT and close the example. - -aedtapp.save_project() -aedtapp.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/high_frequency/antenna/interferences/hfss_emit.py b/examples/high_frequency/antenna/interferences/hfss_emit.py deleted file mode 100644 index c8b380005..000000000 --- a/examples/high_frequency/antenna/interferences/hfss_emit.py +++ /dev/null @@ -1,149 +0,0 @@ -# # HFSS to EMIT coupling -# -# This example shows how to link an HFSS design -# to EMIT and model RF interference among various components. -# -# -# -# > **Note:** This example uses the ``Cell Phone RFI Desense`` -# > project that is available with the AEDT installation in the -# > ``\Examples\EMIT\`` directory. -# -# Keywords: **EMIT**, **Coupling**. - -# ## Perform imports and define constants -# -# Perform required imports. - -import os -import shutil -import tempfile -import time - -import ansys.aedt.core -from ansys.aedt.core.emit_core.emit_constants import ResultType, TxRxMode - -# Define constants. - -AEDT_VERSION = "2024.2" -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Launch AEDT with EMIT -# -# Launch AEDT with EMIT. The ``Desktop`` class initializes AEDT and starts it -# on the specified version and in the specified graphical mode. -# A temporary working directory is created using ``tempfile``. - -d = ansys.aedt.core.launch_desktop( - version=AEDT_VERSION, non_graphical=NG_MODE, new_desktop=True -) - -# ## Copy example files -# -# Copy the ``Cell Phone RFT Defense`` example data from the -# installed ``Examples`` directory to the temporary working -# directory. -# -# > **Note:** The HFSS design from the installed example -# > used to model the RF environment -# > has been pre-solved. Hence, the results folder is copied and -# > the RF interference between transceivers is calculated in EMIT using -# > results from the linked HFSS design. -# -# The following lambda functions help create file and directory -# names when copying data from the ``Examples`` directory. - -file_name = lambda s: s + ".aedt" -results_name = lambda s: s + ".aedtresults" -pdf_name = lambda s: s + " Example.pdf" - -# Build the names of the source files for this example. - -example = "Cell Phone RFI Desense" -example_dir = os.path.join(d.install_path, "Examples\\EMIT") -example_project = os.path.join(example_dir, file_name(example)) -example_results_folder = os.path.join(example_dir, results_name(example)) -example_pdf = os.path.join(example_dir, pdf_name(example)) - -# Copy the files to the temporary working directory. - -project_name = shutil.copyfile( - example_project, os.path.join(temp_folder.name, file_name(example)) -) -results_folder = shutil.copytree( - example_results_folder, os.path.join(temp_folder.name, results_name(example)) -) -project_pdf = shutil.copyfile( - example_pdf, os.path.join(temp_folder.name, pdf_name(example)) -) - -# Open the project in the working directory. - -aedtapp = ansys.aedt.core.Emit(project_name, version=AEDT_VERSION) - -# ## Create and connect EMIT components -# -# Create two radios with antennas connected to each one. - -rad1, ant1 = aedtapp.modeler.components.create_radio_antenna( - "Bluetooth Low Energy (LE)" -) -rad2, ant2 = aedtapp.modeler.components.create_radio_antenna( - "Bluetooth Low Energy (LE)" -) - -# ## Define coupling among RF systems -# -# Define coupling among the RF systems. - -for link in aedtapp.couplings.linkable_design_names: - aedtapp.couplings.add_link(link) - print('linked "' + link + '".') - -for link in aedtapp.couplings.coupling_names: - aedtapp.couplings.update_link(link) - print('linked "' + link + '".') - -# ## Calculate RF interference -# -# Run the EMIT simulation. This portion of the EMIT API is not yet implemented. -# -# This part of the example requires Ansys AEDT 2023 R2. - -if AEDT_VERSION > "2023.1": - rev = aedtapp.results.analyze() - rx_bands = rev.get_band_names(rad1.name, TxRxMode.RX) - tx_bands = rev.get_band_names(rad2.name, TxRxMode.TX) - domain = aedtapp.results.interaction_domain() - domain.set_receiver(rad1.name, rx_bands[0], -1) - domain.set_interferer(rad2.name, tx_bands[0]) - interaction = rev.run(domain) - worst = interaction.get_worst_instance(ResultType.EMI) - if worst.has_valid_values(): - emi = worst.get_value(ResultType.EMI) - print("Worst case interference is: {} dB".format(emi)) - -# ## Release AEDT -# -# Release AEDT and close the example. - -aedtapp.save_project() -aedtapp.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/high_frequency/antenna/interferences/index.rst b/examples/high_frequency/antenna/interferences/index.rst deleted file mode 100644 index 3e9e0035f..000000000 --- a/examples/high_frequency/antenna/interferences/index.rst +++ /dev/null @@ -1,81 +0,0 @@ -RF interference -~~~~~~~~~~~~~~~ -These examples use PyAEDT to show some general capabilities of EMIT for RF interference - -.. grid:: 2 - - .. grid-item-card:: Antenna - :padding: 2 2 2 2 - :link: antenna - :link-type: doc - - .. image:: _static/emit.png - :alt: Antenna - :width: 250px - :height: 200px - :align: center - - This example shows how to create a project in EMIT for the simulation of an antenna using HFSS. - - .. grid-item-card:: HFSS to EMIT coupling - :padding: 2 2 2 2 - :link: hfss_emit - :link-type: doc - - .. image:: _static/emit_hfss.png - :alt: EMIT HFSS - :width: 250px - :height: 200px - :align: center - - This example shows how to link an HFSS design to EMIT and model RF interference among various components. - - .. grid-item-card:: Interference type classification - :padding: 2 2 2 2 - :link: interference - :link-type: doc - - .. image:: _static/interference.png - :alt: EMIT HFSS - :width: 250px - :height: 200px - :align: center - - This example shows how to load an existing AEDT EMIT design and analyze the results to classify the worst-case interference. - - .. grid-item-card:: Compute receiver protection levels - :padding: 2 2 2 2 - :link: interference_type - :link-type: doc - - .. image:: _static/protection.png - :alt: EMIT protection - :width: 250px - :height: 200px - :align: center - - This example shows how to open an AEDT project with an EMIT design and analyze the results to determine if - the received power at the input to each receiver exceeds the specified protection levels. - - .. grid-item-card:: Interference type classification using a GUI - :padding: 2 2 2 2 - :link: interference_type - :link-type: doc - - .. image:: _static/interference_type.png - :alt: EMIT protection - :width: 250px - :height: 200px - :align: center - - This example uses a GUI to open an AEDT project with an EMIT design and analyze the results to classify - the worst-case interference. - - .. toctree:: - :hidden: - - antenna - hfss_emit - interference - protection - interference_type diff --git a/examples/high_frequency/antenna/interferences/interference.py b/examples/high_frequency/antenna/interferences/interference.py deleted file mode 100644 index 2d6dac9e5..000000000 --- a/examples/high_frequency/antenna/interferences/interference.py +++ /dev/null @@ -1,227 +0,0 @@ -# # Interference type classification -# -# This example shows how to load an existing AEDT EMIT -# design and analyze the results to classify the -# worst-case interference. -# -# Keywords: **EMIT**, **interference**. - -# ## Perform imports and define constants - -# + -import sys -import tempfile - -import ansys.aedt.core -import plotly.graph_objects as go -from ansys.aedt.core import Emit -from ansys.aedt.core.emit_core.emit_constants import InterfererType - -# - - -# Define constants. - -AEDT_VERSION = "2024.2" -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# Check that EMIT 2023.2 or later is installed. - -if AEDT_VERSION <= "2023.1": - print("Warning: This example requires AEDT 2023.2 or later.") - sys.exit() - -# Download project - -project_name = ansys.aedt.core.downloads.download_file( - "emit", "interference.aedtz", destination=temp_folder.name -) - -# ## Launch EMIT and open project - -emitapp = Emit( - non_graphical=NG_MODE, new_desktop=True, project=project_name, version=AEDT_VERSION -) - -# ## Get lists of transmitters and receivers -# -# Get lists of all transmitters and receivers in the project. - -# + -rev = emitapp.results.analyze() -tx_interferer = InterfererType().TRANSMITTERS -rx_radios = rev.get_receiver_names() -tx_radios = rev.get_interferer_names(tx_interferer) -domain = emitapp.results.interaction_domain() - -if tx_radios is None or rx_radios is None: - print("No receivers or transmitters are in the design.") - sys.exit() -# - - -# ## Classify the interference -# -# Iterate over all the transmitters and receivers and compute the power -# at the input to each receiver due to each of the transmitters. Compute -# which type of interference occurred, if any. - -power_matrix = [] -all_colors = [] - - -all_colors, power_matrix = rev.interference_type_classification( - domain, use_filter=False, filter_list=[] -) - -# ## Release AEDT -# -# Release AEDT and close the example. - -emitapp.release_desktop() - -# ## Create a scenario matrix view -# -# Create a scenario matrix view with the transmitters defined across the top -# and receivers down the left-most column. The power at the input to each -# receiver is shown in each cell of the matrix and color-coded based on the -# interference type. -# -# Set up colors to visualize results in a table. - -# + -table_colors = { - "green": "#7d73ca", - "yellow": "#d359a2", - "orange": "#ff6361", - "red": "#ffa600", - "white": "#ffffff", -} -header_color = "grey" - - -def create_scenario_view(emis, colors, tx_radios, rx_radios): - """Create a scenario matrix-like table with the higher received - power for each Tx-Rx radio combination. The colors - used for the scenario matrix view are based on the interference type.""" - - all_colors = [] - for color in colors: - col = [] - for cell in color: - col.append(table_colors[cell]) - all_colors.append(col) - - fig = go.Figure( - data=[ - go.Table( - header=dict( - values=[ - "Tx/Rx", - "{}".format(tx_radios[0]), - "{}".format(tx_radios[1]), - ], - line_color="darkslategray", - fill_color="grey", - align=["left", "center"], - font=dict(color="white", size=16), - ), - cells=dict( - values=[rx_radios, emis[0], emis[1]], - line_color="darkslategray", - fill_color=["white", all_colors[0], all_colors[1]], - align=["left", "center"], - height=25, - font=dict(color=["darkslategray", "black"], size=15), - ), - ) - ] - ) - fig.update_layout( - title=dict( - text="Interference Type Classification", - font=dict(color="darkslategray", size=20), - x=0.5, - ), - width=600, - ) - fig.show() - - -# - - - -# ## Create a legend -# -# Create a legend, defining the interference types and colors used to display the results of -# the analysis. - - -def create_legend_table(): - """Create a table showing the interference types.""" - classifications = [ - "In-band/In-band", - "Out-of-band/In-band", - "In-band/Out-of-band", - "Out-of-band/Out-of-band", - ] - fig = go.Figure( - data=[ - go.Table( - header=dict( - values=["Interference Type (Source/Victim)"], - line_color="darkslategray", - fill_color=header_color, - align=["center"], - font=dict(color="white", size=16), - ), - cells=dict( - values=[classifications], - line_color="darkslategray", - fill_color=[ - [ - table_colors["red"], - table_colors["orange"], - table_colors["yellow"], - table_colors["green"], - ] - ], - align=["center"], - height=25, - font=dict(color=["darkslategray", "black"], size=15), - ), - ) - ] - ) - fig.update_layout( - title=dict( - text="Interference Type Classification", - font=dict(color="darkslategray", size=20), - x=0.5, - ), - width=600, - ) - fig.show() - - -# Create a scenario view for all the interference types -create_scenario_view(power_matrix, all_colors, tx_radios, rx_radios) - -# Create a legend for the interference types -create_legend_table() - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. -# If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell -# removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/high_frequency/antenna/interferences/interference_type.py b/examples/high_frequency/antenna/interferences/interference_type.py deleted file mode 100644 index 0d5453e61..000000000 --- a/examples/high_frequency/antenna/interferences/interference_type.py +++ /dev/null @@ -1,735 +0,0 @@ -# # Interference type classification using a GUI -# -# This example uses a GUI to open an AEDT project with -# an EMIT design and analyze the results to classify the -# worst-case interference. -# -# > **Note:** This example requires PySide6. -# -# Keywords: **EMIT**, **user interface**. - -# ## Perform imports and define constants -# -# Perform required imports. - -import os -import sys - -import ansys.aedt.core -import openpyxl -from ansys.aedt.core import get_pyaedt_app -from ansys.aedt.core.emit_core.emit_constants import InterfererType -from openpyxl.styles import PatternFill -from PySide6 import QtCore, QtGui, QtUiTools, QtWidgets - -# Define constants. - -AEDT_VERSION = "2024.2" -NG_MODE = False # Open AEDT UI when it is launched. - -# Uncomment the following code if there are Qt plugin errors -# import PySide6 -# dirname = os.path.dirname(PySide6.__file__) -# plugin_path = os.path.join(dirname, 'plugins', 'platforms') -# os.environ['QT_QPA_PLATFORM_PLUGIN_PATH'] = plugin_path - -# ## Launch EMIT - -desktop = ansys.aedt.core.launch_desktop(AEDT_VERSION, NG_MODE, new_desktop=True) - -# ## Add ``EmitApiPython`` module to system path to import it - -emit_path = os.path.join(desktop.install_path, "Delcross") -sys.path.insert(0, emit_path) -import EmitApiPython - -api = EmitApiPython.EmitApi() - -# ## Define GUI -# -# Define the UI extension file. - -ui_file = ansys.aedt.core.downloads.download_file("emit", "interference_gui.ui") -Ui_MainWindow, _ = QtUiTools.loadUiType(ui_file) - -# Customize the GUI. - -# + -class DoubleDelegate(QtWidgets.QStyledItemDelegate): - def __init__(self, decimals, values, max_power, min_power): - super().__init__() - self.decimals = decimals - self.values = values - self.max_power = max_power - self.min_power = min_power - - def createEditor(self, parent, option, index): - editor = super().createEditor(parent, option, index) - if isinstance(editor, QtWidgets.QLineEdit): - validator = QtGui.QDoubleValidator(parent) - num_rows = len(self.values) - cur_row = index.row() - if cur_row == 0: - min_val = self.values[1] - max_val = self.max_power - elif cur_row == num_rows - 1: - min_val = self.min_power - max_val = self.values[cur_row - 1] - else: - min_val = self.values[cur_row + 1] - max_val = self.values[cur_row - 1] - validator.setRange(min_val, max_val, self.decimals) - validator.setNotation(QtGui.QDoubleValidator.Notation.StandardNotation) - editor.setValidator(validator) - return editor - - def update_values(self, values): - self.values = values - - -# - - -# + -class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): - def __init__(self): - super(MainWindow, self).__init__() - self.emitapp = None - self.populating_dropdown = False - self.setupUi(self) - self.setup_widgets() - - # ## Setup widgets - # - # Define all widgets from the UI file, connect the widgets to functions, define - # table colors, and format table settings. - - def setup_widgets(self): - # Widget definitions for file selection/tab management - self.file_select_btn = self.findChild(QtWidgets.QToolButton, "file_select_btn") - self.file_path_box = self.findChild(QtWidgets.QLineEdit, "file_path_box") - self.design_name_dropdown = self.findChild( - QtWidgets.QComboBox, "design_name_dropdown" - ) - self.design_name_dropdown.setEnabled(True) - self.tab_widget = self.findChild(QtWidgets.QTabWidget, "tab_widget") - - # Widget definitions for protection level classification - self.protection_results_btn = self.findChild( - QtWidgets.QPushButton, "protection_results_btn" - ) - self.protection_matrix = self.findChild( - QtWidgets.QTableWidget, "protection_matrix" - ) - self.protection_legend_table = self.findChild( - QtWidgets.QTableWidget, "protection_legend_table" - ) - - self.damage_check = self.findChild(QtWidgets.QCheckBox, "damage_check") - self.overload_check = self.findChild(QtWidgets.QCheckBox, "overload_check") - self.intermodulation_check = self.findChild( - QtWidgets.QCheckBox, "intermodulation_check" - ) - self.desensitization_check = self.findChild( - QtWidgets.QCheckBox, "desensitization_check" - ) - self.protection_export_btn = self.findChild( - QtWidgets.QPushButton, "protection_export_btn" - ) - self.radio_specific_levels = self.findChild( - QtWidgets.QCheckBox, "radio_specific_levels" - ) - self.radio_dropdown = self.findChild(QtWidgets.QComboBox, "radio_dropdown") - self.protection_save_img_btn = self.findChild( - QtWidgets.QPushButton, "protection_save_img_btn" - ) - - # warning label - self.warning_label = self.findChild(QtWidgets.QLabel, "warnings") - myFont = QtGui.QFont() - myFont.setBold(True) - self.warning_label.setFont(myFont) - self.warning_label.setHidden(True) - self.design_name_dropdown.currentIndexChanged.connect( - self.design_dropdown_changed - ) - - # Setup for protection level buttons and table - self.protection_results_btn.setEnabled(False) - self.protection_export_btn.setEnabled(False) - self.protection_save_img_btn.setEnabled(False) - self.file_select_btn.clicked.connect(self.open_file_dialog) - self.protection_export_btn.clicked.connect(self.save_results_excel) - self.protection_results_btn.clicked.connect(self.protection_results) - self.protection_legend_table.resizeRowsToContents() - self.protection_legend_table.resizeColumnsToContents() - self.damage_check.stateChanged.connect(self.protection_results) - self.overload_check.stateChanged.connect(self.protection_results) - self.intermodulation_check.stateChanged.connect(self.protection_results) - self.desensitization_check.stateChanged.connect(self.protection_results) - self.protection_legend_table.setEditTriggers( - QtWidgets.QTableWidget.DoubleClicked - ) - self.global_protection_level = True - self.protection_levels = {} - values = [ - float(self.protection_legend_table.item(row, 0).text()) - for row in range(self.protection_legend_table.rowCount()) - ] - self.protection_levels["Global"] = values - self.changing = False - self.radio_dropdown.currentIndexChanged.connect(self.radio_dropdown_changed) - self.protection_legend_table.itemChanged.connect(self.table_changed) - self.protection_save_img_btn.clicked.connect(self.save_image) - - # Widget definitions for interference type - self.interference_results_btn = self.findChild( - QtWidgets.QPushButton, "interference_results_btn" - ) - self.interference_matrix = self.findChild( - QtWidgets.QTableWidget, "interference_matrix" - ) - self.interference_legend_table = self.findChild( - QtWidgets.QTableWidget, "interference_legend_table" - ) - - # set the items read only - for i in range(0, self.interference_legend_table.rowCount()): - item = self.interference_legend_table.item(i, 0) - item.setFlags(QtCore.Qt.ItemIsEnabled) - self.interference_legend_table.setItem(i, 0, item) - - self.in_in_check = self.findChild(QtWidgets.QCheckBox, "in_in_check") - self.in_out_check = self.findChild(QtWidgets.QCheckBox, "in_out_check") - self.out_in_check = self.findChild(QtWidgets.QCheckBox, "out_in_check") - self.out_out_check = self.findChild(QtWidgets.QCheckBox, "out_out_check") - self.interference_export_btn = self.findChild( - QtWidgets.QPushButton, "interference_export_btn" - ) - self.interference_save_img_btn = self.findChild( - QtWidgets.QPushButton, "interference_save_img_btn" - ) - - # Setup for interference type buttons and table - self.interference_results_btn.setEnabled(False) - self.interference_export_btn.setEnabled(False) - self.interference_save_img_btn.setEnabled(False) - self.interference_export_btn.clicked.connect(self.save_results_excel) - self.interference_results_btn.clicked.connect(self.interference_results) - self.interference_legend_table.resizeRowsToContents() - self.interference_legend_table.resizeColumnsToContents() - self.in_in_check.stateChanged.connect(self.interference_results) - self.in_out_check.stateChanged.connect(self.interference_results) - self.out_in_check.stateChanged.connect(self.interference_results) - self.out_out_check.stateChanged.connect(self.interference_results) - self.radio_specific_levels.stateChanged.connect(self.radio_specific) - self.interference_save_img_btn.clicked.connect(self.save_image) - - # Color definition dictionary and previous project/design names - self.color_dict = { - "green": [QtGui.QColor(125, 115, 202), "#7d73ca"], - "yellow": [QtGui.QColor(211, 89, 162), "#d359a2"], - "orange": [QtGui.QColor(255, 99, 97), "#ff6361"], - "red": [QtGui.QColor(255, 166, 0), "#ffa600"], - "white": [QtGui.QColor("white"), "#ffffff"], - } - self.previous_design = "" - self.previous_project = "" - - # Set the legend tables to stretch resize mode - header = self.protection_legend_table.horizontalHeader() - v_header = self.protection_legend_table.verticalHeader() - - header.setSectionResizeMode(0, QtWidgets.QHeaderView.ResizeMode.Stretch) - v_header.setSectionResizeMode(0, QtWidgets.QHeaderView.ResizeMode.Stretch) - v_header.setSectionResizeMode(1, QtWidgets.QHeaderView.ResizeMode.Stretch) - v_header.setSectionResizeMode(2, QtWidgets.QHeaderView.ResizeMode.Stretch) - v_header.setSectionResizeMode(3, QtWidgets.QHeaderView.ResizeMode.Stretch) - - header = self.interference_legend_table.horizontalHeader() - v_header = self.interference_legend_table.verticalHeader() - - header.setSectionResizeMode(0, QtWidgets.QHeaderView.ResizeMode.Stretch) - v_header.setSectionResizeMode(0, QtWidgets.QHeaderView.ResizeMode.Stretch) - v_header.setSectionResizeMode(1, QtWidgets.QHeaderView.ResizeMode.Stretch) - v_header.setSectionResizeMode(2, QtWidgets.QHeaderView.ResizeMode.Stretch) - v_header.setSectionResizeMode(3, QtWidgets.QHeaderView.ResizeMode.Stretch) - - # Input validation for protection level legend table - self.delegate = DoubleDelegate( - decimals=2, values=values, max_power=1000, min_power=-200 - ) - self.protection_legend_table.setItemDelegateForColumn(0, self.delegate) - self.open_file_dialog() - - # ## Open file dialog and select project - # - # Open the file dialog for project selection and populate the design dropdown - # with all EMIT designs in the project. - - def open_file_dialog(self): - fname, _ = QtWidgets.QFileDialog.getOpenFileName( - self, - "Select EMIT Project", - "", - "Ansys Electronics Desktop Files (*.aedt)", - ) - if fname: - self.file_path_box.setText(fname) - - # Close previous project and open specified one - if self.emitapp is not None: - self.emitapp.close_project() - self.emitapp = None - desktop_proj = desktop.load_project(self.file_path_box.text()) - - # check for an empty project (i.e. no designs) - if isinstance(desktop_proj, bool): - self.file_path_box.setText("") - msg = QtWidgets.QMessageBox() - msg.setWindowTitle("Error: Project missing designs.") - msg.setText( - "The selected project has no designs. Projects must have at least " - "one EMIT design. See AEDT log for more information." - ) - x = msg.exec() - return - - # Check if project is already open - if desktop_proj.lock_file == None: - msg = QtWidgets.QMessageBox() - msg.setWindowTitle("Error: Project already open") - msg.setText( - "Project is locked. Close or remove the lock before proceeding. See AEDT log for more information." - ) - x = msg.exec() - return - - # Populate design dropdown with all design names - designs = desktop_proj.design_list - emit_designs = [] - self.populating_dropdown = True - self.design_name_dropdown.clear() - self.populating_dropdown = False - for d in designs: - design_type = desktop.design_type(desktop_proj.project_name, d) - if design_type == "EMIT": - emit_designs.append(d) - - # Add warning if no EMIT design - # NOTE: This should never happen because loading a project without an EMIT design - # should add a blank EMIT design - self.warning_label.setHidden(True) - if len(emit_designs) == 0: - self.warning_label.setText( - "Warning: The project must contain at least one EMIT design." - ) - self.warning_label.setHidden(False) - return - - self.populating_dropdown = True - self.design_name_dropdown.addItems(emit_designs) - self.populating_dropdown = False - self.emitapp = get_pyaedt_app(desktop_proj.project_name, emit_designs[0]) - self.design_name_dropdown.setCurrentIndex(0) - - # Check for at least 2 radios - radios = self.emitapp.modeler.components.get_radios() - self.warning_label.setHidden(True) - if len(radios) < 2: - self.warning_label.setText( - "Warning: The selected design must contain at least two radios." - ) - self.warning_label.setHidden(False) - - if self.radio_specific_levels.isEnabled(): - self.radio_specific_levels.setChecked(False) - self.radio_dropdown.clear() - self.radio_dropdown.setEnabled(False) - self.protection_levels = {} - values = [ - float(self.protection_legend_table.item(row, 0).text()) - for row in range(self.protection_legend_table.rowCount()) - ] - self.protection_levels["Global"] = values - - self.radio_specific_levels.setEnabled(True) - self.protection_results_btn.setEnabled(True) - self.interference_results_btn.setEnabled(True) - - # ### Change design selection - # - # Refresh the warning messages when the selected design changes - - def design_dropdown_changed(self): - if self.populating_dropdown: - # Don't load design's on initial project load - return - - design_name = self.design_name_dropdown.currentText() - self.emitapp = get_pyaedt_app(self.emitapp.project_name, design_name) - # Check for at least 2 radios - radios = self.emitapp.modeler.components.get_radios() - self.warning_label.setHidden(True) - if len(radios) < 2: - self.warning_label.setText( - "Warning: The selected design must contain at least two radios." - ) - self.warning_label.setHidden(False) - - # Clear the table if the design is changed - self.clear_table() - - # ### Enable radio specific protection levels - # - # Activate radio selection dropdown and initialize dictionary to store protection levels - # when the radio-specific level dropdown is checked. - - def radio_specific(self): - self.radio_dropdown.setEnabled(self.radio_specific_levels.isChecked()) - self.radio_dropdown.clear() - if self.radio_dropdown.isEnabled(): - self.emitapp.set_active_design(self.design_name_dropdown.currentText()) - radios = self.emitapp.modeler.components.get_radios() - values = [ - float(self.protection_legend_table.item(row, 0).text()) - for row in range(self.protection_legend_table.rowCount()) - ] - for radio in radios: - if radios[radio].has_rx_channels(): - self.protection_levels[radio] = values - self.radio_dropdown.addItem(radio) - else: - self.radio_dropdown.clear() - values = [ - float(self.protection_legend_table.item(row, 0).text()) - for row in range(self.protection_legend_table.rowCount()) - ] - self.protection_levels["Global"] = values - self.global_protection_level = not self.radio_specific_levels.isChecked() - - # ### Update legend table - # - # Update shown legend table values when the radio dropdown value changes. - - def radio_dropdown_changed(self): - if self.radio_dropdown.isEnabled(): - self.changing = True - for row in range(self.protection_legend_table.rowCount()): - item = self.protection_legend_table.item(row, 0) - item.setText( - str(self.protection_levels[self.radio_dropdown.currentText()][row]) - ) - self.changing = False - # update the validator so min/max for each row is properly set - values = [ - float(self.protection_legend_table.item(row, 0).text()) - for row in range(self.protection_legend_table.rowCount()) - ] - self.delegate.update_values(values) - - # ### Save legend table values - # - # Save inputted radio protection level threshold values every time one is changed - # in the legend table. - - def table_changed(self): - if self.changing == False: - values = [ - float(self.protection_legend_table.item(row, 0).text()) - for row in range(self.protection_legend_table.rowCount()) - ] - if self.radio_dropdown.currentText() == "": - index = "Global" - else: - index = self.radio_dropdown.currentText() - self.protection_levels[index] = values - self.delegate.update_values(values) - - # ### Save scenario matrix to as PNG file - # - # Save the scenario matrix table as a PNG file. - - def save_image(self): - if self.tab_widget.currentIndex() == 0: - table = self.protection_matrix - else: - table = self.interference_matrix - - fname, _ = QtWidgets.QFileDialog.getSaveFileName( - self, "Save Scenario Matrix", "Scenario Matrix", "png (*.png)" - ) - if fname: - image = QtGui.QImage(table.size(), QtGui.QImage.Format_ARGB32) - table.render(image) - image.save(fname) - - # ### Save scenario matrix to Excel file - # - # Write the scenario matrix results to an Excel file with color coding. - - def save_results_excel(self): - defaultName = "" - if self.tab_widget.currentIndex() == 0: - table = self.protection_matrix - defaultName = "Protection Level Classification" - else: - table = self.interference_matrix - defaultName = "Interference Type Classification" - - fname, _ = QtWidgets.QFileDialog.getSaveFileName( - self, "Save Scenario Matrix", defaultName, "xlsx (*.xlsx)" - ) - - if fname: - workbook = openpyxl.Workbook() - worksheet = workbook.active - header = self.tx_radios[:] - header.insert(0, "Tx/Rx") - worksheet.append(header) - for row in range(2, table.rowCount() + 2): - worksheet.cell(row=row, column=1, value=str(self.rx_radios[row - 2])) - for col in range(2, table.columnCount() + 2): - text = str(table.item(row - 2, col - 2).text()) - worksheet.cell(row=row, column=col, value=text) - cell = worksheet.cell(row, col) - cell.fill = PatternFill( - start_color=self.color_dict[self.all_colors[col - 2][row - 2]][ - 1 - ][1:], - end_color=self.color_dict[self.all_colors[col - 2][row - 2]][1][ - 1: - ], - fill_type="solid", - ) - workbook.save(fname) - - # ### Run interference type simulation - # - # Run interference type simulation and classify results. - - def interference_results(self): - # Initialize filter check marks and expected filter results - self.interference_checks = [ - self.in_in_check.isChecked(), - self.out_in_check.isChecked(), - self.in_out_check.isChecked(), - self.out_out_check.isChecked(), - ] - - self.interference_filters = [ - "TxFundamental:In-band", - ["TxHarmonic/Spurious:In-band", "Intermod:In-band", "Broadband:In-band"], - "TxFundamental:Out-of-band", - [ - "TxHarmonic/Spurious:Out-of-band", - "Intermod:Out-of-band", - "Broadband:Out-of-band", - ], - ] - - # Create list of problem types to analyze according to inputted filters - filter = [ - i - for (i, v) in zip(self.interference_filters, self.interference_checks) - if v - ] - - if ( - self.file_path_box.text() != "" - and self.design_name_dropdown.currentText() != "" - ): - if ( - self.previous_design != self.design_name_dropdown.currentText() - or self.previous_project != self.file_path_box.text() - ): - self.previous_design = self.design_name_dropdown.currentText() - self.previous_project = self.file_path_box.text() - self.emitapp.set_active_design(self.design_name_dropdown.currentText()) - - # Check if file is read-only - if self.emitapp.save_project() == False: - msg = QtWidgets.QMessageBox() - msg.setWindowTitle("Writing Error") - msg.setText( - "An error occurred while writing to the file. Is it readonly? Disk full? See AEDT log for more information." - ) - x = msg.exec() - return - - # Get results and radios - self.rev = self.emitapp.results.analyze() - self.tx_interferer = InterfererType().TRANSMITTERS - self.rx_radios = self.rev.get_receiver_names() - self.tx_radios = self.rev.get_interferer_names(self.tx_interferer) - - # Check if design is valid - if self.tx_radios is None or self.rx_radios is None: - return - - # Classify the interference - # Iterate over all the transmitters and receivers and compute the power - # at the input to each receiver due to each of the transmitters. Compute - # which, if any, type of interference occurred. - domain = self.emitapp.results.interaction_domain() - ( - self.all_colors, - self.power_matrix, - ) = self.rev.interference_type_classification( - domain, use_filter=True, filter_list=filter - ) - - # Save project and plot results on table widget - self.emitapp.save_project() - self.populate_table() - - # ### Run protection level simulation - # - # Run protection level simulation and classify results according to inputted - # threshold levels. - - def protection_results(self): - # Initialize filter check marks and expected filter results - self.protection_checks = [ - self.damage_check.isChecked(), - self.overload_check.isChecked(), - self.intermodulation_check.isChecked(), - self.desensitization_check.isChecked(), - ] - - self.protection_filters = [ - "damage", - "overload", - "intermodulation", - "desensitization", - ] - - filter = [ - i for (i, v) in zip(self.protection_filters, self.protection_checks) if v - ] - - if ( - self.file_path_box.text() != "" - and self.design_name_dropdown.currentText() != "" - ): - if ( - self.previous_design != self.design_name_dropdown.currentText() - or self.previous_project != self.file_path_box.text() - ): - self.previous_design = self.design_name_dropdown.currentText() - self.previous_project = self.file_path_box.text() - self.emitapp.set_active_design(self.design_name_dropdown.currentText()) - - # Check if file is read-only - if self.emitapp.save_project() == False: - msg = QtWidgets.QMessageBox() - msg.setWindowTitle("Writing Error") - msg.setText( - "An error occurred while writing to the file. Is it readonly? Disk full? See AEDT log for more information." - ) - x = msg.exec() - return - - # Get results and design radios - self.tx_interferer = InterfererType().TRANSMITTERS - self.rev = self.emitapp.results.analyze() - self.rx_radios = self.rev.get_receiver_names() - self.tx_radios = self.rev.get_interferer_names(self.tx_interferer) - - # Check if there are radios in the design - if self.tx_radios is None or self.rx_radios is None: - return - - domain = self.emitapp.results.interaction_domain() - ( - self.all_colors, - self.power_matrix, - ) = self.rev.protection_level_classification( - domain, - self.global_protection_level, - self.protection_levels["Global"], - self.protection_levels, - use_filter=True, - filter_list=filter, - ) - - self.populate_table() - - # ### Populate the scenario matrix - # - # Create a scenario matrix view with the transmitters defined across the top - # and receivers down the left-most column. - - def populate_table(self): - if self.tab_widget.currentIndex() == 0: - table = self.protection_matrix - button = self.protection_export_btn - img_btn = self.protection_save_img_btn - else: - table = self.interference_matrix - button = self.interference_export_btn - img_btn = self.interference_save_img_btn - - num_cols = len(self.all_colors) - num_rows = len(self.all_colors[0]) - table.setColumnCount(num_cols) - table.setRowCount(num_rows) - table.setVerticalHeaderLabels(self.rx_radios) - table.setHorizontalHeaderLabels(self.tx_radios) - - for col in range(num_cols): - for row in range(num_rows): - item = QtWidgets.QTableWidgetItem(str(self.power_matrix[col][row])) - table.setItem(row, col, item) - cell = table.item(row, col) - cell.setBackground(self.color_dict[self.all_colors[col][row]][0]) - - button.setEnabled(True) - img_btn.setEnabled(True) - - def clear_table(self): - # get the table/buttons based on current tab - if self.tab_widget.currentIndex() == 0: - table = self.protection_matrix - button = self.protection_export_btn - img_btn = self.protection_save_img_btn - else: - table = self.interference_matrix - button = self.interference_export_btn - img_btn = self.interference_save_img_btn - - # disable export options - button.setEnabled(False) - img_btn.setEnabled(False) - - # clear the table - table.setColumnCount(0) - table.setRowCount(0) - - # ### GUI closing event - # - # Close AEDT if the GUI is closed. - def closeEvent(self, event): - msg = QtWidgets.QMessageBox() - msg.setWindowTitle("Closing GUI") - msg.setText("Closing AEDT. Wait for the GUI to close on its own.") - x = msg.exec() - if self.emitapp: - self.emitapp.close_project() - self.emitapp.close_desktop() - else: - desktop.release_desktop(True, True) - - -# - - -# ## Run GUI -# -# Run the GUI. - -if __name__ == "__main__": - app = QtWidgets.QApplication([]) - window = MainWindow() - window.show() - app.exec() -else: - desktop.release_desktop(True, True) diff --git a/examples/high_frequency/antenna/interferences/protection.py b/examples/high_frequency/antenna/interferences/protection.py deleted file mode 100644 index 847fe7cc6..000000000 --- a/examples/high_frequency/antenna/interferences/protection.py +++ /dev/null @@ -1,288 +0,0 @@ -# # Compute receiver protection levels -# -# This example shows how to open an AEDT project with -# an EMIT design and analyze the results to determine if the received -# power at the input to each receiver exceeds the specified protection -# levels. -# -# Keywords: **EMIT**, **protection levels**. - -# ## Perform imports and define constants -# - -import os -import sys -import tempfile -import time - -import plotly.graph_objects as go -from ansys.aedt.core import Emit - -# from ansys.aedt.core.emit_core.emit_constants import \ -# InterfererType # noqa: F401 - -# Define constants. - -AEDT_VERSION = "2024.2" -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Launch AEDT with EMIT -# -# Launch AEDT with EMIT. The ``Desktop`` class initializes AEDT and starts it -# on the specified version and in the specified graphical mode. -# -# Check that the correct version of EMIT is installed. - -if AEDT_VERSION <= "2023.1": - print("Warning: This example requires AEDT 2023.2 or later.") - sys.exit() - -project_name = os.path.join(temp_folder.name, "emit.aedt") - -emitapp = Emit( - non_graphical=NG_MODE, new_desktop=True, project=project_name, version=AEDT_VERSION -) - -# ## Specify protection levels -# -# The protection levels are specified in dBm. -# If the damage threshold is exceeded, permanent damage to the receiver front -# end may occur. -# Exceeding the overload threshold severely densensitizes the receiver. -# Exceeding the intermod threshold can drive the victim receiver into non-linear -# operation, where it operates as a mixer. -# Exceeding the desense threshold reduces the signal-to-noise ratio and can -# reduce the maximum range, maximum bandwidth, and/or the overall link quality. - -# + -header_color = "grey" -damage_threshold = 30 -overload_threshold = -4 -intermod_threshold = -30 -desense_threshold = -104 - -protection_levels = [ - damage_threshold, - overload_threshold, - intermod_threshold, - desense_threshold, -] -# - - -# ## Create and connect EMIT components -# -# Set up the scenario with radios connected to antennas. - -bluetooth, blue_ant = emitapp.modeler.components.create_radio_antenna( - "Bluetooth Low Energy (LE)", "Bluetooth" -) -gps, gps_ant = emitapp.modeler.components.create_radio_antenna("GPS Receiver", "GPS") -wifi, wifi_ant = emitapp.modeler.components.create_radio_antenna( - "WiFi - 802.11-2012", "WiFi" -) - -# ## Configure the radios -# -# Enable the HR-DSSS bands for the Wi-Fi radio and set the power level -# for all transmit bands to -20 dBm. - -# + -bands = wifi.bands() -for band in bands: - if "HR-DSSS" in band.node_name: - if "Ch 1-13" in band.node_name: - band.enabled = True - band.set_band_power_level(-20) - -# Reduce the bluetooth transmit power -bands = bluetooth.bands() -for band in bands: - band.set_band_power_level(-20) - - -def get_radio_node(radio_name): - """Get the radio node that matches the - given radio name. - - Arguments: - radio_name: String name of the radio. - - Returns: Instance of the radio. - """ - if gps.name == radio_name: - radio = gps - elif bluetooth.name == radio_name: - radio = bluetooth - else: - radio = wifi - return radio - - -bands = gps.bands() -for band in bands: - for child in band.children: - if "L2 P(Y)" in band.node_name: - band.enabled = True - else: - band.enabled = False -# - - -# ## Load the results set -# -# Create a results revision and load it for analysis. - -rev = emitapp.results.analyze() - - -# ## Create a legend -# -# Create a legend, defining the thresholds and colors used to display the results of -# the protection level analysis. - - -def create_legend_table(): - """Create a table showing the defined protection levels.""" - protectionLevels = [ - ">{} dBm".format(damage_threshold), - ">{} dBm".format(overload_threshold), - ">{} dBm".format(intermod_threshold), - ">{} dBm".format(desense_threshold), - ] - fig = go.Figure( - data=[ - go.Table( - header=dict( - values=["Interference", "Power Level Threshold"], - line_color="darkslategray", - fill_color=header_color, - align=["left", "center"], - font=dict(color="white", size=16), - ), - cells=dict( - values=[ - ["Damage", "Overload", "Intermodulation", "Clear"], - protectionLevels, - ], - line_color="darkslategray", - fill_color=["white", ["red", "orange", "yellow", "green"]], - align=["left", "center"], - font=dict(color=["darkslategray", "black"], size=15), - ), - ) - ] - ) - fig.update_layout( - title=dict( - text="Protection Levels (dBm)", - font=dict(color="darkslategray", size=20), - x=0.5, - ), - width=600, - ) - fig.show() - - -# ## Create a scenario matrix view -# -# Create a scenario matrix view with the transmitters defined across the top -# and receivers down the left-most column. The power at the input to each -# receiver is shown in each cell of the matrix and color-coded based on the -# protection level thresholds defined. - - -def create_scenario_view(emis, colors, tx_radios, rx_radios): - """Create a scenario matrix-like table with the higher received - power for each Tx-Rx radio combination. The colors - used for the scenario matrix view are based on the highest - protection level that the received power exceeds.""" - fig = go.Figure( - data=[ - go.Table( - header=dict( - values=[ - "Tx/Rx", - "{}".format(tx_radios[0]), - "{}".format(tx_radios[1]), - ], - line_color="darkslategray", - fill_color=header_color, - align=["left", "center"], - font=dict(color="white", size=16), - ), - cells=dict( - values=[rx_radios, emis[0], emis[1]], - line_color="darkslategray", - fill_color=["white", colors[0], colors[1]], - align=["left", "center"], - font=dict(color=["darkslategray", "black"], size=15), - ), - ) - ] - ) - fig.update_layout( - title=dict( - text="Protection Levels (dBm)", - font=dict(color="darkslategray", size=20), - x=0.5, - ), - width=600, - ) - fig.show() - - -# ## Get all the radios in the project -# -# Get lists of all transmitters and receivers in the project. - -# > **Note:** You can uncomment the following code. -# -# rev = emitapp.results.current_revision -# rx_radios = rev.get_receiver_names() -# tx_radios = rev.get_interferer_names(InterfererType.TRANSMITTERS) -# domain = emitapp.results.interaction_domain() - -# ## Classify the results -# -# Iterate over all the transmitters and receivers and compute the power -# at the input to each receiver due to each of the transmitters. Computes -# which protection levels are exceeded by these power levels, if any. - -# > **Note:** Your ability to uncomment the following code depends on whether you uncommented the earlier code. -# -# power_matrix = [] -# all_colors = [] - -# all_colors, power_matrix = rev.protection_level_classification( -# domain, global_levels=protection_levels -# ) - -# ## Create a scenario matrix-like view for the protection levels -# create_scenario_view(power_matrix, all_colors, tx_radios, rx_radios) - -# ## Create a legend for the protection levels -# create_legend_table() - -# ## Release AEDT -# -# Release AEDT and close the example. - -emitapp.save_project() -emitapp.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/high_frequency/antenna/large_scenarios/_static/city.png b/examples/high_frequency/antenna/large_scenarios/_static/city.png deleted file mode 100644 index 359383f12..000000000 Binary files a/examples/high_frequency/antenna/large_scenarios/_static/city.png and /dev/null differ diff --git a/examples/high_frequency/antenna/large_scenarios/_static/doppler.png b/examples/high_frequency/antenna/large_scenarios/_static/doppler.png deleted file mode 100644 index bd47d4b30..000000000 Binary files a/examples/high_frequency/antenna/large_scenarios/_static/doppler.png and /dev/null differ diff --git a/examples/high_frequency/antenna/large_scenarios/_static/reflector.png b/examples/high_frequency/antenna/large_scenarios/_static/reflector.png deleted file mode 100644 index 1a2b52830..000000000 Binary files a/examples/high_frequency/antenna/large_scenarios/_static/reflector.png and /dev/null differ diff --git a/examples/high_frequency/antenna/large_scenarios/_static/time_domain.png b/examples/high_frequency/antenna/large_scenarios/_static/time_domain.png deleted file mode 100644 index 788d36334..000000000 Binary files a/examples/high_frequency/antenna/large_scenarios/_static/time_domain.png and /dev/null differ diff --git a/examples/high_frequency/antenna/large_scenarios/city.py b/examples/high_frequency/antenna/large_scenarios/city.py deleted file mode 100644 index 15a5b0ba5..000000000 --- a/examples/high_frequency/antenna/large_scenarios/city.py +++ /dev/null @@ -1,91 +0,0 @@ -# # Geometry import from maps -# -# This example shows how to use PyAEDT to create an HFSS SBR+ project from -# OpenStreetMap. -# -# Keywords: **HFSS**, **SBR+**, **city**. - -# ## Perform imports and define constants -# -# Perform required imports and set up the local path to the PyAEDT -# directory path. - -import os -import tempfile -import time - -import ansys.aedt.core - -# Define constants. - -AEDT_VERSION = "2024.2" -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Launch HFSS and open project -# -# Launch HFSS and open the project. - -project_name = os.path.join(temp_folder.name, "city.aedt") -app = ansys.aedt.core.Hfss( - project=project_name, - design="Ansys", - solution_type="SBR+", - version=AEDT_VERSION, - new_desktop=True, - non_graphical=NG_MODE, -) - -# ## Define location to import -# -# Define the latitude and longitude of the location to import. - -ansys_home = [40.273726, -80.168269] - -# ## Generate map and import -# -# Assign boundaries. - -app.modeler.import_from_openstreet_map( - ansys_home, - terrain_radius=250, - road_step=3, - plot_before_importing=False, - import_in_aedt=True, -) - -# ## Plot model -# -# Plot the model. - -plot_obj = app.plot(show=False, plot_air_objects=True) -plot_obj.background_color = [153, 203, 255] -plot_obj.zoom = 1.5 -plot_obj.show_grid = False -plot_obj.show_axes = False -plot_obj.bounding_box = False -plot_obj.plot(os.path.join(temp_folder.name, "Source.jpg")) - -# ## Release AEDT -# -# Release AEDT and close the example. - -app.save_project() -app.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/high_frequency/antenna/large_scenarios/doppler.py b/examples/high_frequency/antenna/large_scenarios/doppler.py deleted file mode 100644 index 07f6daea7..000000000 --- a/examples/high_frequency/antenna/large_scenarios/doppler.py +++ /dev/null @@ -1,180 +0,0 @@ -# # Doppler setup -# -# This example shows how to use PyAEDT to create a multipart scenario in HFSS SBR+ -# and set up a doppler analysis. -# -# Keywords: **HFSS**, **SBR+**, **doppler**. - -# ## Perform imports and define constants -# -# Perform required imports. - -import os -import tempfile -import time - -import ansys.aedt.core - -# Define constants. - -AEDT_VERSION = "2024.2" -NUM_CORES = 4 -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Download 3D component -# Download the 3D component that is needed to run the example. - -library_path = ansys.aedt.core.downloads.download_multiparts( - destination=temp_folder.name -) - -# ## Launch HFSS and open project -# -# Launch HFSS and open the project. - -project_name = os.path.join(temp_folder.name, "doppler.aedt") -app = ansys.aedt.core.Hfss( - version=AEDT_VERSION, - solution_type="SBR+", - new_desktop=True, - project=project_name, - close_on_exit=True, - non_graphical=NG_MODE, -) - -# Creation of the "actors" in the scene is comprised of many editing steps. Disabling the autosave option helps -# avoid delays that occur while the project is being saved. - -app.autosave_disable() - -# ## Save project and rename design -# -# Save the project to the temporary folder and rename the design. - -design = "doppler_sbr" -app.rename_design(design) -app.save_project() - -# ## Set up library paths -# -# Specify the location of 3D components used to create the scene. - -actor_lib = os.path.join(library_path, "actor_library") -env_lib = os.path.join(library_path, "environment_library") -radar_lib = os.path.join(library_path, "radar_modules") -env_folder = os.path.join(env_lib, "road1") -person_folder = os.path.join(actor_lib, "person3") -car_folder = os.path.join(actor_lib, "vehicle1") -bike_folder = os.path.join(actor_lib, "bike1") -bird_folder = os.path.join(actor_lib, "bird1") - -# ## Define environment -# -# Define the background environment. - -road1 = app.modeler.add_environment(input_dir=env_folder, name="Bari") -prim = app.modeler - -# ## Place actors -# -# Place actors in the environment. This code places persons, birds, bikes, and cars -# in the environment. - -person1 = app.modeler.add_person( - input_dir=person_folder, - speed=1.0, - global_offset=[25, 1.5, 0], - yaw=180, - name="Massimo", -) -person2 = app.modeler.add_person( - input_dir=person_folder, - speed=1.0, - global_offset=[25, 2.5, 0], - yaw=180, - name="Devin", -) -car1 = app.modeler.add_vehicle( - input_dir=car_folder, speed=8.7, global_offset=[3, -2.5, 0], name="LuxuryCar" -) -bike1 = app.modeler.add_vehicle( - input_dir=bike_folder, - speed=2.1, - global_offset=[24, 3.6, 0], - yaw=180, - name="Alberto_in_bike", -) -bird1 = app.modeler.add_bird( - input_dir=bird_folder, - speed=1.0, - global_offset=[19, 4, 3], - yaw=120, - pitch=-5, - flapping_rate=30, - name="Pigeon", -) -bird2 = app.modeler.add_bird( - input_dir=bird_folder, - speed=1.0, - global_offset=[6, 2, 3], - yaw=-60, - pitch=10, - name="Eagle", -) - -# ## Place radar -# -# Place radar on the car. The radar is created relative to the car's coordinate -# system. - -radar1 = app.create_sbr_radar_from_json( - radar_file=radar_lib, - name="Example_1Tx_1Rx", - offset=[2.57, 0, 0.54], - use_relative_cs=True, - relative_cs_name=car1.cs_name, -) - -# ## Create setup -# -# Create setup and validate it. The ``create_sbr_pulse_doppler_setup()`` method -# creates a setup and a parametric sweep on the time variable with a -# duration of two seconds. The step is computed automatically from CPI. - -setup, sweep = app.create_sbr_pulse_doppler_setup(sweep_time_duration=2) -app.set_sbr_current_sources_options() -app.validate_simple() - -# ## Solve and release AEDT -# -# Solve and release AEDT. To solve, uncomment the ``app.analyze_setup`` command -# to activate the simulation. - -# + -# app.analyze_setup(sweep.name) -# - - -# ## Release AEDT -# -# Release AEDT and close the example. - -app.save_project() -app.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/high_frequency/antenna/large_scenarios/index.rst b/examples/high_frequency/antenna/large_scenarios/index.rst deleted file mode 100644 index 199da1304..000000000 --- a/examples/high_frequency/antenna/large_scenarios/index.rst +++ /dev/null @@ -1,66 +0,0 @@ -Large scenarios -~~~~~~~~~~~~~~~ -These examples use PyAEDT to show some general capabilities of HFSS SBR+ for large scenarios - -.. grid:: 2 - - .. grid-item-card:: Geometry import from maps - :padding: 2 2 2 2 - :link: city - :link-type: doc - - .. image:: _static/city.png - :alt: City - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create an HFSS SBR+ project from OpenStreetMap. - - .. grid-item-card:: Doppler setup - :padding: 2 2 2 2 - :link: doppler - :link-type: doc - - .. image:: _static/doppler.png - :alt: Doppler - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create a multipart scenario in HFSS SBR+ and set up a doppler analysis. - - .. grid-item-card:: Reflector - :padding: 2 2 2 2 - :link: reflector - :link-type: doc - - .. image:: _static/reflector.png - :alt: Reflector - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create an HFSS SBR+ project from an HFSS antenna and run a simulation. - - .. grid-item-card:: HFSS to SBR+ time animation - :padding: 2 2 2 2 - :link: time_domain - :link-type: doc - - .. image:: _static/time_domain.png - :alt: SBR Time - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create an SBR+ time animation and save it to a GIF file. - - - .. toctree:: - :hidden: - - city - doppler - reflector - time_domain diff --git a/examples/high_frequency/antenna/large_scenarios/reflector.py b/examples/high_frequency/antenna/large_scenarios/reflector.py deleted file mode 100644 index 4fb79ca0d..000000000 --- a/examples/high_frequency/antenna/large_scenarios/reflector.py +++ /dev/null @@ -1,130 +0,0 @@ -# # Reflector -# -# This example shows how to use PyAEDT to create an HFSS SBR+ project from an -# HFSS antenna and run a simulation. -# -# Keywords: **HFSS**, **SBR+**, **reflector**. - -# ## Perform imports and define constants -# -# Perform required imports and set up the local path to the path for the PyAEDT -# directory. - -import tempfile -import time - -import ansys.aedt.core - -# Define constants. - -AEDT_VERSION = "2024.2" -NUM_CORES = 4 -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Download project - -project_full_name = ansys.aedt.core.downloads.download_sbr(destination=temp_folder.name) - -# ## Define designs -# -# Define two designs, one source and one target, with each design connected to -# a different object. - -# + -target = ansys.aedt.core.Hfss( - project=project_full_name, - design="Cassegrain_", - solution_type="SBR+", - version=AEDT_VERSION, - new_desktop=True, - non_graphical=NG_MODE, -) - -source = ansys.aedt.core.Hfss( - project=target.project_name, - design="feeder", - version=AEDT_VERSION, -) -# - - -# ## Define linked antenna -# -# Define a linked antenna. This is HFSS far field applied to HFSS SBR+. - -target.create_sbr_linked_antenna( - source, target_cs="feederPosition", field_type="farfield" -) - -# ## Assign boundaries -# -# Assign boundaries. - -target.assign_perfecte_to_sheets(["Reflector", "Subreflector"]) -target.mesh.assign_curvilinear_elements(["Reflector", "Subreflector"]) - -# ## Create setup and solve -# -# Create a setup and solve it. - -setup1 = target.create_setup() -setup1.props["RadiationSetup"] = "ATK_3D" -setup1.props["ComputeFarFields"] = True -setup1.props["RayDensityPerWavelength"] = 2 -setup1.props["MaxNumberOfBounces"] = 3 -setup1["RangeType"] = "SinglePoints" -setup1["RangeStart"] = "10GHz" -target.analyze(cores=NUM_CORES) - -# ## Postprocess -# -# Plot results in AEDT. - -variations = target.available_variations.nominal_w_values_dict -variations["Freq"] = ["10GHz"] -variations["Theta"] = ["All"] -variations["Phi"] = ["All"] -target.post.create_report( - "db(GainTotal)", - target.nominal_adaptive, - variations=variations, - primary_sweep_variable="Theta", - context="ATK_3D", - report_category="Far Fields", -) - -# Plot results using Matplotlib. - -solution = target.post.get_solution_data( - "GainTotal", - target.nominal_adaptive, - variations=variations, - primary_sweep_variable="Theta", - context="ATK_3D", - report_category="Far Fields", -) -solution.plot() - -# ## Release AEDT -# -# Release AEDT and close the example. - -target.save_project() -target.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/high_frequency/antenna/large_scenarios/time_domain.py b/examples/high_frequency/antenna/large_scenarios/time_domain.py deleted file mode 100644 index 58e5c6af8..000000000 --- a/examples/high_frequency/antenna/large_scenarios/time_domain.py +++ /dev/null @@ -1,106 +0,0 @@ -# # HFSS to SBR+ time animation -# -# This example shows how to use PyAEDT to create an SBR+ time animation -# and save it to a GIF file. This example works only on CPython. -# -# Keywords: **HFSS**, **SBR+**, **time domain**, **IFFT**. - -# ## Perform imports and define constants -# -# Perform required imports. - -import os -import tempfile -import time - -from ansys.aedt.core import Hfss, downloads - -# Define constants. - -AEDT_VERSION = "2024.2" -NUM_CORES = 4 -NG_MODE = False # Open AEDT UI when it is launched. - - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - - -# ## Download project - -project_file = downloads.download_sbr_time(destination=temp_folder.name) - -# ## Launch HFSS and analyze - -hfss = Hfss( - project=project_file, - version=AEDT_VERSION, - non_graphical=NG_MODE, - new_desktop=True, -) - -hfss.analyze(cores=NUM_CORES) - -# ## Get solution data -# -# Get solution data. After the simulation is performed, you can load solutions -# in the ``solution_data`` object. - -solution_data = hfss.post.get_solution_data( - expressions=["NearEX", "NearEY", "NearEZ"], - variations={"_u": ["All"], "_v": ["All"], "Freq": ["All"]}, - context="Near_Field", - report_category="Near Fields", -) - -# ## Compute IFFT -# -# Compute IFFT (Inverse Fast Fourier Transform). - -t_matrix = solution_data.ifft("NearE", window=True) - -# ## Export IFFT to CSV file -# -# Export IFFT to a CSV file. - -frames_list_file = solution_data.ifft_to_file( - coord_system_center=[-0.15, 0, 0], - db_val=True, - csv_path=os.path.join(hfss.working_directory, "csv"), -) - -# ## Plot scene -# -# Plot the scene to create the time plot animation - -hfss.post.plot_scene( - frames=frames_list_file, - gif_path=os.path.join(hfss.working_directory, "animation.gif"), - norm_index=15, - dy_rng=35, - show=False, - view="xy", - zoom=1, -) - -# ## Release AEDT -# -# Release AEDT and close the example. - -hfss.save_project() -hfss.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/high_frequency/antenna/patch.py b/examples/high_frequency/antenna/patch.py deleted file mode 100644 index f2fa572a7..000000000 --- a/examples/high_frequency/antenna/patch.py +++ /dev/null @@ -1,124 +0,0 @@ -# # Probe-fed patch antenna -# -# This example shows how to use the ``Stackup3D`` class -# to create and analyze a patch antenna in HFSS. -# -# Note that the HFSS 3D Layout interface may offer advantages for -# laminate structures such as the patch antenna. -# -# Keywords: **HFSS**, **terminal**, **antenna**., **patch**. -# -# ## Perform imports and define constants -# -# Perform required imports. - -import os -import tempfile -import time - -import ansys.aedt.core -from ansys.aedt.core.modeler.advanced_cad.stackup_3d import Stackup3D - -# Define constants. - -AEDT_VERSION = "2024.2" -NUM_CORES = 4 -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Launch HFSS -# -# Launch HFSS and change the length units. - -project_name = os.path.join(temp_folder.name, "patch.aedt") -hfss = ansys.aedt.core.Hfss( - project=project_name, - solution_type="Terminal", - design="patch", - non_graphical=NG_MODE, - new_desktop=True, - version=AEDT_VERSION, -) - -length_units = "mm" -freq_units = "GHz" -hfss.modeler.model_units = length_units - -# ## Create patch -# -# Create the patch. - -# + -stackup = Stackup3D(hfss) -ground = stackup.add_ground_layer( - "ground", material="copper", thickness=0.035, fill_material="air" -) -dielectric = stackup.add_dielectric_layer( - "dielectric", thickness="0.5" + length_units, material="Duroid (tm)" -) -signal = stackup.add_signal_layer( - "signal", material="copper", thickness=0.035, fill_material="air" -) -patch = signal.add_patch( - patch_length=9.57, patch_width=9.25, patch_name="Patch", frequency=1e10 -) - -stackup.resize_around_element(patch) -pad_length = [3, 3, 3, 3, 3, 3] # Air bounding box buffer in mm. -region = hfss.modeler.create_region(pad_length, is_percentage=False) -hfss.assign_radiation_boundary_to_objects(region) - -patch.create_probe_port(ground, rel_x_offset=0.485) -# - - -# ## Set up simulation -# Set up a simulation and analyze it. - -# + -setup = hfss.create_setup(name="Setup1", setup_type="HFSSDriven", Frequency="10GHz") - -setup.create_frequency_sweep( - unit="GHz", - name="Sweep1", - start_frequency=8, - stop_frequency=12, - sweep_type="Interpolating", -) - -hfss.save_project() -hfss.analyze(cores=NUM_CORES) -# - - -# ## Plot S11 -# - -plot_data = hfss.get_traces_for_plot() -report = hfss.post.create_report(plot_data) -solution = report.get_solution_data() -plt = solution.plot(solution.expressions) - -# ## Release AEDT -# -# Release AEDT. - -hfss.save_project() -hfss.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. -# If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell removes -# all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/high_frequency/emc/_static/armoured.png b/examples/high_frequency/emc/_static/armoured.png deleted file mode 100644 index 8b42e319f..000000000 Binary files a/examples/high_frequency/emc/_static/armoured.png and /dev/null differ diff --git a/examples/high_frequency/emc/_static/busbar.png b/examples/high_frequency/emc/_static/busbar.png deleted file mode 100644 index ab9fdbd77..000000000 Binary files a/examples/high_frequency/emc/_static/busbar.png and /dev/null differ diff --git a/examples/high_frequency/emc/_static/choke.png b/examples/high_frequency/emc/_static/choke.png deleted file mode 100644 index 925749435..000000000 Binary files a/examples/high_frequency/emc/_static/choke.png and /dev/null differ diff --git a/examples/high_frequency/emc/_static/eigenmode.png b/examples/high_frequency/emc/_static/eigenmode.png deleted file mode 100644 index 022dc0501..000000000 Binary files a/examples/high_frequency/emc/_static/eigenmode.png and /dev/null differ diff --git a/examples/high_frequency/emc/_static/flex_cable.png b/examples/high_frequency/emc/_static/flex_cable.png deleted file mode 100644 index 79e893794..000000000 Binary files a/examples/high_frequency/emc/_static/flex_cable.png and /dev/null differ diff --git a/examples/high_frequency/emc/_static/subcircuit.png b/examples/high_frequency/emc/_static/subcircuit.png deleted file mode 100644 index 86686eef4..000000000 Binary files a/examples/high_frequency/emc/_static/subcircuit.png and /dev/null differ diff --git a/examples/high_frequency/emc/armoured_cable.py b/examples/high_frequency/emc/armoured_cable.py deleted file mode 100644 index d1f8b1ca7..000000000 --- a/examples/high_frequency/emc/armoured_cable.py +++ /dev/null @@ -1,301 +0,0 @@ -# # Cable parameter identification - -# This example shows how to use PyAEDT to perform these tasks: -# -# - Create a Q2D design using modeler primitives and an imported CAD. -# - Set up the simulation. -# - Link the solution to a Simplorer design. -# -# For information on the cable model used in this example, see -# [4 Core Armoured Power Cable](https://www.luxingcable.com/low-voltage-cables/4-core-armoured-power-cable.html). -# -# Keywords: **Q2D**, **EMC**, **cable**. - -# ## Perform imports and define constants -# -# Perform required imports. - -import math -import os -import tempfile -import time - -import ansys.aedt.core - -# Define constants. - -AEDT_VERSION = "2024.2" -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Set up for model creation -# -# Initialize cable sizing by specifying radii in millimeters. - -c_strand_radius = 2.575 -cable_n_cores = 4 -core_n_strands = 6 -core_xlpe_ins_thickness = 0.5 -core_xy_coord = math.ceil(3 * c_strand_radius + 2 * core_xlpe_ins_thickness) - -# Initialize radii of further structures incrementally adding thicknesses. - -filling_radius = 1.4142 * ( - core_xy_coord + 3 * c_strand_radius + core_xlpe_ins_thickness + 0.5 -) -inner_sheath_radius = filling_radius + 0.75 -armour_thickness = 3 -armour_radius = inner_sheath_radius + armour_thickness -outer_sheath_radius = armour_radius + 2 - -# Initialize radii. - -armour_centre_pos = inner_sheath_radius + armour_thickness / 2.0 -arm_strand_rad = armour_thickness / 2.0 - 0.2 -n_arm_strands = 30 - -# Start an instance of Q2D Extractor, providing the version, project name, design -# name, and type. - -project_name = os.path.join(temp_folder.name, "Q2D_ArmouredCableExample.aedt") -q2d_design_name = "2D_Extractor_Cable" -setup_name = "AnalysisSeetup" -sweep_name = "FreqSweep" -tb_design_name = "CableSystem" -q2d = ansys.aedt.core.Q2d( - project=project_name, - design=q2d_design_name, - version=AEDT_VERSION, - non_graphical=NG_MODE, -) -q2d.modeler.model_units = "mm" - -# Assign variables to the Q3D design. - -core_params = { - "n_cores": str(cable_n_cores), - "n_strands_core": str(core_n_strands), - "c_strand_radius": str(c_strand_radius) + "mm", - "c_strand_xy_coord": str(core_xy_coord) + "mm", -} -outer_params = { - "filling_radius": str(filling_radius) + "mm", - "inner_sheath_radius": str(inner_sheath_radius) + "mm", - "armour_radius": str(armour_radius) + "mm", - "outer_sheath_radius": str(outer_sheath_radius) + "mm", -} -armour_params = { - "armour_centre_pos": str(armour_centre_pos) + "mm", - "arm_strand_rad": str(arm_strand_rad) + "mm", - "n_arm_strands": str(n_arm_strands), -} -for k, v in core_params.items(): - q2d[k] = v -for k, v in outer_params.items(): - q2d[k] = v -for k, v in armour_params.items(): - q2d[k] = v - -# Cable insulators require the definition of specific materials since they are not -# included in the ``Sys`` library. -# -# Define Plastic, PE (cross-linked, wire, and cable grade): - -mat_pe_cable_grade = q2d.materials.add_material("plastic_pe_cable_grade") -mat_pe_cable_grade.conductivity = "1.40573e-16" -mat_pe_cable_grade.permittivity = "2.09762" -mat_pe_cable_grade.dielectric_loss_tangent = "0.000264575" -mat_pe_cable_grade.update() - -# Define Plastic, PP (10% carbon fiber): - -mat_pp = q2d.materials.add_material("plastic_pp_carbon_fiber") -mat_pp.conductivity = "0.0003161" -mat_pp.update() - -# ## Create model -# -# Create the geometry for core strands, fill, and XLPE insulation. - -q2d.modeler.create_coordinate_system( - origin=["c_strand_xy_coord", "c_strand_xy_coord", "0mm"], name="CS_c_strand_1" -) -q2d.modeler.set_working_coordinate_system("CS_c_strand_1") -c1_id = q2d.modeler.create_circle( - origin=["0mm", "0mm", "0mm"], - radius="c_strand_radius", - name="c_strand_1", - material="copper", -) -c2_id = c1_id.duplicate_along_line( - vector=["0mm", "2.0*c_strand_radius", "0mm"], clones=2 -) -q2d.modeler.duplicate_around_axis(c2_id, axis="Z", angle=360 / core_n_strands, clones=6) -c_unite_name = q2d.modeler.unite(q2d.get_all_conductors_names()) - -fill_id = q2d.modeler.create_circle( - origin=["0mm", "0mm", "0mm"], - radius="3*c_strand_radius", - name="c_strand_fill", - material="plastic_pp_carbon_fiber", -) -fill_id.color = (255, 255, 0) - -xlpe_id = q2d.modeler.create_circle( - origin=["0mm", "0mm", "0mm"], - radius="3*c_strand_radius+" + str(core_xlpe_ins_thickness) + "mm", - name="c_strand_xlpe", - material="plastic_pe_cable_grade", -) -xlpe_id.color = (0, 128, 128) - -q2d.modeler.set_working_coordinate_system("Global") - -all_obj_names = q2d.get_all_conductors_names() + q2d.get_all_dielectrics_names() - -q2d.modeler.duplicate_around_axis( - all_obj_names, axis="Z", angle=360 / cable_n_cores, clones=4 -) -cond_names = q2d.get_all_conductors_names() - -# Define the filling object. - -filling_id = q2d.modeler.create_circle( - origin=["0mm", "0mm", "0mm"], - radius="filling_radius", - name="Filling", - material="plastic_pp_carbon_fiber", -) -filling_id.color = (255, 255, 180) - -# Define the inner sheath. - -inner_sheath_id = q2d.modeler.create_circle( - origin=["0mm", "0mm", "0mm"], - radius="inner_sheath_radius", - name="InnerSheath", - material="PVC plastic", -) -inner_sheath_id.color = (0, 0, 0) - -# Create the armature fill. - -arm_fill_id = q2d.modeler.create_circle( - origin=["0mm", "0mm", "0mm"], - radius="armour_radius", - name="ArmourFilling", - material="plastic_pp_carbon_fiber", -) -arm_fill_id.color = (255, 255, 255) - -# Create the geometry for the outer sheath. - -outer_sheath_id = q2d.modeler.create_circle( - origin=["0mm", "0mm", "0mm"], - radius="outer_sheath_radius", - name="OuterSheath", - material="PVC plastic", -) -outer_sheath_id.color = (0, 0, 0) - -# Create the geometry for the armature steel strands. - -arm_strand_1_id = q2d.modeler.create_circle( - origin=["0mm", "armour_centre_pos", "0mm"], - radius="1.1mm", - name="arm_strand_1", - material="steel_stainless", -) -arm_strand_1_id.color = (128, 128, 64) -arm_strand_1_id.duplicate_around_axis( - axis="Z", angle="360deg/n_arm_strands", clones="n_arm_strands" -) -arm_strand_names = q2d.modeler.get_objects_w_string("arm_strand") - -# Define the outer region that defines the solution domain. - -region = q2d.modeler.create_region([500, 500, 500, 500]) -region.material_name = "vacuum" - -# Assign conductors and reference ground. - -obj = [q2d.modeler.get_object_from_name(i) for i in cond_names] -[ - q2d.assign_single_conductor( - name="C1" + str(obj.index(i) + 1), assignment=i, conductor_type="SignalLine" - ) - for i in obj -] -obj = [q2d.modeler.get_object_from_name(i) for i in arm_strand_names] -q2d.assign_single_conductor( - name="gnd", assignment=obj, conductor_type="ReferenceGround" -) -q2d.modeler.fit_all() - -# Specify the design settings. - -lumped_length = "100m" -q2d.design_settings["LumpedLength"] = lumped_length - -# ## Solve model -# -# Insert the setup and frequency sweep. - -q2d_setup = q2d.create_setup(name=setup_name) -q2d_sweep = q2d_setup.add_sweep(name=sweep_name) - -# The cable model is generated by running two solution types: -# -# 1. Capacitance and conductance per unit length (CG). -# For this model, the CG solution runs in a few seconds. -# -# 2. Series resistance and inductance (RL). -# For this model, the solution time can range from 15-20 minutes, -# depending on the available hardware. -# -# Uncomment the following line to run the analysis. - -# + -# q2d.analyze() -# - - -# ## Evaluate results -# -# Add a Simplorer/Twin Builder design and the Q3D dynamic component. - -tb = ansys.aedt.core.TwinBuilder(design=tb_design_name, version=AEDT_VERSION) - -# Add a Q2D dynamic component. - -tb.add_q3d_dynamic_component( - project_name, - q2d_design_name, - q2d_setup.name, - q2d_sweep.name, - model_depth=lumped_length, - coupling_matrix_name="Original", -) - -# ## Release AEDT - -tb.save_project() -tb.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. -# If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell -# removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/high_frequency/emc/busbar.py b/examples/high_frequency/emc/busbar.py deleted file mode 100644 index e05302d52..000000000 --- a/examples/high_frequency/emc/busbar.py +++ /dev/null @@ -1,174 +0,0 @@ -# # Busbar analysis - -# This example shows how to use PyAEDT to create a busbar design in -# Q3D Extractor and run a simulation. -# -# Keywords: **Q3D**, **EMC*, **busbar**. - -# ## Perform imports and define constants -# -# Perform required imports. - -import os -import tempfile -import time - -import ansys.aedt.core - -# Define constants. - -AEDT_VERSION = "2024.2" -NUM_CORES = 4 -NG_MODE = False - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Launch AEDT and Q3D Extractor -# -# Launch AEDT 2024 R2 in graphical mode and launch Q3D Extractor. This example uses SI units. - -q3d = ansys.aedt.core.Q3d( - project=os.path.join(temp_folder.name, "busbar.aedt"), - version=AEDT_VERSION, - non_graphical=NG_MODE, - new_desktop=True, -) - -# ## Create and set up the Q3D model -# -# Create polylines for three busbars and a box for the substrate. - -# + -b1 = q3d.modeler.create_polyline( - points=[[0, 0, 0], [-100, 0, 0]], - name="Bar1", - material="copper", - xsection_type="Rectangle", - xsection_width="5mm", - xsection_height="1mm", -) -q3d.modeler["Bar1"].color = (255, 0, 0) - -q3d.modeler.create_polyline( - points=[[0, -15, 0], [-150, -15, 0]], - name="Bar2", - material="aluminum", - xsection_type="Rectangle", - xsection_width="5mm", - xsection_height="1mm", -) -q3d.modeler["Bar2"].color = (0, 255, 0) - -q3d.modeler.create_polyline( - points=[[0, -30, 0], [-175, -30, 0], [-175, -10, 0]], - name="Bar3", - material="copper", - xsection_type="Rectangle", - xsection_width="5mm", - xsection_height="1mm", -) -q3d.modeler["Bar3"].color = (0, 0, 255) - -q3d.modeler.create_box( - origin=[50, 30, -0.5], - sizes=[-250, -100, -3], - name="substrate", - material="FR4_epoxy", -) -q3d.modeler["substrate"].color = (128, 128, 128) -q3d.modeler["substrate"].transparency = 0.8 - -q3d.plot( - show=False, - output_file=os.path.join(temp_folder.name, "Q3D.jpg"), - plot_air_objects=False, -) -# - - -# Identify nets and assign sources and sinks to all nets. -# There is a source and sink for each busbar. - -# + -q3d.auto_identify_nets() - -q3d.source(assignment="Bar1", direction=q3d.AxisDir.XPos, name="Source1") -q3d.sink(assignment="Bar1", direction=q3d.AxisDir.XNeg, name="Sink1") - -q3d.source(assignment="Bar2", direction=q3d.AxisDir.XPos, name="Source2") -q3d.sink(assignment="Bar2", direction=q3d.AxisDir.XNeg, name="Sink2") -q3d.source(assignment="Bar3", direction=q3d.AxisDir.XPos, name="Source3") -bar3_sink = q3d.sink(assignment="Bar3", direction=q3d.AxisDir.YPos, name="Sink3") -# - - -# Print information about nets and terminal assignments. - -print(q3d.nets) -print(q3d.net_sinks("Bar1")) -print(q3d.net_sinks("Bar2")) -print(q3d.net_sinks("Bar3")) -print(q3d.net_sources("Bar1")) -print(q3d.net_sources("Bar2")) -print(q3d.net_sources("Bar3")) - -# Create the solution setup and define the frequency range for the solution. - -setup1 = q3d.create_setup(props={"AdaptiveFreq": "100MHz"}) -sweep = setup1.add_sweep() -sweep.props["RangeStart"] = "1MHz" -sweep.props["RangeEnd"] = "100MHz" -sweep.props["RangeStep"] = "5MHz" -sweep.update() - -# ### Set up for postprocessing -# -# Specify the traces to display after solving the model. - -data_plot_self = q3d.matrices[0].get_sources_for_plot( - get_self_terms=True, get_mutual_terms=False -) -data_plot_mutual = q3d.get_traces_for_plot( - get_self_terms=False, get_mutual_terms=True, category="C" -) - -# Define a plot and a data table in AEDT for visualizing results. - -q3d.post.create_report(expressions=data_plot_self) -q3d.post.create_report( - expressions=data_plot_mutual, context="Original", plot_type="Data Table" -) - -# ## Analyze -# -# Solve the setup. - -q3d.analyze(cores=NUM_CORES) -q3d.save_project() - -# Retrieve solution data for processing in Python. - -data = q3d.post.get_solution_data(expressions=data_plot_self, context="Original") -data.data_magnitude() -data.plot() - -# ## Release AEDT - -q3d.save_project() -q3d.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. -# If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell -# removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/high_frequency/emc/choke.py b/examples/high_frequency/emc/choke.py deleted file mode 100644 index 8a543fce5..000000000 --- a/examples/high_frequency/emc/choke.py +++ /dev/null @@ -1,263 +0,0 @@ -# # Choke -# -# This example shows how to use PyAEDT to create a choke setup in HFSS. -# -# Keywords: **HFSS**, **EMC**, **choke**, . - -# ## Perform imports and define constants -# -# Perform required imports. - -import json -import os -import tempfile -import time - -import ansys.aedt.core - -# Define constants. - -AEDT_VERSION = "2024.2" -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Launch HFSS - -project_name = os.path.join(temp_folder.name, "choke.aedt") -hfss = ansys.aedt.core.Hfss( - project=project_name, - version=AEDT_VERSION, - non_graphical=NG_MODE, - new_desktop=True, - solution_type="Terminal", -) - -# ## Define parameters -# -# The dictionary values contain the different parameter values of the core and -# the windings that compose the choke. You must not change the main structure of -# the dictionary. The dictionary has many primary keys, including -# ``"Number of Windings"``, ``"Layer"``, and ``"Layer Type"``, that have -# dictionaries as values. The keys of these dictionaries are secondary keys -# of the dictionary values, such as ``"1"``, ``"2"``, ``"3"``, ``"4"``, and -# ``"Simple"``. -# -# You must not modify the primary or secondary keys. You can modify only their values. -# You must not change the data types for these keys. For the dictionaries from -# ``"Number of Windings"`` through ``"Wire Section"``, values must be Boolean. Only -# one value per dictionary can be ``True``. If all values are ``True``, only the first one -# remains set to ``True``. If all values are ``False``, the first value is chosen as the -# correct one by default. For the dictionaries from ``"Core"`` through ``"Inner Winding"``, -# values must be strings, floats, or integers. -# -# Descriptions follow for the primary keys: -# -# - ``"Number of Windings"``: Number of windings around the core. -# - ``"Layer"``: Number of layers of all windings. -# - ``"Layer Type"``: Whether layers of a winding are linked to each other -# - ``"Similar Layer"``: Whether layers of a winding have the same number of turns and -# same spacing between turns. -# - ``"Mode"``: When there are only two windows, whether they are in common or differential mode. -# - ``"Wire Section"``: Type of wire section and number of segments. -# - ``"Core"``: Design of the core. -# - ``"Outer Winding"``: Design of the first layer or outer layer of a winding and the common -# parameters for all layers. -# - ``"Mid Winding"``: Turns and turns spacing (``Coil Pit``) for the second or -# mid layer if it is necessary. -# - ``"Inner Winding"``: Turns and turns spacing (``Coil Pit``) for the third or inner -# layer if it is necessary. -# - ``"Occupation(%)"``: An informative parameter that is useless to modify. -# -# The following parameter values work. You can modify them if you want. - -values = { - "Number of Windings": {"1": False, "2": True, "3": False, "4": False}, - "Layer": {"Simple": False, "Double": True, "Triple": False}, - "Layer Type": {"Separate": False, "Linked": True}, - "Similar Layer": {"Similar": False, "Different": True}, - "Mode": {"Differential": False, "Common": True}, - "Wire Section": {"None": False, "Hexagon": True, "Octagon": False, "Circle": False}, - "Core": { - "Name": "Core", - "Material": "ferrite", - "Inner Radius": 20, - "Outer Radius": 30, - "Height": 10, - "Chamfer": 0.8, - }, - "Outer Winding": { - "Name": "Winding", - "Material": "copper", - "Inner Radius": 20, - "Outer Radius": 30, - "Height": 10, - "Wire Diameter": 1.5, - "Turns": 20, - "Coil Pit(deg)": 0.1, - "Occupation(%)": 0, - }, - "Mid Winding": {"Turns": 25, "Coil Pit(deg)": 0.1, "Occupation(%)": 0}, - "Inner Winding": {"Turns": 4, "Coil Pit(deg)": 0.1, "Occupation(%)": 0}, -} - -# ## Convert dictionary to JSON file -# -# Convert the dictionary to a JSON file. You must supply the path of the -# JSON file as an argument. - -json_path = os.path.join(hfss.working_directory, "choke_example.json") -with open(json_path, "w") as outfile: - json.dump(values, outfile) - -# ## Verify parameters of JSON file -# -# Verify parameters of the JSON file. The ``check_choke_values()`` method takes -# the JSON file path as an argument and does the following: -# -# - Checks if the JSON file is correctly written (as explained earlier). -# - Checks equations on windings parameters to avoid having unintended intersections. - -dictionary_values = hfss.modeler.check_choke_values( - json_path, create_another_file=False -) -print(dictionary_values) - -# ## Create choke -# -# Create the choke. The ``Hfss.modeler.create_choke()`` method takes the JSON file path as an -# argument. - -list_object = hfss.modeler.create_choke(json_path) -print(list_object) -core = list_object[1] -first_winding_list = list_object[2] -second_winding_list = list_object[3] - -# ## Create ground - -ground_radius = 1.2 * dictionary_values[1]["Outer Winding"]["Outer Radius"] -ground_position = [0, 0, first_winding_list[1][0][2] - 2] -ground = hfss.modeler.create_circle( - "XY", ground_position, ground_radius, name="GND", material="copper" -) -coat = hfss.assign_coating(ground, is_infinite_ground=True) -ground.transparency = 0.9 - -# ## Create lumped ports - -port_position_list = [ - [ - first_winding_list[1][0][0], - first_winding_list[1][0][1], - first_winding_list[1][0][2] - 1, - ], - [ - first_winding_list[1][-1][0], - first_winding_list[1][-1][1], - first_winding_list[1][-1][2] - 1, - ], - [ - second_winding_list[1][0][0], - second_winding_list[1][0][1], - second_winding_list[1][0][2] - 1, - ], - [ - second_winding_list[1][-1][0], - second_winding_list[1][-1][1], - second_winding_list[1][-1][2] - 1, - ], -] -port_dimension_list = [2, dictionary_values[1]["Outer Winding"]["Wire Diameter"]] -for position in port_position_list: - sheet = hfss.modeler.create_rectangle( - "XZ", position, port_dimension_list, name="sheet_port" - ) - sheet.move([-dictionary_values[1]["Outer Winding"]["Wire Diameter"] / 2, 0, -1]) - hfss.lumped_port( - assignment=sheet.name, - name="port_" + str(port_position_list.index(position) + 1), - reference=[ground], - ) - -# ## Create mesh - -# + -cylinder_height = 2.5 * dictionary_values[1]["Outer Winding"]["Height"] -cylinder_position = [0, 0, first_winding_list[1][0][2] - 4] -mesh_operation_cylinder = hfss.modeler.create_cylinder( - "XY", - cylinder_position, - ground_radius, - cylinder_height, - num_sides=36, - name="mesh_cylinder", -) - -hfss.mesh.assign_length_mesh( - [mesh_operation_cylinder], - maximum_length=15, - maximum_elements=None, - name="choke_mesh", -) -# - - - -# ## Create boundaries -# -# Create the boundaries. A region with openings is needed to run the analysis. - -region = hfss.modeler.create_region(pad_percent=1000) - - -# ## Create setup -# -# Create a setup with a sweep to run the simulation. Depending on your machine's -# computing power, the simulation can take some time to run. - -setup = hfss.create_setup("MySetup") -setup.props["Frequency"] = "50MHz" -setup["MaximumPasses"] = 10 -hfss.create_linear_count_sweep( - setup=setup.name, - units="MHz", - start_frequency=0.1, - stop_frequency=100, - num_of_freq_points=100, - name="sweep1", - sweep_type="Interpolating", - save_fields=False, -) - -# ## Plot objects - -hfss.modeler.fit_all() -hfss.plot( - show=False, - output_file=os.path.join(hfss.working_directory, "Image.jpg"), - plot_air_objects=False, -) - - -# ## Release AEDT - -hfss.save_project() -hfss.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. -# If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell -# removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/high_frequency/emc/eigenmode.py b/examples/high_frequency/emc/eigenmode.py deleted file mode 100644 index 17d32ee17..000000000 --- a/examples/high_frequency/emc/eigenmode.py +++ /dev/null @@ -1,187 +0,0 @@ -# # Eigenmode filter -# -# This example shows how to use PyAEDT to automate the Eigenmode solver in HFSS. -# Eigenmode analysis can be applied to open radiating structures -# using an absorbing boundary condition. This type of analysis is useful for -# determining the resonant frequency of a geometry or an antenna, and it can be used to refine -# the mesh at the resonance, even when the resonant frequency of the antenna is not known. -# -# The challenge posed by this method is to identify and filter the non-physical modes -# resulting from reflection from boundaries of the main domain. -# Because the Eigenmode solver sorts by frequency and does not filter on the -# quality factor, these virtual modes are present when the Eigenmode approach is -# applied to nominally open structures. -# -# When looking for resonant modes over a wide frequency range for nominally -# enclosed structures, several iterations may be required because the minimum frequency -# is determined manually. Simulations re-run until the complete frequency range is covered -# and all important physical modes are calculated. -# -# The following script finds the physical modes of a model in a wide frequency -# range by automating the solution setup. -# During each simulation, a user-defined number of modes is simulated, and the modes -# with a Q higher than a user-defined value are filtered. -# The next simulation automatically continues to find modes having a frequency higher -# than the last mode of the previous analysis. -# This continues until the maximum frequency in the desired range is achieved. -# -# Keywords: **HFSS**, **Eigenmode**, **resonance**. - -# ## Perform imports and define constants -# -# Perform required imports. - -import os -import tempfile -import time - -import ansys.aedt.core - -# Define constants. - -AEDT_VERSION = "2024.2" -NUM_CORES = 4 -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Download 3D component -# Download the 3D component that is needed to run the example. - -project_path = ansys.aedt.core.downloads.download_file( - "eigenmode", "emi_PCB_house.aedt", temp_folder.name -) - -# ## Launch AEDT - -d = ansys.aedt.core.launch_desktop( - AEDT_VERSION, - non_graphical=NG_MODE, - new_desktop=True, -) - -# ## Launch HFSS -# -# Create an HFSS design. - -hfss = ansys.aedt.core.Hfss( - version=AEDT_VERSION, project=project_path, non_graphical=NG_MODE -) - -# ## Input parameters for Eigenmode solver -# -# The geometry and material should be already set. The analyses are generated by the code. -# The ``num_modes`` parameter is the number of modes during each analysis. The maximum -# allowed number is 20. Entering a number higher than 10 might result in a long simulation -# time as the Eigenmode solver must converge on modes. The ``fmin`` parameter is the lowest -# frequency of interest. The ``fmax`` parameter is the highest frequency of interest. -# The ``limit`` parameter determines which modes are ignored. - -num_modes = 6 -fmin = 1 -fmax = 2 -next_fmin = fmin -setup_nr = 1 -limit = 10 -resonance = {} - -# ## Find modes -# -# The following cell defines a function that can be used to create and solve an Eigenmode setup. -# After solving the model, information about each mode is saved for subsequent processing. - - -def find_resonance(): - # Setup creation - next_min_freq = f"{next_fmin} GHz" - setup_name = f"em_setup{setup_nr}" - setup = hfss.create_setup(setup_name) - setup.props["MinimumFrequency"] = next_min_freq - setup.props["NumModes"] = num_modes - setup.props["ConvergeOnRealFreq"] = True - setup.props["MaximumPasses"] = 10 - setup.props["MinimumPasses"] = 3 - setup.props["MaxDeltaFreq"] = 5 - - # Analyze the Eigenmode setup - hfss.analyze_setup(setup_name, cores=NUM_CORES, use_auto_settings=True) - - # Get the Q and real frequency of each mode - eigen_q_quantities = hfss.post.available_report_quantities( - quantities_category="Eigen Q" - ) - eigen_mode_quantities = hfss.post.available_report_quantities() - data = {} - for i, expression in enumerate(eigen_mode_quantities): - eigen_q_value = hfss.post.get_solution_data( - expressions=eigen_q_quantities[i], - setup_sweep_name=f"{setup_name} : LastAdaptive", - report_category="Eigenmode", - ) - eigen_mode_value = hfss.post.get_solution_data( - expressions=expression, - setup_sweep_name=f"{setup_name} : LastAdaptive", - report_category="Eigenmode", - ) - data[i] = [eigen_q_value.data_real()[0], eigen_mode_value.data_real()[0]] - - print(data) - return data - - -# ## Automate Eigenmode solution -# -# Running the next cell calls the resonance function and saves -# only those modes with a Q higher than the defined -# limit. The ``find_resonance()`` function is called until the complete -# frequency range is covered. -# When the automation ends, the physical modes in the whole frequency -# range are reported. - - -# + -while next_fmin < fmax: - output = find_resonance() - next_fmin = output[len(output) - 1][1] / 1e9 - setup_nr += 1 - cont_res = len(resonance) - for q in output: - if output[q][0] > limit: - resonance[cont_res] = output[q] - cont_res += 1 - -resonance_frequencies = [f"{resonance[i][1] / 1e9:.5} GHz" for i in resonance] -print(str(resonance_frequencies)) -# - - -# Plot the model. - -hfss.modeler.fit_all() -hfss.plot( - show=False, - output_file=os.path.join(hfss.working_directory, "Image.jpg"), - plot_air_objects=False, -) - -# ## Release AEDT - -hfss.save_project() -d.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. -# If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell removes -# all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/high_frequency/emc/flex_cable.py b/examples/high_frequency/emc/flex_cable.py deleted file mode 100644 index 1cb673a89..000000000 --- a/examples/high_frequency/emc/flex_cable.py +++ /dev/null @@ -1,248 +0,0 @@ -# # Flex cable CPWG -# -# This example shows how to use PyAEDT to create a flex cable CPWG -# (coplanar waveguide with ground). -# -# Keywords: **HFSS**, **flex cable**, **CPWG**. - -# ## Perform imports and define constants -# -# Perform required imports. - -import os -import tempfile -from math import cos, radians, sin, sqrt - -import ansys.aedt.core -from ansys.aedt.core.generic.general_methods import generate_unique_name - -# Define constants. - -AEDT_VERSION = "2024.2" - -# ## Set non-graphical mode -# -# Set non-graphical mode. -# You can set ``non_graphical`` either to ``True`` or ``False``. - -non_graphical = False - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Launch AEDT -# -# Launch AEDT, create an HFSS design, and save the project. - -hfss = ansys.aedt.core.Hfss( - version=AEDT_VERSION, - solution_type="DrivenTerminal", - new_desktop=True, - non_graphical=non_graphical, -) -hfss.save_project( - os.path.join(temp_folder.name, generate_unique_name("example") + ".aedt") -) - -# ## Modify design settings -# -# Modify some design settings. - -hfss.change_material_override(True) -hfss.change_automatically_use_causal_materials(True) -hfss.create_open_region("100GHz") -hfss.modeler.model_units = "mil" -hfss.mesh.assign_initial_mesh_from_slider(applycurvilinear=True) - -# ## Create variables -# -# Create input variables for creating the flex cable CPWG. - -# + -total_length = 300 -theta = 120 -r = 100 -width = 3 -height = 0.1 -spacing = 1.53 -gnd_width = 10 -gnd_thickness = 2 - -xt = (total_length - r * radians(theta)) / 2 -# - - -# ## Create bend -# -# The ``create_bending()`` method creates a list of points for -# the bend based on the curvature radius and extension. - - -def create_bending(radius, extension=0): - points = [(-xt, 0, -radius), (0, 0, -radius)] - - for i in [radians(i) for i in range(theta)] + [radians(theta + 0.000000001)]: - points.append((radius * sin(i), 0, -radius * cos(i))) - - x1, y1, z1 = points[-1] - x0, y0, z0 = points[-2] - - scale = (xt + extension) / sqrt((x1 - x0) ** 2 + (z1 - z0) ** 2) - x, y, z = (x1 - x0) * scale + x0, 0, (z1 - z0) * scale + z0 - - points[-1] = (x, y, z) - return points - - -# ## Draw signal line -# -# Draw a signal line to create a bent signal wire. - -points = create_bending(r, 1) -line = hfss.modeler.create_polyline( - points=points, - xsection_type="Rectangle", - xsection_width=height, - xsection_height=width, - material="copper", -) - -# ## Draw ground line -# -# Draw a ground line to create two bent ground wires. - -# + -gnd_r = [(x, spacing + width / 2 + gnd_width / 2, z) for x, y, z in points] -gnd_l = [(x, -y, z) for x, y, z in gnd_r] - -gnd_objs = [] -for gnd in [gnd_r, gnd_l]: - x = hfss.modeler.create_polyline( - points=gnd, - xsection_type="Rectangle", - xsection_width=height, - xsection_height=gnd_width, - material="copper", - ) - x.color = (255, 0, 0) - gnd_objs.append(x) -# - - -# ## Draw dielectric -# -# Draw a dielectric to create a dielectric cable. - -# + -points = create_bending(r + (height + gnd_thickness) / 2) - -fr4 = hfss.modeler.create_polyline( - points=points, - xsection_type="Rectangle", - xsection_width=gnd_thickness, - xsection_height=width + 2 * spacing + 2 * gnd_width, - material="FR4_epoxy", -) -# - - -# ## Create bottom metals -# -# Create the bottom metals. - -# + -points = create_bending(r + height + gnd_thickness, 1) - -bot = hfss.modeler.create_polyline( - points=points, - xsection_type="Rectangle", - xsection_width=height, - xsection_height=width + 2 * spacing + 2 * gnd_width, - material="copper", -) -# - - -# ## Create port interfaces -# -# Create port interfaces (PEC enclosures). - -port_faces = [] -for face, blockname in zip([fr4.top_face_z, fr4.bottom_face_x], ["b1", "b2"]): - xc, yc, zc = face.center - positions = [i.position for i in face.vertices] - - port_sheet_list = [ - ((x - xc) * 10 + xc, (y - yc) + yc, (z - zc) * 10 + zc) for x, y, z in positions - ] - s = hfss.modeler.create_polyline( - port_sheet_list, close_surface=True, cover_surface=True - ) - center = [round(i, 6) for i in s.faces[0].center] - - port_block = hfss.modeler.thicken_sheet(s.name, -5) - port_block.name = blockname - for f in port_block.faces: - - if [round(i, 6) for i in f.center] == center: - port_faces.append(f) - - port_block.material_name = "PEC" - - for i in [line, bot] + gnd_objs: - i.subtract([port_block], True) - - print(port_faces) - -# ## Create boundary condition -# -# Creates a Perfect E boundary condition. - -boundary = [] -for face in [fr4.top_face_y, fr4.bottom_face_y]: - s = hfss.modeler.create_object_from_face(face) - boundary.append(s) - hfss.assign_perfecte_to_sheets(s) - -# ## Create ports -# -# Create ports. - -for s, port_name in zip(port_faces, ["1", "2"]): - reference = [i.name for i in gnd_objs + boundary + [bot]] + ["b1", "b2"] - - hfss.wave_port(s.id, name=port_name, reference=reference) - -# ## Create setup and sweep -# -# Create the setup and sweep. - -setup = hfss.create_setup("setup1") -setup["Frequency"] = "2GHz" -setup.props["MaximumPasses"] = 10 -setup.props["MinimumConvergedPasses"] = 2 -hfss.create_linear_count_sweep( - setup="setup1", - units="GHz", - start_frequency=1e-1, - stop_frequency=4, - num_of_freq_points=101, - name="sweep1", - save_fields=False, - sweep_type="Interpolating", -) - -# ## Release AEDT - -hfss.release_desktop() - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. -# If you've run this example as a Jupyter notebook, you -# can retrieve those project files. -# The following cell removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/high_frequency/emc/index.rst b/examples/high_frequency/emc/index.rst deleted file mode 100644 index cf8480ec3..000000000 --- a/examples/high_frequency/emc/index.rst +++ /dev/null @@ -1,124 +0,0 @@ -EMC -~~~ - -These examples use PyAEDT to show some EMC applications. - -.. grid:: 2 - - .. grid-item-card:: Choke - :padding: 2 2 2 2 - :link: choke - :link-type: doc - - .. image:: _static/choke.png - :alt: Choke - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create a choke setup in HFSS. - - .. grid-item-card:: Eigenmode filter - :padding: 2 2 2 2 - :link: eigenmode - :link-type: doc - - .. image:: _static/eigenmode.png - :alt: Eigenmode - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to automate the Eigenmode solver in HFSS. - - .. grid-item-card:: Flex cable CPWG - :padding: 2 2 2 2 - :link: flex_cable - :link-type: doc - - .. image:: _static/flex_cable.png - :alt: Flex cable - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create a flex cable CPWG (coplanar waveguide with ground). - - .. grid-item-card:: Cable parameter identification - :padding: 2 2 2 2 - :link: armoured_cable - :link-type: doc - - .. image:: _static/armoured.png - :alt: Cable - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create see a 4 Core Armoured Power Cable. - - .. grid-item-card:: Busbar analysis - :padding: 2 2 2 2 - :link: busbar - :link-type: doc - - .. image:: _static/busbar.png - :alt: Busbar - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create a busbar design in Q3D Extractor and run a simulation. - - .. grid-item-card:: Schematic subcircuit management - :padding: 2 2 2 2 - :link: subcircuit - :link-type: doc - - .. image:: _static/subcircuit.png - :alt: Cable - :width: 250px - :height: 200px - :align: center - - This example shows how to add a subcircuit to a circuit design. - It changes the focus within the hierarchy between the child subcircuit and the parent design. - - - .. grid-item-card:: Circuit schematic creation and analysis - :padding: 2 2 2 2 - :link: ../../aedt_general/modeler/circuit_schematic - :link-type: doc - - .. image:: ../../aedt_general/modeler/_static/circuit.png - :alt: Circuit - :width: 250px - :height: 200px - :align: center - - This example shows how to build a circuit schematic and run a transient circuit simulation. - - .. grid-item-card:: RF interference - :padding: 2 2 2 2 - :link: ../antenna/interferences/index - :link-type: doc - - .. image:: ../antenna/_static/emit_simple_cosite.png - :alt: EMIT logo - :width: 250px - :height: 200px - :align: center - - These examples use PyAEDT to show some general capabilities of EMIT for RF interference. - - .. toctree:: - :hidden: - - choke - eigenmode - flex_cable - armoured_cable - busbar - subcircuit - ../../aedt_general/modeler/circuit_schematic - ../antenna/interferences/index diff --git a/examples/high_frequency/emc/subcircuit.py b/examples/high_frequency/emc/subcircuit.py deleted file mode 100644 index dbb8b7392..000000000 --- a/examples/high_frequency/emc/subcircuit.py +++ /dev/null @@ -1,89 +0,0 @@ -# # Schematic subcircuit management -# -# This example shows how to add a subcircuit to a circuit design. -# It changes the focus within the hierarchy between -# the child subcircuit and the parent design. -# -# Keywords: **Circuit**, **EMC**, **schematic**. - -# ## Perform imports and define constants -# -# Perform required imports. - -import os -import tempfile -import time - -import ansys.aedt.core - -# Define constants. - -AEDT_VERSION = "2024.2" -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Launch AEDT with Circuit -# -# Launch AEDT in graphical mode. Instantite an instance of the ``Circuit`` class. - -circuit = ansys.aedt.core.Circuit( - project=os.path.join(temp_folder.name, "SubcircuitExampl.aedt"), - design="SimpleExample", - version=AEDT_VERSION, - non_graphical=NG_MODE, - new_desktop=True, -) -circuit.modeler.schematic_units = "mil" - -# ## Add subcircuit -# -# Add a new subcircuit to the previously created circuit design, creating a -# child circuit. Push this child circuit down into the child subcircuit. - -subcircuit = circuit.modeler.schematic.create_subcircuit(location=[0.0, 0.0]) -subcircuit_name = subcircuit.composed_name -circuit.push_down(subcircuit) - -# ## Parametrize subcircuit -# -# Parametrize the subcircuit and add a resistor, inductor, and a capacitor with -# parameter values. Components are connected in series, -# and the focus is changed to the parent schematic using -# the ``pop_up()`` method. - -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") -c1 = circuit.modeler.schematic.create_capacitor(value="C_val") -p2 = circuit.modeler.schematic.create_interface_port(name="Out") -circuit.modeler.schematic.connect_components_in_series( - assignment=[p1, r1, l1, c1, p2], use_wire=True -) -circuit.pop_up() - -# ## Release AEDT -# -# Release AEDT and close the example. - -circuit.save_project() -circuit.release_desktop() -# Wait 5 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(5) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/high_frequency/index.rst b/examples/high_frequency/index.rst deleted file mode 100644 index b235977dc..000000000 --- a/examples/high_frequency/index.rst +++ /dev/null @@ -1,95 +0,0 @@ -High frequency -============== - -These end-to-end examples show how to use PyAEDT for high-frequency applications. - - -.. grid:: 2 - - .. grid-item-card:: Antenna - :padding: 2 2 2 2 - :link: antenna/index - :link-type: doc - - .. image:: antenna/_static/array.png - :alt: Antenna - :width: 250px - :height: 200px - :align: center - - Antenna examples - - .. grid-item-card:: IC-Package-PCB - :padding: 2 2 2 2 - :link: layout/index - :link-type: doc - - .. image:: ./_static/layout.png - :alt: PCB - :width: 250px - :height: 200px - :align: center - - Layout automation examples - - .. grid-item-card:: Radio frequency and millimeter wave - :padding: 2 2 2 2 - :link: radiofrequency_mmwave/index - :link-type: doc - - .. image:: ./_static/wgf.png - :alt: Filter - :width: 250px - :height: 200px - :align: center - - Radio frequency and millimeter wave examples - - .. grid-item-card:: EMC - :padding: 2 2 2 2 - :link: emc/index - :link-type: doc - - .. image:: ./_static/emc.png - :alt: Busbar - :width: 250px - :height: 200px - :align: center - - EMC examples - - .. grid-item-card:: Multiphysics - :padding: 2 2 2 2 - :link: multiphysics/index - :link-type: doc - - .. image:: ./_static/pcb_stress.png - :alt: Stress PCB - :width: 250px - :height: 200px - :align: center - - Multiphysics examples - - .. grid-item-card:: Report - :padding: 2 2 2 2 - :link: ../aedt_general/report/index - :link-type: doc - - .. image:: ../aedt_general/_static/touchstone.png - :alt: Components - :width: 250px - :height: 200px - :align: center - - These examples use PyAEDT to show some report capabilities. - - .. toctree:: - :hidden: - - antenna/index - radiofrequency_mmwave/index - layout/index - emc/index - multiphysics/index - ../aedt_general/report/index diff --git a/examples/high_frequency/layout/_static/power_integrity.png b/examples/high_frequency/layout/_static/power_integrity.png deleted file mode 100644 index 7ee1c35d3..000000000 Binary files a/examples/high_frequency/layout/_static/power_integrity.png and /dev/null differ diff --git a/examples/high_frequency/layout/_static/pyedb.png b/examples/high_frequency/layout/_static/pyedb.png deleted file mode 100644 index d444d1ccb..000000000 Binary files a/examples/high_frequency/layout/_static/pyedb.png and /dev/null differ diff --git a/examples/high_frequency/layout/_static/pyedb2.png b/examples/high_frequency/layout/_static/pyedb2.png deleted file mode 100644 index 99187454a..000000000 Binary files a/examples/high_frequency/layout/_static/pyedb2.png and /dev/null differ diff --git a/examples/high_frequency/layout/_static/signal_integrity.png b/examples/high_frequency/layout/_static/signal_integrity.png deleted file mode 100644 index 08a183b18..000000000 Binary files a/examples/high_frequency/layout/_static/signal_integrity.png and /dev/null differ diff --git a/examples/high_frequency/layout/_static/user_interface.png b/examples/high_frequency/layout/_static/user_interface.png deleted file mode 100644 index 2b35e10e4..000000000 Binary files a/examples/high_frequency/layout/_static/user_interface.png and /dev/null differ diff --git a/examples/high_frequency/layout/gui_manipulation.py b/examples/high_frequency/layout/gui_manipulation.py deleted file mode 100644 index 9b1c3934d..000000000 --- a/examples/high_frequency/layout/gui_manipulation.py +++ /dev/null @@ -1,97 +0,0 @@ -# # HFSS Layout UI modification -# -# This example shows how to modify the HFSS 3D Layout UI. -# -# -# Keywords: **HFSS 3D Layout**, **UI**, **user interface**. - -# ## Perform imports and define constants -# Perform required imports. - -# + - -import sys -import tempfile -import time - -from ansys.aedt.core import Hfss3dLayout -from ansys.aedt.core.downloads import download_file - -# - - -# Define constants. - -AEDT_VERSION = "2024.2" -NUM_CORES = 4 -NG_MODE = True # Open AEDT UI when it is launched. - -# Check if AEDT is launched in graphical mode. - -if not NG_MODE: - print("Warning: This example requires graphical mode enabled.") - sys.exit() - -# Download example board. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") -aedb = download_file(source="edb/ANSYS-HSD_V1.aedb", destination=temp_folder.name) - - -# ## Launch HFSS 3D Layout -# -# Initialize AEDT and launch HFSS 3D Layout. - -h3d = Hfss3dLayout(aedb, version=AEDT_VERSION, non_graphical=NG_MODE, new_desktop=True) -h3d.save_project() - -# ## Net visibility -# Hide all nets. - -h3d.modeler.change_net_visibility(visible=False) - -# Show two specified nets. - -h3d.modeler.change_net_visibility(["5V", "1V0"], visible=True) - -# Show all layers. - -for layer in h3d.modeler.layers.all_signal_layers: - layer.is_visible = True - -# Change the layer color. - -layer = h3d.modeler.layers.layers[h3d.modeler.layers.layer_id("1_Top")] -layer.set_layer_color(0, 255, 0) -h3d.modeler.fit_all() - -# ## Disable component visibility - -# Disable component visibility for the ``"1_Top"`` and ``"16_Bottom"`` layers. - -top = h3d.modeler.layers.layers[h3d.modeler.layers.layer_id("1_Top")] -top.is_visible_component = False - -bot = h3d.modeler.layers.layers[h3d.modeler.layers.layer_id("16_Bottom")] -bot.is_visible_component = False - -# ## Display the layout -# -# Fit all so that you can visualize all. - -h3d.modeler.fit_all() - -# ## Release AEDT - -h3d.save_project() -h3d.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. -# If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell -# removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/high_frequency/layout/index.rst b/examples/high_frequency/layout/index.rst deleted file mode 100644 index 559934584..000000000 --- a/examples/high_frequency/layout/index.rst +++ /dev/null @@ -1,80 +0,0 @@ -IC-Package-PCB -============== - -These examples use PyAEDT to show some layout applications. - - -.. grid:: 2 - - .. grid-item-card:: Layout preprocessing - :padding: 2 2 2 2 - :link: https://edb.docs.pyansys.com/version/stable/examples/legacy_standalone/index.html - :link-type: url - - .. image:: _static/pyedb.png - :alt: PyEDB - :width: 250px - :height: 200px - :align: center - - Links to examples in the AEDT documentation that show how to use the legacy PyEDB API as a standalone package. - - .. grid-item-card:: PyEDB configuration files - :padding: 2 2 2 2 - :link: https://edb.docs.pyansys.com/version/stable/examples/use_configuration/index.html - :link-type: url - - .. image:: _static/pyedb2.png - :alt: PyEDB2 - :width: 250px - :height: 200px - :align: center - - Links to examples in the PyAEDT documentation that show how to use PyEDB configuration files. - - .. grid-item-card:: Power integrity - :padding: 2 2 2 2 - :link: power_integrity/index - :link-type: doc - - .. image:: _static/power_integrity.png - :alt: Power - :width: 250px - :height: 200px - :align: center - - Provides power integrity examples. - - .. grid-item-card:: Signal integrity - :padding: 2 2 2 2 - :link: signal_integrity/index - :link-type: doc - - .. image:: _static/signal_integrity.png - :alt: Signal - :width: 250px - :height: 200px - :align: center - - Provides signal integrity examples - - .. grid-item-card:: HFSS 3D Layout GUI modificatation - :padding: 2 2 2 2 - :link: gui_manipulation - :link-type: doc - - .. image:: _static/user_interface.png - :alt: UI 3D Layout - :width: 250px - :height: 200px - :align: center - - Provides HFSS 3D Layout GUI modification examples. - - - .. toctree:: - :hidden: - - power_integrity/index - signal_integrity/index - gui_manipulation \ No newline at end of file diff --git a/examples/high_frequency/layout/power_integrity/_static/ac_q3d.png b/examples/high_frequency/layout/power_integrity/_static/ac_q3d.png deleted file mode 100644 index 501bd5780..000000000 Binary files a/examples/high_frequency/layout/power_integrity/_static/ac_q3d.png and /dev/null differ diff --git a/examples/high_frequency/layout/power_integrity/_static/dcir.png b/examples/high_frequency/layout/power_integrity/_static/dcir.png deleted file mode 100644 index 7711754d1..000000000 Binary files a/examples/high_frequency/layout/power_integrity/_static/dcir.png and /dev/null differ diff --git a/examples/high_frequency/layout/power_integrity/_static/dcir_q3d.png b/examples/high_frequency/layout/power_integrity/_static/dcir_q3d.png deleted file mode 100644 index c1bb59c54..000000000 Binary files a/examples/high_frequency/layout/power_integrity/_static/dcir_q3d.png and /dev/null differ diff --git a/examples/high_frequency/layout/power_integrity/_static/power_integrity.png b/examples/high_frequency/layout/power_integrity/_static/power_integrity.png deleted file mode 100644 index 57ec77ca4..000000000 Binary files a/examples/high_frequency/layout/power_integrity/_static/power_integrity.png and /dev/null differ diff --git a/examples/high_frequency/layout/power_integrity/ac_q3d.py b/examples/high_frequency/layout/power_integrity/ac_q3d.py deleted file mode 100644 index 17951052d..000000000 --- a/examples/high_frequency/layout/power_integrity/ac_q3d.py +++ /dev/null @@ -1,185 +0,0 @@ -# # PCB AC analysis - -# This example shows how to use PyAEDT to create a design in -# Q3D Extractor and run a simulation starting from an EDB project. -# -# Keywords: **Q3D**, **PCB**. - -# ## Perform imports and define constants -# -# Perform required imports. - -import os -import tempfile -import time - -import ansys.aedt.core -import pyedb - -# Define constants. - -AEDT_VERSION = "2024.2" -NUM_CORES = 4 -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Set up project files and path -# -# Download needed project file and set up temporary project directory. - -# + -project_dir = os.path.join(temp_folder.name, "edb") -aedb_project = ansys.aedt.core.downloads.download_file( - source="edb/ANSYS-HSD_V1.aedb", destination=project_dir -) - -project_name = os.path.join(temp_folder.name, "HSD") -output_edb = os.path.join(project_dir, project_name + ".aedb") -output_q3d = os.path.join(project_dir, project_name + "_q3d.aedt") -# - - -# ## Open EDB and create cutout -# -# Open the EDB project and create a cutout on the selected nets -# before exporting to Q3D. - -edb = pyedb.Edb(aedb_project, edbversion=AEDT_VERSION) -cutout_points = edb.cutout( - ["CLOCK_I2C_SCL", "CLOCK_I2C_SDA"], - ["GND"], - output_aedb_path=output_edb, - use_pyaedt_extent_computing=True, -) - - -# ## Identify locations of pins -# -# Identify $(x,y)$ pin locations on the components to define where to assign sources -# and sinks for Q3D. - -pin_u13_scl = [ - i for i in edb.components["U13"].pins.values() if i.net_name == "CLOCK_I2C_SCL" -] -pin_u1_scl = [ - i for i in edb.components["U1"].pins.values() if i.net_name == "CLOCK_I2C_SCL" -] -pin_u13_sda = [ - i for i in edb.components["U13"].pins.values() if i.net_name == "CLOCK_I2C_SDA" -] -pin_u1_sda = [ - i for i in edb.components["U1"].pins.values() if i.net_name == "CLOCK_I2C_SDA" -] - -# ## Append Z elevation positions -# -# > **Note:** The factor 1000 converts from meters to millimeters. - -# + -location_u13_scl = [i * 1000 for i in pin_u13_scl[0].position] -location_u13_scl.append(edb.components["U13"].upper_elevation * 1000) - -location_u1_scl = [i * 1000 for i in pin_u1_scl[0].position] -location_u1_scl.append(edb.components["U1"].upper_elevation * 1000) - -location_u13_sda = [i * 1000 for i in pin_u13_sda[0].position] -location_u13_sda.append(edb.components["U13"].upper_elevation * 1000) - -location_u1_sda = [i * 1000 for i in pin_u1_sda[0].position] -location_u1_sda.append(edb.components["U1"].upper_elevation * 1000) -# - - -# ## Save and close EDB -# -# Save and close EDB. Then, open the EDB project in HFSS 3D Layout to generate the 3D model. - -# + -edb.save_edb() -edb.close_edb() - -h3d = ansys.aedt.core.Hfss3dLayout( - output_edb, version=AEDT_VERSION, non_graphical=NG_MODE, new_desktop=True -) -# - - -# ## Set up the Q3D Project -# -# Use HFSS 3D Layout to export the model to Q3D Extractor. The named parameter -# ``keep_net_name=True`` ensures that net names are retained when the model is exported from HFSS 3D Layout. - -setup = h3d.create_setup() -setup.export_to_q3d(output_q3d, keep_net_name=True) -h3d.close_project() -time.sleep(3) - -# Open the newly created Q3D project and display the layout. - -q3d = ansys.aedt.core.Q3d(output_q3d, version=AEDT_VERSION) -q3d.plot( - show=False, - assignment=["CLOCK_I2C_SCL", "CLOCK_I2C_SDA"], - output_file=os.path.join(temp_folder.name, "Q3D.jpg"), - plot_air_objects=False, -) - -# Use the previously calculated positions to identify faces and -# assign sources and sinks on nets. - -f1 = q3d.modeler.get_faceid_from_position(location_u13_scl, assignment="CLOCK_I2C_SCL") -q3d.source(f1, net_name="CLOCK_I2C_SCL") -f1 = q3d.modeler.get_faceid_from_position(location_u13_sda, assignment="CLOCK_I2C_SDA") -q3d.source(f1, net_name="CLOCK_I2C_SDA") -f1 = q3d.modeler.get_faceid_from_position(location_u1_scl, assignment="CLOCK_I2C_SCL") -q3d.sink(f1, net_name="CLOCK_I2C_SCL") -f1 = q3d.modeler.get_faceid_from_position(location_u1_sda, assignment="CLOCK_I2C_SDA") -q3d.sink(f1, net_name="CLOCK_I2C_SDA") - -# Define the solution setup and the frequency sweep ranging from DC to 2GHz. - -setup = q3d.create_setup() -setup.dc_enabled = True -setup.capacitance_enabled = False -sweep = setup.add_sweep() -sweep.add_subrange( - "LinearStep", 0, end=2, count=0.05, unit="GHz", save_single_fields=False, clear=True -) -setup.analyze(cores=NUM_CORES) - -# ## Solve -# -# Compute AC inductance and resistance. - -traces_acl = q3d.post.available_report_quantities(quantities_category="ACL Matrix") -solution = q3d.post.get_solution_data(traces_acl) - -# ## Postprocess -# -# Plot AC inductance and resistance. - -solution.plot() -traces_acr = q3d.post.available_report_quantities(quantities_category="ACR Matrix") -solution2 = q3d.post.get_solution_data(traces_acr) -solution2.plot() - -# ## Release AEDT - -q3d.save_project() -q3d.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. -# If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell -# removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/high_frequency/layout/power_integrity/dcir.py b/examples/high_frequency/layout/power_integrity/dcir.py deleted file mode 100644 index 26bb49f45..000000000 --- a/examples/high_frequency/layout/power_integrity/dcir.py +++ /dev/null @@ -1,219 +0,0 @@ -# # DC IR analysis -# This example shows how to configure EDB for DC IR analysis and load EDB into the HFSS 3D Layout UI for analysis and -# postprocessing. -# -# - Set up EDB: -# -# - Edit via padstack. -# - Assign SPICE model to components. -# - Create pin groups. -# - Create voltage and current sources. -# - Create SIwave DC analysis. -# - Create cutout. -# -# - Import EDB into HFSS 3D Layout: -# -# - Analyze. -# - Get DC IR analysis results. -# -# Keywords: **HFSS 3D Layout**, **DC IR**. - -# ## Perform imports and define constants -# Perform required imports. - -import json -import os -import tempfile -import time - -import ansys.aedt.core -from ansys.aedt.core.downloads import download_file -from pyedb import Edb - -# Define constants. - -AEDT_VERSION = "2024.2" -NUM_CORES = 4 -NG_MODE = False # Open AEDT UI when it is launched. - -# Download example board. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") -aedb = download_file(source="edb/ANSYS-HSD_V1.aedb", destination=temp_folder.name) -download_file( - source="spice", name="ferrite_bead_BLM15BX750SZ1.mod", destination=temp_folder.name -) - -# ## Create configuration file -# This example uses a configuration file to set up the layout for analysis. -# Initialize and create an empty dictionary to host all configurations. - -cfg = dict() - -# Define model library paths. - -cfg["general"] = { - "s_parameter_library": os.path.join(temp_folder.name, "touchstone"), - "spice_model_library": os.path.join(temp_folder.name, "spice"), -} - -# ### Change via hole size and plating thickness - -cfg["padstacks"] = { - "definitions": [ - {"name": "v40h15-3", "hole_diameter": "0.2mm", "hole_plating_thickness": "25um"} - ], -} - -# ### Assign SPICE models - -cfg["spice_models"] = [ - { - "name": "ferrite_bead_BLM15BX750SZ1", # Give a name to the SPICE Mode. - "component_definition": "COIL-1008CS_V", # Part name of the components - "file_path": "ferrite_bead_BLM15BX750SZ1.mod", # File name or full file path to the SPICE file. - "sub_circuit_name": "BLM15BX750SZ1", - "apply_to_all": True, # If True, SPICE model is to be assigned to all components share the same part name. - # If False, only assign SPICE model to components in "components". - "components": [], - } -] - -# ### Create voltage source -# Create a voltage source from a net. - -cfg["sources"] = [ - { - "name": "VSOURCE_5V", - "reference_designator": "U4", - "type": "voltage", - "magnitude": 5, - "positive_terminal": {"net": "5V"}, - "negative_terminal": {"net": "GND"}, - } -] - -# ### Create current sources -# Create current sources between the net and pin group. - -cfg["pin_groups"] = [{"name": "J5_GND", "reference_designator": "J5", "net": "GND"}] - -cfg["sources"].append( - { - "name": "J5_VCCR", - "reference_designator": "J5", - "type": "current", - "magnitude": 0.5, - "positive_terminal": {"net": "SFPA_VCCR"}, - "negative_terminal": { - "pin_group": "J5_GND" # Defined in "pin_groups" section. - }, - } -) -cfg["sources"].append( - { - "name": "J5_VCCT", - "reference_designator": "J5", - "type": "current", - "magnitude": 0.5, - "positive_terminal": {"net": "SFPA_VCCT"}, - "negative_terminal": { - "pin_group": "J5_GND" # Defined in "pin_groups" section. - }, - } -) - -# ### Create SIwave DC analysis - -cfg["setups"] = [{"name": "siwave_dc", "type": "siwave_dc", "dc_slider_position": 0}] - -# ### Define cutout - -cfg["operations"] = { - "cutout": { - "signal_list": ["SFPA_VCCR", "SFPA_VCCT", "5V"], - "reference_list": ["GND"], - "extent_type": "ConvexHull", - "expansion_size": 0.002, - "use_round_corner": False, - "output_aedb_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": False, - "custom_extent": "", - "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, - } -} - -# ### Save configuration as a JSON file - -pi_json = os.path.join(temp_folder.name, "pi.json") -with open(pi_json, "w") as f: - json.dump(cfg, f, indent=4, ensure_ascii=False) - -# ## Load configuration into EDB - -# Load the configuration from the JSON file into EDB. - -edbapp = Edb(aedb, edbversion=AEDT_VERSION) -edbapp.configuration.load(config_file=pi_json) -edbapp.configuration.run() - -# # Load configuration into EDB -edbapp.nets.plot(None, None, color_by_net=True) - -# ## Save and close EDB - -edbapp.save() -edbapp.close() - -# The configured EDB file is saved in the temporary folder. - -print(temp_folder.name) - -# ## Analyze DCIR with SIwave -# -# The HFSS 3D Layout interface to SIwave is used to open the EDB and run the DCIR analysis -# using SIwave - -# ### Load EDB into HFSS 3D Layout. - -siw = ansys.aedt.core.Hfss3dLayout( - aedb, version=AEDT_VERSION, non_graphical=NG_MODE, new_desktop=True -) - -# ### Analyze - -siw.analyze(cores=NUM_CORES) - -# ### Get DC IR results - -siw.get_dcir_element_data_current_source("siwave_dc") - -# ## Release AEDT - -siw.save_project() -siw.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. -# If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell -# removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/high_frequency/layout/power_integrity/dcir_q3d.py b/examples/high_frequency/layout/power_integrity/dcir_q3d.py deleted file mode 100644 index afbb57cd8..000000000 --- a/examples/high_frequency/layout/power_integrity/dcir_q3d.py +++ /dev/null @@ -1,326 +0,0 @@ -# # PCB DCIR analysis -# -# This example shows how to use PyAEDT to create a design in -# Q3D Extractor and run a DC IR drop simulation starting from an EDB project. -# -# Keywords: **Q3D**, **layout**, **DCIR**. - -# ## Perform imports and define constants -# -# Perform required imports. - -import os -import tempfile -import time - -import ansys.aedt.core -import pyedb - -# Define constants. - -AEDT_VERSION = "2024.2" -NUM_CORES = 4 -NG_MODE = False - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") -# ## Set up project files and path -# -# Download needed project file and set up temporary project directory. - -aedb_project = ansys.aedt.core.downloads.download_file( - "edb/ANSYS-HSD_V1.aedb", destination=temp_folder.name -) -coil = ansys.aedt.core.downloads.download_file( - source="inductance_3d_component", - name="air_coil.a3dcomp", - destination=temp_folder.name, -) -res = ansys.aedt.core.downloads.download_file( - source="resistors", name="Res_0402.a3dcomp", destination=temp_folder.name -) -project_name = "HSD" -output_edb = os.path.join(temp_folder.name, project_name + ".aedb") -output_q3d = os.path.join(temp_folder.name, project_name + "_q3d.aedt") - -# ## Open EDB project -# -# Open the EDB project and create a cutout on the selected nets -# before exporting to Q3D. - -edb = pyedb.Edb(aedb_project, edbversion=AEDT_VERSION) -signal_nets = ["1.2V_AVDLL_PLL", "1.2V_AVDDL", "1.2V_DVDDL", "NetR106_1"] -ground_nets = ["GND"] -cutout_points = edb.cutout( - signal_list=signal_nets, - reference_list=ground_nets, - output_aedb_path=output_edb, -) - -# ## Identify pin positions -# -# Identify [x,y] pin locations on the components to define where to assign sources -# and sinks for Q3D. - -pin_u11_scl = [ - i for i in edb.components["U11"].pins.values() if i.net_name == "1.2V_AVDLL_PLL" -] -pin_u9_1 = [i for i in edb.components["U9"].pins.values() if i.net_name == "1.2V_AVDDL"] -pin_u9_2 = [i for i in edb.components["U9"].pins.values() if i.net_name == "1.2V_DVDDL"] -pin_u11_r106 = [ - i for i in edb.components["U11"].pins.values() if i.net_name == "NetR106_1" -] - -# ## Append Z Positions -# -# Compute the Q3D 3D position. The units in EDB are meters so the -# factor 1000 converts from meters to millimeters. - -# + -location_u11_scl = [i * 1000 for i in pin_u11_scl[0].position] -location_u11_scl.append(edb.components["U11"].upper_elevation * 1000) - -location_u9_1_scl = [i * 1000 for i in pin_u9_1[0].position] -location_u9_1_scl.append(edb.components["U9"].upper_elevation * 1000) - -location_u9_2_scl = [i * 1000 for i in pin_u9_2[0].position] -location_u9_2_scl.append(edb.components["U9"].upper_elevation * 1000) - -location_u11_r106 = [i * 1000 for i in pin_u11_r106[0].position] -location_u11_r106.append(edb.components["U11"].upper_elevation * 1000) -# - - -# ## Identify pin positions for 3D components -# -# Identify the pin positions where 3D components of passives are to be added. - -# + -location_l2_1 = [i * 1000 for i in edb.components["L2"].pins["1"].position] -location_l2_1.append(edb.components["L2"].upper_elevation * 1000) -location_l4_1 = [i * 1000 for i in edb.components["L4"].pins["1"].position] -location_l4_1.append(edb.components["L4"].upper_elevation * 1000) - -location_r106_1 = [i * 1000 for i in edb.components["R106"].pins["1"].position] -location_r106_1.append(edb.components["R106"].upper_elevation * 1000) -# - - -# ## Save and close EDB -# -# Save and close EDB. Then, open EDT in HFSS 3D Layout to generate the 3D model. - -# + -edb.save_edb() -edb.close_edb() -time.sleep(3) - -h3d = ansys.aedt.core.Hfss3dLayout( - output_edb, version=AEDT_VERSION, non_graphical=NG_MODE, new_desktop=True -) -# - - -# ## Export to Q3D -# -# Create a dummy setup and export the layout to Q3D. -# The ``keep_net_name`` parameter reassigns Q3D net names from HFSS 3D Layout. - -setup = h3d.create_setup() -setup.export_to_q3d(output_q3d, keep_net_name=True) -h3d.close_project() -time.sleep(3) - -# ## Open Q3D -# -# Launch the newly created Q3D project. - -q3d = ansys.aedt.core.Q3d(output_q3d, version=AEDT_VERSION) -q3d.modeler.delete("GND") -q3d.modeler.delete("16_Bottom_L6") -q3d.delete_all_nets() - -# ## Insert inductors -# -# Create coordinate systems and place 3D component inductors. - -# + -q3d.modeler.create_coordinate_system(location_l2_1, name="L2") -comp = q3d.modeler.insert_3d_component(coil, coordinate_system="L2") -comp.rotate(q3d.AXIS.Z, -90) -comp.parameters["n_turns"] = "3" -comp.parameters["d_wire"] = "100um" -q3d.modeler.set_working_coordinate_system("Global") -q3d.modeler.create_coordinate_system(location_l4_1, name="L4") -comp2 = q3d.modeler.insert_3d_component(coil, coordinate_system="L4") -comp2.rotate(q3d.AXIS.Z, -90) -comp2.parameters["n_turns"] = "3" -comp2.parameters["d_wire"] = "100um" -q3d.modeler.set_working_coordinate_system("Global") - -q3d.modeler.set_working_coordinate_system("Global") -q3d.modeler.create_coordinate_system(location_r106_1, name="R106") -comp3 = q3d.modeler.insert_3d_component( - res, geometry_parameters={"$Resistance": 2000}, coordinate_system="R106" -) -comp3.rotate(q3d.AXIS.Z, -90) - -q3d.modeler.set_working_coordinate_system("Global") -# - - -# ## Delete dielectrics -# -# Delete all dielectric objects since they are not needed in DC analysis. - -# + -q3d.modeler.delete(q3d.modeler.get_objects_by_material("Megtron4")) -q3d.modeler.delete(q3d.modeler.get_objects_by_material("Megtron4_2")) -q3d.modeler.delete(q3d.modeler.get_objects_by_material("Megtron4_3")) -q3d.modeler.delete(q3d.modeler.get_objects_by_material("Solder Resist")) - -objs_copper = q3d.modeler.get_objects_by_material("copper") -objs_copper_names = [i.name for i in objs_copper] -q3d.plot( - show=False, - assignment=objs_copper_names, - plot_as_separate_objects=False, - output_file=os.path.join(temp_folder.name, "Q3D.jpg"), - plot_air_objects=False, -) -# - - -# ## Assign source and sink -# -# Use previously calculated positions to identify faces. Select the net ``1_Top`` and -# assign sources and sinks on nets. - -# + -sink_f = q3d.modeler.create_circle(q3d.PLANE.XY, location_u11_scl, 0.1) -source_f1 = q3d.modeler.create_circle(q3d.PLANE.XY, location_u9_1_scl, 0.1) -source_f2 = q3d.modeler.create_circle(q3d.PLANE.XY, location_u9_2_scl, 0.1) -source_f3 = q3d.modeler.create_circle(q3d.PLANE.XY, location_u11_r106, 0.1) -sources_objs = [source_f1, source_f2, source_f3] - -q3d.auto_identify_nets() - -identified_net = q3d.nets[0] - -q3d.sink(sink_f, net_name=identified_net) - -source1 = q3d.source(source_f1, net_name=identified_net) - -source2 = q3d.source(source_f2, net_name=identified_net) -source3 = q3d.source(source_f3, net_name=identified_net) -sources_bounds = [source1, source2, source3] - -q3d.edit_sources( - dcrl={ - "{}:{}".format(source1.props["Net"], source1.name): "-1.0A", - "{}:{}".format(source2.props["Net"], source2.name): "-1.0A", - "{}:{}".format(source2.props["Net"], source3.name): "-1.0A", - } -) -# - - -# ## Create setup -# -# Create a setup and a frequency sweep from DC to 2GHz. -# Then, analyze the project. - -setup = q3d.create_setup() -setup.dc_enabled = True -setup.capacitance_enabled = False -setup.ac_rl_enabled = False -setup.props["SaveFields"] = True -setup.props["DC"]["Cond"]["MaxPass"] = 3 -setup.analyze() - -# ## Solve setup - -q3d.save_project() -q3d.analyze_setup(setup.name, cores=NUM_CORES) - -# ## Create a named expression -# -# Use PyAEDT advanced fields calculator to add from the expressions catalog the voltage drop. - -voltage_drop = q3d.post.fields_calculator.add_expression("voltage_drop", None) - -# ## Create Phi plot -# -# Compute ACL solutions and plot them. - -# + -plot1 = q3d.post.create_fieldplot_surface( - q3d.modeler.get_objects_by_material("copper"), - quantity=voltage_drop, - intrinsics={"Freq": "1GHz"}, -) - -q3d.post.plot_field_from_fieldplot( - plot1.name, - project_path=temp_folder.name, - mesh_plot=False, - image_format="jpg", - view="isometric", - show=False, - plot_cad_objs=False, - log_scale=False, -) -# - - - -# ## Compute voltage on source circles -# -# Use PyAEDT advanced field calculator to compute the voltage on source circles and get the value -# using the ``get_solution_data()`` method. - -# + -v_surface = { - "name": "", - "description": "Maximum value of voltage on a surface", - "design_type": ["Q3D Extractor"], - "fields_type": ["DC R/L Fields"], - "primary_sweep": "Freq", - "assignment": "", - "assignment_type": ["Face", "Sheet"], - "operations": [ - f"NameOfExpression({voltage_drop})", - "EnterSurface('assignment')", - "Operation('SurfaceValue')", - "Operation('Maximum')", - ], - "report": ["Field_3D"], -} -for source_circle, source_bound in zip(sources_objs, sources_bounds): - v_surface["name"] = "V{}".format(source_bound.name) - q3d.post.fields_calculator.add_expression(v_surface, source_circle.name) - - data = q3d.post.get_solution_data( - "V{}".format(source_bound.name), - q3d.nominal_adaptive, - variations={"Freq": "1GHz"}, - report_category="DC R/L Fields", - ) - if data: - print(data.data_real("V{}".format(source_bound.name))) -# - - -# ## Release AEDT - -q3d.save_project() -q3d.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. -# If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell -# removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/high_frequency/layout/power_integrity/index.rst b/examples/high_frequency/layout/power_integrity/index.rst deleted file mode 100644 index c24e5b8d2..000000000 --- a/examples/high_frequency/layout/power_integrity/index.rst +++ /dev/null @@ -1,112 +0,0 @@ -Power integrity -~~~~~~~~~~~~~~~ - -These examples use PyAEDT to show power integrity examples. - -.. grid:: 2 - - .. grid-item-card:: Power integrity analysis - :padding: 2 2 2 2 - :link: power_integrity - :link-type: doc - - .. image:: _static/power_integrity.png - :alt: Power integrity - :width: 250px - :height: 200px - :align: center - - This example shows how to use the Ansys Electronics Database (EDB) for power integrity analysis. - - .. grid-item-card:: DC IR analysis - :padding: 2 2 2 2 - :link: dcir - :link-type: doc - - .. image:: _static/dcir.png - :alt: DCIR - :width: 250px - :height: 200px - :align: center - - This example shows how to configure EDB for DC IR analysis and load EDB into the HFSS 3D Layout UI for analysis - and postprocessing. - - .. grid-item-card:: PCB DCIR analysis - :padding: 2 2 2 2 - :link: dcir_q3d - :link-type: doc - - .. image:: _static/dcir_q3d.png - :alt: DCIR - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create a design in Q3D Extractor and run a DC IR drop simulation starting - from an EDB project. - - .. grid-item-card:: PCB AC analysis - :padding: 2 2 2 2 - :link: ac_q3d - :link-type: doc - - .. image:: _static/ac_q3d.png - :alt: AC Q3D - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create a design in Q3D Extractor and run a simulation starting - from an EDB project. - - .. grid-item-card:: Circuit schematic creation and analysis - :padding: 2 2 2 2 - :link: ../../../aedt_general/modeler/circuit_schematic - :link-type: doc - - .. image:: ../../../aedt_general/modeler/_static/circuit.png - :alt: Circuit - :width: 250px - :height: 200px - :align: center - - This example shows how to build a circuit schematic and run a transient circuit simulation. - - .. grid-item-card:: Circuit Netlist to Schematic - :padding: 2 2 2 2 - :link: ../../../aedt_general/modeler/netlist_to_schematic - :link-type: doc - - .. image:: ../../../aedt_general/modeler/_static/netlist.png - :alt: Netlist - :width: 250px - :height: 250px - :align: center - - This example shows how to build a circuit schematic and run a transient circuit simulation. - - .. grid-item-card:: Touchstone files - :padding: 2 2 2 2 - :link: ../../../aedt_general/report/touchstone_file - :link-type: doc - - .. image:: ../../../aedt_general/report/_static/touchstone_skitrf.png - :alt: Touchstone file - :width: 250px - :height: 200px - :align: center - - This example shows how to use objects in a Touchstone file without opening AEDT. - - - .. toctree:: - :hidden: - - power_integrity - dcir - dcir_q3d - ac_q3d - ../../../aedt_general/modeler/circuit_schematic - ../../../aedt_general/modeler/netlist_to_schematic - ../../../aedt_general/report/touchstone_file diff --git a/examples/high_frequency/layout/power_integrity/power_integrity.py b/examples/high_frequency/layout/power_integrity/power_integrity.py deleted file mode 100644 index bc997fe29..000000000 --- a/examples/high_frequency/layout/power_integrity/power_integrity.py +++ /dev/null @@ -1,218 +0,0 @@ -# # Power integrity analysis -# This example shows how to use the Ansys Electronics Database (EDB) for power integrity analysis. The -# EDB is loaded into HFSS 3D Layout for analysis and postprocessing. -# -# - Set up EDB consists of these steps: -# -# - Assign S-parameter model to components. -# - Create pin groups. -# - Create ports. -# - Create SIwave SYZ analysis. -# - Create cutout. -# -# - Import EDB into HFSS 3D Layout: -# -# - Analyze. -# - Plot ``$Z_{11}$``. -# -# Keywords: **HFSS 3D Layout**, **power integrity**. - -# ## Perform imports and define constants -# Import the required packages - -import json -import os -import tempfile -import time - -import ansys.aedt.core -from ansys.aedt.core.downloads import download_file - -# Define constants. - -AEDT_VERSION = "2024.2" -NUM_CORES = 4 -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# Download the example PCB data. - -aedb = download_file(source="edb/ANSYS-HSD_V1.aedb", destination=temp_folder.name) -download_file( - source="touchstone", - name="GRM32_DC0V_25degC_series.s2p", - destination=temp_folder.name, -) - -# ## Create configuration file -# This example uses a configuration file to set up the layout for analysis. -# Initialize and create an empty dictionary to host all configurations. - -cfg = dict() - -# Assigns S-parameter models to capacitors. -# The first step is to use the "general" key to specify where the S-parameter files can be found. - -cfg["general"] = {"s_parameter_library": os.path.join(temp_folder.name, "touchstone")} - -# ## Assign model to capactitors -# The model ``GRM32_DC0V_25degC_series.s2p`` is assigned to capacitors C3 and C4, which share the same component part number. -# When "apply_to_all" is ``True``, all components having the part number "CAPC3216X180X20ML20" are assigned the S-parameter model. - -cfg["s_parameters"] = [ - { - "name": "GRM32_DC0V_25degC_series", - "component_definition": "CAPC0603X33X15LL03T05", - "file_path": "GRM32_DC0V_25degC_series.s2p", - "apply_to_all": False, - "components": ["C110", "C206"], - "reference_net": "GND", - "reference_net_per_component": {"C110": "GND"}, - } -] - -# ## Create pin groups -# Pins can be grouped explicitly by the pin name, or pin groups can be assigned by net name using the ''net'' key. -# The following code combine the listed pins on component U2 into two pin groups using the ``net`` key. - - -cfg["pin_groups"] = [ - { - "name": "PIN_GROUP_1", - "reference_designator": "U1", - "pins": ["AD14", "AD15", "AD16", "AD17"], - }, - {"name": "PIN_GROUP_2", "reference_designator": "U1", "net": "GND"}, -] - -# ## Create ports -# Create a circuit port between the two pin groups just created. - -cfg["ports"] = [ - { - "name": "port1", - "reference_designator": "U1", - "type": "circuit", - "positive_terminal": {"pin_group": "PIN_GROUP_1"}, - "negative_terminal": {"pin_group": "PIN_GROUP_2"}, - } -] - -# ## Create SIwave SYZ analysis setup -# Both SIwave and HFSS can be used to run an analysis in the 3D Layout user interface. - -cfg["setups"] = [ - { - "name": "siwave_syz", - "type": "siwave_syz", - "pi_slider_position": 1, - "freq_sweep": [ - { - "name": "Sweep1", - "type": "Interpolation", - "frequencies": [ - { - "distribution": "log scale", - "start": 1e6, - "stop": 1e9, - "samples": 20, - } - ], - } - ], - } -] - -# ## Define cutout -# Define the region of the PCB to be cut out for analysis. - -cfg["operations"] = { - "cutout": { - "signal_list": ["1V0"], - "reference_list": ["GND"], - "extent_type": "ConvexHull", - "expansion_size": 0.002, - "use_round_corner": False, - "output_aedb_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": False, - "custom_extent": "", - "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, - } -} - -# ## Save configuration -# -# Save the configuration file to a JSON file and apply it to layout data using the EDB. - -pi_json = os.path.join(temp_folder.name, "pi.json") -with open(pi_json, "w") as f: - json.dump(cfg, f, indent=4, ensure_ascii=False) - -# ## Load configuration into EDB - -# Load the configuration into EDB from the JSON file. - -edbapp = ansys.aedt.core.Edb(aedb, edbversion=AEDT_VERSION) -edbapp.configuration.load(config_file=pi_json) -edbapp.configuration.run() -edbapp.save() -edbapp.close() - -# The configured EDB file is saved in the temporary folder. - -print(temp_folder.name) - -# ## Analyze in HFSS 3D Layout - -# ### Load EDB into HFSS 3D Layout - -h3d = ansys.aedt.core.Hfss3dLayout( - aedb, version=AEDT_VERSION, non_graphical=NG_MODE, new_desktop=True -) - -# ### Analyze - -h3d.analyze(cores=NUM_CORES) - -# ### Plot impedance - -solutions = h3d.post.get_solution_data(expressions="Z(port1,port1)") -solutions.plot() - -# ## Release AEDT - -h3d.save_project() -h3d.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. -# If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell -# removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/high_frequency/layout/signal_integrity/_static/ami.png b/examples/high_frequency/layout/signal_integrity/_static/ami.png deleted file mode 100644 index d5585a983..000000000 Binary files a/examples/high_frequency/layout/signal_integrity/_static/ami.png and /dev/null differ diff --git a/examples/high_frequency/layout/signal_integrity/_static/circuit_transient.png b/examples/high_frequency/layout/signal_integrity/_static/circuit_transient.png deleted file mode 100644 index 28b02a0db..000000000 Binary files a/examples/high_frequency/layout/signal_integrity/_static/circuit_transient.png and /dev/null differ diff --git a/examples/high_frequency/layout/signal_integrity/_static/com_eye.png b/examples/high_frequency/layout/signal_integrity/_static/com_eye.png deleted file mode 100644 index d29a019d0..000000000 Binary files a/examples/high_frequency/layout/signal_integrity/_static/com_eye.png and /dev/null differ diff --git a/examples/high_frequency/layout/signal_integrity/_static/com_report.png b/examples/high_frequency/layout/signal_integrity/_static/com_report.png deleted file mode 100644 index 93661ef07..000000000 Binary files a/examples/high_frequency/layout/signal_integrity/_static/com_report.png and /dev/null differ diff --git a/examples/high_frequency/layout/signal_integrity/_static/multizone.png b/examples/high_frequency/layout/signal_integrity/_static/multizone.png deleted file mode 100644 index d040d3d1a..000000000 Binary files a/examples/high_frequency/layout/signal_integrity/_static/multizone.png and /dev/null differ diff --git a/examples/high_frequency/layout/signal_integrity/_static/pre_layout_parameterized_pcb.png b/examples/high_frequency/layout/signal_integrity/_static/pre_layout_parameterized_pcb.png deleted file mode 100644 index f75d4a2e6..000000000 Binary files a/examples/high_frequency/layout/signal_integrity/_static/pre_layout_parameterized_pcb.png and /dev/null differ diff --git a/examples/high_frequency/layout/signal_integrity/_static/pre_layout_sma_connector_on_pcb.png b/examples/high_frequency/layout/signal_integrity/_static/pre_layout_sma_connector_on_pcb.png deleted file mode 100644 index 6e921c691..000000000 Binary files a/examples/high_frequency/layout/signal_integrity/_static/pre_layout_sma_connector_on_pcb.png and /dev/null differ diff --git a/examples/high_frequency/layout/signal_integrity/_static/spectrum_plot.png b/examples/high_frequency/layout/signal_integrity/_static/spectrum_plot.png deleted file mode 100644 index 44dc027e8..000000000 Binary files a/examples/high_frequency/layout/signal_integrity/_static/spectrum_plot.png and /dev/null differ diff --git a/examples/high_frequency/layout/signal_integrity/ami.py b/examples/high_frequency/layout/signal_integrity/ami.py deleted file mode 100644 index 63198f48b..000000000 --- a/examples/high_frequency/layout/signal_integrity/ami.py +++ /dev/null @@ -1,332 +0,0 @@ -# # AMI Postprocessing -# -# This example demonstrates advanced postprocessing of AMI simulations. -# -# Keywords: **Circuit**, **AMI**. - -# ## Perform imports and define constants -# -# Perform required imports. -# -# > **Note:** [Numpy](https://numpy.org/) -# > and [Matplotlib](https://matplotlib.org/) are required to run this example. - -# + -import os -import tempfile -import time - -import ansys.aedt.core -import numpy as np -from matplotlib import pyplot as plt - -# - - -# Define constants. - -AEDT_VERSION = "2024.2" -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Create temporary directory and download example files -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Download example data -# -# The ``download_file()`` method retrieves example -# data from the PyAnsys -# [example-data](https://github.com/ansys/example-data/tree/master/pyaedt) repository. -# -# - The fist argument is the folder name where -# the example files are located in the GitHub repository. -# - The 2nd argument is the file to retrieve. -# - The 3rd argument is the destination folder. -# -# Files are placed in the destination folder. - -project_path = ansys.aedt.core.downloads.download_file( - "ami", name="ami_usb.aedtz", destination=temp_folder.name -) - - -# ## Launch AEDT with Circuit and enable Pandas as the output format -# -# All outputs obtained with the `get_solution_data()` method are in the -# [Pandas](https://pandas.pydata.org/docs/user_guide/index.html) format. -# Launch AEDT with Circuit. The `ansys.aedt.core.Desktop` class initializes AEDT -# and starts the specified version in the specified mode. - -ansys.aedt.core.settings.enable_pandas_output = True -circuit = ansys.aedt.core.Circuit( - project=os.path.join(project_path), - non_graphical=NG_MODE, - version=AEDT_VERSION, - new_desktop=True, -) - -# ## Solve AMI setup -# -# Solve the transient setup. - -circuit.analyze() - -# ## Get AMI report -# -# Get AMI report data. - -plot_name = "WaveAfterProbe" -circuit.solution_type = "NexximAMI" -original_data = circuit.post.get_solution_data( - expressions=plot_name, - setup_sweep_name="AMIAnalysis", - domain="Time", - variations=circuit.available_variations.nominal, -) -original_data_value = original_data.full_matrix_real_imag[0] -original_data_sweep = original_data.primary_sweep_values -print(original_data_value) - -# ## Plot data -# -# Create a plot based on solution data. - -fig = original_data.plot() - -# ## Extract wave form -# -# Use the ``WaveAfterProbe`` plot type to extract the -# waveform using an AMI receiver clock probe. -# The signal is extracted at a specific clock -# flank with additional half unit interval. - -probe_name = "b_input_43" -source_name = "b_output4_42" -plot_type = "WaveAfterProbe" -setup_name = "AMIAnalysis" -ignore_bits = 100 -unit_interval = 0.1e-9 -sample_waveform = circuit.post.sample_ami_waveform( - setup=setup_name, - probe=probe_name, - source=source_name, - variation_list_w_value=circuit.available_variations.nominal, - unit_interval=unit_interval, - ignore_bits=ignore_bits, - plot_type=plot_type, -) - -# ## Plot waveform and samples -# -# Create the plot from a start time to stop time in seconds. - -# + -tstop = 55e-9 -tstart = 50e-9 -scale_time = ansys.aedt.core.constants.unit_converter( - 1, - unit_system="Time", - input_units="s", - output_units=original_data.units_sweeps["Time"], -) -scale_data = ansys.aedt.core.constants.unit_converter( - 1, - unit_system="Voltage", - input_units="V", - output_units=original_data.units_data[plot_name], -) - -tstop_ns = scale_time * tstop -tstart_ns = scale_time * tstart - -for time_value in original_data_value[plot_name].index: - if tstart_ns <= time_value[0]: - start_index_original_data = time_value[0] - break -for time_value in original_data_value[plot_name][start_index_original_data:].index: - if time_value[0] >= tstop_ns: - stop_index_original_data = time_value[0] - break -for time_value in sample_waveform[0].index: - if tstart <= time_value: - sample_index = sample_waveform[0].index == time_value - start_index_waveform = sample_index.tolist().index(True) - break -for time_value in sample_waveform[0].index: - if time_value >= tstop: - sample_index = sample_waveform[0].index == time_value - stop_index_waveform = sample_index.tolist().index(True) - break - -original_data_zoom = original_data_value[ - start_index_original_data:stop_index_original_data -] -sampled_data_zoom = ( - sample_waveform[0].values[start_index_waveform:stop_index_waveform] * scale_data -) -sampled_time_zoom = ( - sample_waveform[0].index[start_index_waveform:stop_index_waveform] * scale_time -) - -fig, ax = plt.subplots() -ax.plot(sampled_time_zoom, sampled_data_zoom, "r*") -ax.plot( - np.array(list(original_data_zoom.index.values)), - original_data_zoom.values, - color="blue", -) -ax.set_title("WaveAfterProbe") -ax.set_xlabel(original_data.units_sweeps["Time"]) -ax.set_ylabel(original_data.units_data[plot_name]) -plt.show() -# - - -# ## Plot slicer scatter -# -# Create the plot from a start time to stop time in seconds. - -fig, ax2 = plt.subplots() -ax2.plot(sample_waveform[0].index, sample_waveform[0].values, "r*") -ax2.set_title("Slicer Scatter: WaveAfterProbe") -ax2.set_xlabel("s") -ax2.set_ylabel("V") -plt.show() - -# ## Plot scatter histogram -# -# Create the plot from a start time to stop time in seconds. - -fig, ax4 = plt.subplots() -ax4.set_title("Slicer Histogram: WaveAfterProbe") -ax4.hist(sample_waveform[0].values, orientation="horizontal") -ax4.set_ylabel("V") -ax4.grid() -plt.show() - -# ## Get transient report data - -plot_name = "V(b_input_43.int_ami_rx.eye_probe.out)" -circuit.solution_type = "NexximTransient" -original_data = circuit.post.get_solution_data( - expressions=plot_name, - setup_sweep_name="NexximTransient", - domain="Time", - variations=circuit.available_variations.nominal, -) - -# ## Extract sample waveform -# -# Extract a waveform at a specific clock time plus a half unit interval. - -# + -original_data.enable_pandas_output = False -original_data_value = original_data.data_real() -original_data_sweep = original_data.primary_sweep_values -waveform_unit = original_data.units_data[plot_name] -waveform_sweep_unit = original_data.units_sweeps["Time"] -tics = np.arange(20e-9, 100e-9, 1e-10, dtype=float) - -sample_waveform = circuit.post.sample_waveform( - waveform_data=original_data_value, - waveform_sweep=original_data_sweep, - waveform_unit=waveform_unit, - waveform_sweep_unit=waveform_sweep_unit, - unit_interval=unit_interval, - clock_tics=tics, - pandas_enabled=False, -) -# - - -# ## Plot waveform -# -# Create the plot from a start time to stop time in seconds. - -# + -tstop = 40.0e-9 -tstart = 25.0e-9 -scale_time = ansys.aedt.core.constants.unit_converter( - 1, unit_system="Time", input_units="s", output_units=waveform_sweep_unit -) -scale_data = ansys.aedt.core.constants.unit_converter( - 1, unit_system="Voltage", input_units="V", output_units=waveform_unit -) - -tstop_ns = scale_time * tstop -tstart_ns = scale_time * tstart - -for time_value in original_data_sweep: - if tstart_ns <= time_value: - start_index_original_data = original_data_sweep.index(time_value) - break -for time_value in original_data_sweep[start_index_original_data:]: - if time_value >= tstop_ns: - stop_index_original_data = original_data_sweep.index(time_value) - break -cont = 0 -for frame in sample_waveform: - if tstart <= frame[0]: - start_index_waveform = cont - break - cont += 1 -for frame in sample_waveform[start_index_waveform:]: - if frame[0] >= tstop: - stop_index_waveform = cont - break - cont += 1 - -original_data_zoom = original_data_value[ - start_index_original_data:stop_index_original_data -] -original_sweep_zoom = original_data_sweep[ - start_index_original_data:stop_index_original_data -] -original_data_zoom_array = np.array( - list(map(list, zip(original_sweep_zoom, original_data_zoom))) -) -original_data_zoom_array[:, 0] *= 1 -sampled_data_zoom_array = np.array( - sample_waveform[start_index_waveform:stop_index_waveform] -) -sampled_data_zoom_array[:, 0] *= scale_time -sampled_data_zoom_array[:, 1] *= scale_data - -fig, ax = plt.subplots() -ax.plot(sampled_data_zoom_array[:, 0], sampled_data_zoom_array[:, 1], "r*") -ax.plot(original_sweep_zoom, original_data_zoom_array[:, 1], color="blue") -ax.set_title(plot_name) -ax.set_xlabel(waveform_sweep_unit) -ax.set_ylabel(waveform_unit) -plt.show() -# - - -# ## Plot slicer scatter -# -# Create the plot from a start time to stop time in seconds. - -sample_waveform_array = np.array(sample_waveform) -fig, ax2 = plt.subplots() -ax2.plot(sample_waveform_array[:, 0], sample_waveform_array[:, 1], "r*") -ax2.set_title("Slicer Scatter: " + plot_name) -ax2.set_xlabel("s") -ax2.set_ylabel("V") -plt.show() - -# ## Release AEDT -# -# Release AEDT and close the example. - -circuit.save_project() -circuit.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/high_frequency/layout/signal_integrity/circuit_transient.py b/examples/high_frequency/layout/signal_integrity/circuit_transient.py deleted file mode 100644 index 63a00f72b..000000000 --- a/examples/high_frequency/layout/signal_integrity/circuit_transient.py +++ /dev/null @@ -1,214 +0,0 @@ -# # Circuit transient analysis and eye diagram -# -# This example shows how to create a circuit design, -# run a Nexxim time-domain simulation, and create an eye diagram. -# -# Keywords: **Circuit**, **transient**, **eye diagram**. - -# ## Perform imports and define constants -# -# Perform required imports. - -# + -import os -import tempfile -import time - -import ansys.aedt.core -import numpy as np -from matplotlib import pyplot as plt - -# - - -# Define constants. - -AEDT_VERSION = "2024.2" -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Launch AEDT with Circuit -# -# Launch AEDT in graphical mode with the Circuit schematic editor. - -circuit = ansys.aedt.core.Circuit( - project=os.path.join(temp_folder.name, "CktTransient"), - design="Circuit Examples", - version=AEDT_VERSION, - new_desktop=True, - non_graphical=NG_MODE, -) - -# ## Place IBIS buffer -# -# Read an IBIS file and place a buffer in the schematic editor. - -ibis = circuit.get_ibis_model_from_file( - os.path.join(circuit.desktop_install_dir, "buflib", "IBIS", "u26a_800.ibs") -) -ibs = ibis.buffers["DQ_u26a_800"].insert(0, 0) - -# ## Place ideal transmission line -# -# Place an ideal transmission line in the schematic and parametrize it. - -tr1 = circuit.modeler.components.components_catalog["Ideal Distributed:TRLK_NX"].place( - "tr1" -) -tr1.parameters["P"] = "50mm" - -# ## Place components -# -# Create a resistor and ground in the schematic. - -res = circuit.modeler.components.create_resistor(name="R1", value="1Meg") -gnd1 = circuit.modeler.components.create_gnd() - -# ## Connect componennts -# -# Connect the components in the schematic. - -tr1.pins[0].connect_to_component(ibs.pins[0]) -tr1.pins[1].connect_to_component(res.pins[0]) -res.pins[1].connect_to_component(gnd1.pins[0]) - -# ## Place a probe -# -# Place a voltage probe and rename it to ``Vout``. - -pr1 = circuit.modeler.components.components_catalog["Probes:VPROBE"].place("vout") -pr1.parameters["Name"] = "Vout" -pr1.pins[0].connect_to_component(res.pins[0]) -pr2 = circuit.modeler.components.components_catalog["Probes:VPROBE"].place("Vin") -pr2.parameters["Name"] = "Vin" -pr2.pins[0].connect_to_component(ibs.pins[0]) - -# ## Analyze -# -# Create a transient analysis setup and analyze it. - -trans_setup = circuit.create_setup(name="TransientRun", setup_type="NexximTransient") -trans_setup.props["TransientData"] = ["0.01ns", "200ns"] -circuit.analyze_setup("TransientRun") - -# ## Create report -# -# Create a report using the ``get_solution_data()`` method. This -# method allows you to view and postprocess results using Python packages. -# The ``solutions.plot()`` method uses -# [Matplotlib](https://matplotlib.org/). - -report = circuit.post.create_report("V(Vout)", domain="Time") -if not NG_MODE: - report.add_cartesian_y_marker(0) -solutions = circuit.post.get_solution_data(domain="Time") -solutions.plot("V(Vout)") - -# ## Visualize results -# -# Create a report inside AEDT using the ``new_report`` object. This object is -# fully customizable and usable with most of the reports available in AEDT. -# The standard report is the main one used in Circuit and Twin Builder. - -new_report = circuit.post.reports_by_category.standard("V(Vout)") -new_report.domain = "Time" -new_report.create() -if not NG_MODE: - new_report.add_limit_line_from_points([60, 80], [1, 1], "ns", "V") - vout = new_report.traces[0] - vout.set_trace_properties( - style=vout.LINESTYLE.Dot, - width=2, - trace_type=vout.TRACETYPE.Continuous, - color=(0, 0, 255), - ) - vout.set_symbol_properties( - style=vout.SYMBOLSTYLE.Circle, fill=True, color=(255, 255, 0) - ) - ll = new_report.limit_lines[0] - ll.set_line_properties( - style=ll.LINESTYLE.Solid, - width=4, - hatch_above=True, - violation_emphasis=True, - hatch_pixels=2, - color=(0, 0, 255), - ) -new_report.time_start = "20ns" -new_report.time_stop = "100ns" -new_report.create() -sol = new_report.get_solution_data() -sol.plot() - -# ## Create eye diagram in AEDT -# -# Create an eye diagram inside AEDT using the ``new_eye`` object. - -new_eye = circuit.post.reports_by_category.eye_diagram("V(Vout)") -new_eye.unit_interval = "1e-9s" -new_eye.time_stop = "100ns" -new_eye.create() - -# ## Create eye diagram in Matplotlib -# -# Create the same eye diagram outside AEDT using Matplotlib and the -# ``get_solution_data()`` method. - -# + -unit_interval = 1 -offset = 0.25 -tstop = 200 -tstart = 0 -t_steps = [] -i = tstart + offset -while i < tstop: - i += 2 * unit_interval - t_steps.append(i) - -t = [ - [i for i in solutions.intrinsics["Time"] if k - 2 * unit_interval < i <= k] - for k in t_steps -] -ys = [ - [ - i / 1000 - for i, j in zip(solutions.data_real(), solutions.intrinsics["Time"]) - if k - 2 * unit_interval < j <= k - ] - for k in t_steps -] -fig, ax = plt.subplots(sharex=True) -cells = np.array([]) -cellsv = np.array([]) -for a, b in zip(t, ys): - an = np.array(a) - an = an - an.mean() - bn = np.array(b) - cells = np.append(cells, an) - cellsv = np.append(cellsv, bn) -plt.plot(cells.T, cellsv.T, zorder=0) -plt.show() -# - - -# ## Release AEDT -# -# Release AEDT and close the example. - -circuit.save_project() -circuit.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/high_frequency/layout/signal_integrity/com_analysis.py b/examples/high_frequency/layout/signal_integrity/com_analysis.py deleted file mode 100644 index 3c0fd51a8..000000000 --- a/examples/high_frequency/layout/signal_integrity/com_analysis.py +++ /dev/null @@ -1,143 +0,0 @@ -# # Channel Operating Margin (COM) -# This example shows how to use PyAEDT for COM analysis. -# These standards are supported: -# -# - 50GAUI_1_C2C -# - 100GAUI_2_C2C -# - 200GAUI_4 -# - 400GAUI_8 -# - 100GBASE_KR4 -# - 100GBASE_KP4 - -# - -# ## What is COM? -# -# - COM was developed as part of IEEE 802.3bj, 100GBASE Ethernet. -# - COM is a figure of merit for an S-parameter representing a high-speed SerDes channel. -# - COM is the ratio between eye height and noise. - -# ```math -# COM = 20 * log10 (A_signal / A_noise) -# ``` -# -# Keywords: **COM**, **signal integrity**, **virtual compliance**. - -# ## Perform imports -# Perform required imports. - -import os -import tempfile - -from ansys.aedt.core.visualization.post.spisim import SpiSim -from ansys.aedt.core.visualization.post.spisim_com_configuration_files import \ - com_parameters -from pyedb.misc.downloads import download_file - -# ## Create temporary directory and download example files -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -# + -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -thru = download_file( - directory="com_analysis", - filename="SerDes_Demo_02_Thru.s4p", - destination=temp_folder.name, -) -fext_2_9 = download_file( - directory="com_analysis", - filename="FCI_CC_Long_Link_Pair_2_to_Pair_9_FEXT.s4p", - destination=temp_folder.name, -) -fext_5_9 = download_file( - directory="com_analysis", - filename="FCI_CC_Long_Link_Pair_5_to_Pair_9_FEXT.s4p", - destination=temp_folder.name, -) -next_11_9 = download_file( - directory="com_analysis", - filename="FCI_CC_Long_Link_Pair_11_to_Pair_9_NEXT.s4p", - destination=temp_folder.name, -) -# - - -# ## Run COM analysis -# PyAEDT calls SPISim for COM analysis. For supported standardes, see the PyAEDT documentation. - -# Set ``port_order="EvenOdd"`` when the S-parameter has this port order: -# -# 1 - 2 -# -# 3 - 4 -# -# Set ``port_order="Incremental"`` when the S-parameter has this port order: -# -# 1 - 3 -# -# 2 - 4 - -spi_sim = SpiSim(thru) -com_results = spi_sim.compute_com( - standard=1, # 50GAUI-1-C2C - port_order="EvenOdd", - fext_s4p=[fext_5_9, fext_5_9], - next_s4p=next_11_9, -) - -# ## Print COM values -# There are two COM values reported by the definition of the standard: -# -# - Case 0: COM value in dB when big package is used. -# - Case 1: COM value in dB when small package is used. - -print(*com_results) - -# ## View COM report -# A complete COM report is generated in the temporary folder in HTML format. - -print(temp_folder.name) - -# - -# ## Run COM analysis on custom configuration file - -# ### Export template configuration file in JSON format - -custom_json = os.path.join(temp_folder.name, "custom.json") -spi_sim.export_com_configure_file(custom_json, standard=1) - -# Modify the custom JSON file as needed. - -# ### Import configuration file and run - -com_results = spi_sim.compute_com( - standard=0, # Custom - config_file=custom_json, - port_order="EvenOdd", - fext_s4p=[fext_5_9, fext_5_9], - next_s4p=next_11_9, -) -print(*com_results) - -# ## Export SPISim supported configuration file -# You can use the exported configuration file in the SPISim GUI. - -# + - -com_param = com_parameters.COMParametersVer3p4() -com_param.load(custom_json) -custom_cfg = os.path.join(temp_folder.name, "custom.cfg") -com_param.export_spisim_cfg(custom_cfg) -# - - -# PyAEDT also supports the SPISim configuration file. - -com_results = spi_sim.compute_com( - standard=0, config_file=custom_cfg, port_order="EvenOdd" -) # Custom -print(*com_results) diff --git a/examples/high_frequency/layout/signal_integrity/index.rst b/examples/high_frequency/layout/signal_integrity/index.rst deleted file mode 100644 index be6e40795..000000000 --- a/examples/high_frequency/layout/signal_integrity/index.rst +++ /dev/null @@ -1,166 +0,0 @@ -Signal integrity -~~~~~~~~~~~~~~~~ - -These examples use PyAEDT to show signal integrity examples. - -.. grid:: 2 - - .. grid-item-card:: Channel Operating Margin (COM) - :padding: 2 2 2 2 - :link: com_analysis - :link-type: doc - - .. image:: _static/com_eye.png - :alt: COM - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT for COM analysis. - - .. grid-item-card:: Pre-layout signal integrity - :padding: 2 2 2 2 - :link: pre_layout - :link-type: doc - - .. image:: _static/pre_layout_sma_connector_on_pcb.png - :alt: Pre layout connector - :width: 250px - :height: 200px - :align: center - - This example shows how to create a parameterized layout design and load the layout into HFSS 3D Layout - for analysis and postprocessing. - - .. grid-item-card:: Pre-layout Parameterized PCB - :padding: 2 2 2 2 - :link: pre_layout_parametrized - :link-type: doc - - .. image:: _static/pre_layout_parameterized_pcb.png - :alt: Pre layout parametrized - :width: 250px - :height: 200px - :align: center - - This example shows how to use the EDB interface along with HFSS 3D Layout to create and solve a parameterized layout. - - .. grid-item-card:: AMI Postprocessing - :padding: 2 2 2 2 - :link: ami - :link-type: doc - - .. image:: _static/ami.png - :alt: AMI - :width: 250px - :height: 200px - :align: center - - This example demonstrates advanced postprocessing of AMI simulations. - - .. grid-item-card:: Multi-zone simulation with SIwave - :padding: 2 2 2 2 - :link: multizone - :link-type: doc - - .. image:: _static/multizone.png - :alt: Multizone - :width: 250px - :height: 200px - :align: center - - This example shows how to simulate multiple zones with SIwave. - - .. grid-item-card:: Circuit transient analysis and eye diagram - :padding: 2 2 2 2 - :link: circuit_transient - :link-type: doc - - .. image:: _static/circuit_transient.png - :alt: Circuit transient - :width: 250px - :height: 200px - :align: center - - This example shows how to create a circuit design, run a Nexxim time-domain simulation, and create an eye diagram. - - .. grid-item-card:: Circuit schematic creation and analysis - :padding: 2 2 2 2 - :link: ../../../aedt_general/modeler/circuit_schematic - :link-type: doc - - .. image:: ../../../aedt_general/modeler/_static/circuit.png - :alt: Circuit - :width: 250px - :height: 200px - :align: center - - This example shows how to build a circuit schematic and run a transient circuit simulation. - - .. grid-item-card:: Circuit Netlist to Schematic - :padding: 2 2 2 2 - :link: ../../../aedt_general/modeler/netlist_to_schematic - :link-type: doc - - .. image:: ../../../aedt_general/modeler/_static/netlist.png - :alt: Netlist - :width: 250px - :height: 250px - :align: center - - This example shows how to build a circuit schematic and run a transient circuit simulation. - - .. grid-item-card:: Schematic subcircuit management - :padding: 2 2 2 2 - :link: ../../emc/subcircuit - :link-type: doc - - .. image:: ../../emc/_static/subcircuit.png - :alt: Cable - :width: 250px - :height: 200px - :align: center - - This example shows how to add a subcircuit to a circuit design. - It changes the focus within the hierarchy between the child subcircuit and the parent design. - - .. grid-item-card:: Touchstone files - :padding: 2 2 2 2 - :link: ../../../aedt_general/report/touchstone_file - :link-type: doc - - .. image:: ../../../aedt_general/report/_static/touchstone_skitrf.png - :alt: Touchstone file - :width: 250px - :height: 200px - :align: center - - This example shows how to use objects in a Touchstone file without opening AEDT. - - .. grid-item-card:: PCIE virtual compliance - :padding: 2 2 2 2 - :link: ../../../aedt_general/report/virtual_compliance - :link-type: doc - - .. image:: ../../../aedt_general/report/_static/virtual_compliance_eye.png - :alt: Virtual compliance - :width: 250px - :height: 200px - :align: center - - This example shows how to generate a compliance report in PyAEDT using the VirtualCompliance class. - - .. toctree:: - :hidden: - - com_analysis - pre_layout - pre_layout_parametrized - ami - multizone - circuit_transient - ../../../aedt_general/modeler/circuit_schematic - ../../../aedt_general/modeler/netlist_to_schematic - ../../emc/subcircuit - ../../../aedt_general/report/touchstone_file - ../../../aedt_general/report/virtual_compliance diff --git a/examples/high_frequency/layout/signal_integrity/multizone.py b/examples/high_frequency/layout/signal_integrity/multizone.py deleted file mode 100644 index ca61ba38b..000000000 --- a/examples/high_frequency/layout/signal_integrity/multizone.py +++ /dev/null @@ -1,145 +0,0 @@ -# # Multi-zone simulation with SIwave -# -# This example shows how to simulate multiple zones with SIwave. -# -# Keywords: **Circuit**, **multi-zone**. - -# ## Perform imports and define constants -# -# Perform required imports, which includes importing a section. - -# + -import os.path -import tempfile -import time - -import ansys.aedt.core -from ansys.aedt.core import Circuit, Edb - -# - - -# Define constants. - -EDB_VERSION = "2024.2" - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Download EDB folder - -edb_file = ansys.aedt.core.downloads.download_file( - directory="edb/siwave_multi_zones.aedb", destination=temp_folder.name -) -work_folder = os.path.join(temp_folder.name, "work") -aedt_file = os.path.splitext(edb_file)[0] + ".aedt" -circuit_project_file = os.path.join(temp_folder.name, "multizone_clipped_circuit.aedt") -print(edb_file) - - -# ## Set AEDT version - - -edb_version = EDB_VERSION - -# ## Define ground net -# -# Define the common reference net used across all subdesigns, which is mandatory for this workflow. - -common_reference_net = "GND" - -# ## Load project -# -# Check if the AEDT file exists and remove it to allow EDB loading. Then, load the initial EDB file. - -if os.path.isfile(aedt_file): - os.remove(aedt_file) -edb = Edb(edbversion=edb_version, edbpath=edb_file) - -# ## Copy project zones -# -# Copy project zone into the subproject. - -edb_zones = edb.copy_zones(working_directory=work_folder) - -# ## Split zones -# -# Clip subdesigns along with corresponding zone definitions -# and create a port of clipped signal traces. - -defined_ports, project_connexions = edb.cutout_multizone_layout( - edb_zones, common_reference_net -) - -# ## Create circuit -# -# Create circuit design, import all subprojects as EM models, and connect -# all corresponding pins in the circuit. - -circuit = Circuit(version=edb_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, -) - -# ## Set up simulation -# -# Add Nexxim LNA simulation setup. - -circuit_setup = circuit.create_setup("Pyedt_LNA") - -# ## Add frequency sweep -# -# Add a frequency sweep from 0 GHt to 20 GHz with a 10 NHz frequency step. - -circuit_setup.props["SweepDefinition"]["Data"] = "LIN {} {} {}".format( - "0GHz", "20GHz", "10MHz" -) - -# ## Start simulation -# -# Analyze all SIwave projects and solve the circuit. - -circuit.analyze() - -# Define differential pairs - -circuit.set_differential_pair( - differential_mode="U0", - assignment="U0.via_38.B2B_SIGP", - reference="U0.via_39.B2B_SIGN", -) -circuit.set_differential_pair( - differential_mode="U1", - assignment="U1.via_32.B2B_SIGP", - reference="U1.via_33.B2B_SIGN", -) - -# Plot results. - -circuit.post.create_report( - expressions=["dB(S(U0,U0))", "dB(S(U1,U0))"], context="Differential Pairs" -) - -# ## Release AEDT -# -# Release AEDT and close the example. - -circuit.save_project() -circuit.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/high_frequency/layout/signal_integrity/pre_layout.py b/examples/high_frequency/layout/signal_integrity/pre_layout.py deleted file mode 100644 index 5c961675c..000000000 --- a/examples/high_frequency/layout/signal_integrity/pre_layout.py +++ /dev/null @@ -1,354 +0,0 @@ -# # Pre-layout signal integrity -# This example shows how to create a parameterized layout design -# and load the layout into HFSS 3D Layout for analysis and postprocessing. -# -# - Create EDB: -# -# - Add material. -# - Create stackup. -# - Create a parameterized via padstack definition. -# - Create ground planes. -# - Create a component. -# - Create signal vias and traces. -# - Create ground stitching vias. -# - Create HFSS analysis setup and frequency sweep. -# -# - Import EDB into HFSS 3D Layout: -# -# - Place SMA connector. -# - Analyze. -# - Plot return loss. - -# Here is an image of the model that is created in this example. -# -# -# -# Keywords: **HFSS 3D Layout**, **signal integrity**. - -# ## Perform imports and define constants -# Perform required packages. - -# + -import os -import tempfile -import time - -from ansys.aedt.core import Hfss3dLayout -from ansys.aedt.core.downloads import download_file -from pyedb import Edb - -# - - -# Define constants. - -AEDT_VERSION = "2024.2" -NUM_CORES = 4 -NG_MODE = False # Open AEDT UI when it is launched. - - -# ## Create temporary directory and download example files -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") -sma_rf_connector = download_file( - source="component_3d", - name="SMA_RF_SURFACE_MOUNT.a3dcomp", - destination=temp_folder.name, -) - - -# # Create layout design - -# ## Import example design - -aedb = os.path.join(temp_folder.name, "new_layout.aedb") -edbapp = Edb(edbpath=aedb, edbversion=AEDT_VERSION) - -# Set antipad always on. -edbapp.design_options.antipads_always_on = True - -# ## Add material definitions - -edbapp.materials.add_conductor_material(name="copper", conductivity=58000000) -edbapp.materials.add_dielectric_material( - name="FR4_epoxy", permittivity=4, dielectric_loss_tangent=0.02 -) -edbapp.materials.add_dielectric_material( - name="solder_mask", permittivity=3.1, dielectric_loss_tangent=0.035 -) - -# ## Create stackup - -edbapp.stackup.create_symmetric_stackup( - layer_count=4, - inner_layer_thickness="18um", - outer_layer_thickness="50um", - dielectric_thickness="100um", - dielectric_material="FR4_epoxy", - soldermask=True, - soldermask_thickness="20um", -) - -# ## Create parameterized padstack definition - -# Create signal via padstack definition. - -edbapp["$antipad"] = "0.7mm" -edbapp.padstacks.create( - padstackname="svia", holediam="0.3mm", antipaddiam="$antipad", paddiam="0.5mm" -) - -# Create component pin padstack definition. - -edbapp.padstacks.create( - padstackname="comp_pin", - paddiam="400um", - antipaddiam="600um", - start_layer="TOP", - stop_layer="TOP", - antipad_shape="Circle", - has_hole=False, -) - -# ## Review stackup - -edbapp.stackup.plot(plot_definitions="svia") - -# ## Create ground planes - -# + -board_width = "22mm" -board_length = "18mm" -board_center_point = [0, "5mm"] - -gnd_l2 = edbapp.modeler.create_rectangle( - layer_name="L2", - net_name="GND", - center_point=board_center_point, - width=board_width, - height=board_length, - representation_type="CenterWidthHeight", - corner_radius="0mm", - rotation="0deg", -) - -gnd_l3 = edbapp.modeler.create_rectangle( - layer_name="L3", - net_name="GND", - center_point=board_center_point, - width=board_width, - height=board_length, - representation_type="CenterWidthHeight", - corner_radius="0mm", - rotation="0deg", -) - -gnd_bottom = edbapp.modeler.create_rectangle( - layer_name="BOT", - net_name="GND", - center_point=board_center_point, - width=board_width, - height=board_length, - representation_type="CenterWidthHeight", - corner_radius="0mm", - rotation="0deg", -) -# - - -# ## Create a component - -edbapp.padstacks.place( - position=[0, 0], - definition_name="comp_pin", - net_name="SIG", - is_pin=True, - via_name="1", -) - -comp_pins = [ - edbapp.padstacks.place( - position=["-6mm", 0], - definition_name="comp_pin", - net_name="GND", - is_pin=True, - via_name="2", - ), - edbapp.padstacks.place( - position=["6mm", 0], - definition_name="comp_pin", - net_name="GND", - is_pin=True, - via_name="3", - ), -] - -comp_u1 = edbapp.components.create( - pins=comp_pins, - component_name="U1", - component_part_name="BGA", - placement_layer="TOP", -) -comp_u1.create_clearance_on_component(extra_soldermask_clearance=3.5e-3) - - -# ## Place vias - -# Place a signal via. - -edbapp.padstacks.place( - position=[0, 0], definition_name="svia", net_name="SIG", is_pin=False -) - -# Place ground stitching vias. - -edbapp.padstacks.place( - position=["-1mm", 0], definition_name="svia", net_name="GND", is_pin=False -) -edbapp.padstacks.place( - position=["1mm", 0], definition_name="svia", net_name="GND", is_pin=False -) -edbapp.padstacks.place( - position=[0, "-1mm"], definition_name="svia", net_name="GND", is_pin=False -) -edbapp.padstacks.place( - position=[0, "1mm"], definition_name="svia", net_name="GND", is_pin=False -) - -# ## Create signal traces - -edbapp["width"] = "0.15mm" -edbapp["gap"] = "0.1mm" - -# Create signal fanout. - -sig_trace = edbapp.modeler.create_trace( - path_list=[[0, 0]], - layer_name="BOT", - width="width", - net_name="SIG", - start_cap_style="Round", - end_cap_style="Round", - corner_style="Round", -) - -sig_trace.add_point(x="0.5mm", y="0.5mm", incremental=True) -sig_trace.add_point(x=0, y="1mm", incremental=True) -sig_trace.add_point(x="-0.5mm", y="0.5mm", incremental=True) -sig_trace.add_point(x=0, y="1mm", incremental=True) -sig_path = sig_trace.get_center_line() - -# Create coplanar waveguide with ground with ground stitching vias. - -sig2_trace = edbapp.modeler.create_trace( - path_list=[sig_path[-1]], - layer_name="BOT", - width="width", - net_name="SIG", - start_cap_style="Round", - end_cap_style="Flat", - corner_style="Round", -) -sig2_trace.add_point(x=0, y="6mm", incremental=True) -sig2_trace.create_via_fence(distance="0.5mm", gap="1mm", padstack_name="svia") -sig2_trace.add_point(x=0, y="1mm", incremental=True) - -# Create trace-to-ground clearance. - -sig2_path = sig2_trace.get_center_line() -path_list = [sig_path, sig2_path] -for i in path_list: - void = edbapp.modeler.create_trace( - path_list=i, - layer_name="BOT", - width="width+gap*2", - start_cap_style="Round", - end_cap_style="Round", - corner_style="Round", - ) - edbapp.modeler.add_void(shape=gnd_bottom, void_shape=void) - -# Generate plot to review. - -edbapp.nets.plot() - -# ## Create ports - -# Create a wave port. - -sig2_trace.create_edge_port( - name="p1_wave_port", - position="End", - port_type="Wave", - reference_layer=None, - horizontal_extent_factor=10, - vertical_extent_factor=10, - pec_launch_width="0.01mm", -) - -# ## Create HFSS analysis setup - -setup = edbapp.create_hfss_setup("Setup1") -setup.set_solution_single_frequency("5GHz", max_num_passes=1, max_delta_s="0.02") -setup.hfss_solver_settings.order_basis = "first" - -# Add a frequency sweep to the setup. -# -# When the simulation results are to -# be used for transient SPICE analysis, you should -# use the following strategy: -# -# - DC point -# - Logarithmic sweep from 1 kHz to 100 MHz -# - Linear scale for higher frequencies - -setup.add_frequency_sweep( - "Sweep1", - frequency_sweep=[ - ["log scale", "10MHz", "100MHz", 3], - ["linear scale", "0.1GHz", "5GHz", "0.2GHz"], - ], -) - -# ## Save and close EDB - -edbapp.save() -edbapp.close() - -# # Analyze in HFSS 3D Layout - -# ## Load EDB into HFSS 3D Layout. - -h3d = Hfss3dLayout(aedb, version=AEDT_VERSION, non_graphical=NG_MODE, new_desktop=True) - -# ## Place SMA RF connector - -comp = h3d.modeler.place_3d_component( - component_path=sma_rf_connector, - number_of_terminals=1, - placement_layer="TOP", - component_name="sma_rf", - pos_x=0, - pos_y=0, - create_ports=True, -) -comp.angle = "90deg" - -# ## Release AEDT - -h3d.save_project() -h3d.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_dir.name``. -# If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell -# removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/high_frequency/layout/signal_integrity/pre_layout_parametrized.py b/examples/high_frequency/layout/signal_integrity/pre_layout_parametrized.py deleted file mode 100644 index 9a0bfd77a..000000000 --- a/examples/high_frequency/layout/signal_integrity/pre_layout_parametrized.py +++ /dev/null @@ -1,422 +0,0 @@ -# # Pre-layout Parameterized PCB -# -# This example shows how to use the EDB interface along with HFSS 3D Layout to create and solve a -# parameterized layout. The layout shows a differential via transition on a printed circuit board -# with back-to-back microstrip to stripline transitions. -# The model is fully parameterized to enable investigation of the transition performance on the -# many degrees of freedom. -# -# The resulting model is shown below -# -# - -# ## Preparation -# Import the required packages - -# + -import os -import tempfile -import time - -from ansys.aedt.core import Hfss3dLayout -from pyedb import Edb - -# - - -# ## Define constants - -AEDT_VERSION = "2024.2" -NUM_CORES = 4 -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Launch EDB - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") -aedb_path = os.path.join(temp_folder.name, "pcb.aedb") -edb = Edb(edbpath=aedb_path, edbversion=AEDT_VERSION) - -# ## Create layout -# ### Define the parameters. - -# + -params = { - "$ms_width": "0.4mm", - "$sl_width": "0.2mm", - "$ms_spacing": "0.2mm", - "$sl_spacing": "0.1mm", - "$via_spacing": "0.5mm", - "$via_diam": "0.3mm", - "$pad_diam": "0.6mm", - "$anti_pad_diam": "0.7mm", - "$pcb_len": "15mm", - "$pcb_w": "5mm", - "$x_size": "1.2mm", - "$y_size": "1mm", - "$corner_rad": "0.5mm", -} - -for par_name in params: - edb.add_project_variable(par_name, params[par_name]) -# - - -# ### Create stackup -# Define the stackup layers from bottom to top. - -layers = [ - { - "name": "bottom", - "layer_type": "signal", - "thickness": "35um", - "material": "copper", - }, - { - "name": "diel_3", - "layer_type": "dielectric", - "thickness": "275um", - "material": "FR4_epoxy", - }, - { - "name": "sig_2", - "layer_type": "signal", - "thickness": "35um", - "material": "copper", - }, - { - "name": "diel_2", - "layer_type": "dielectric", - "thickness": "275um", - "material": "FR4_epoxy", - }, - { - "name": "sig_1", - "layer_type": "signal", - "thickness": "35um", - "material": "copper", - }, - { - "name": "diel_1", - "layer_type": "dielectric", - "thickness": "275um", - "material": "FR4_epoxy", - }, - {"name": "top", "layer_type": "signal", "thickness": "35um", "material": "copper"}, -] - -# Define the bottom layer - -prev = None -for layer in layers: - edb.stackup.add_layer( - layer["name"], - base_layer=prev, - layer_type=layer["layer_type"], - thickness=layer["thickness"], - material=layer["material"], - ) - prev = layer["name"] - -# ### Create a parametrized padstack for the signal via. -# Create a padstack definition. - -signal_via_padstack = "automated_via" -edb.padstacks.create( - padstackname=signal_via_padstack, - holediam="$via_diam", - paddiam="$pad_diam", - antipaddiam="", - antipad_shape="Bullet", - x_size="$x_size", - y_size="$y_size", - corner_radius="$corner_rad", - start_layer=layers[-1]["name"], - stop_layer=layers[-3]["name"], -) - -# Assign net names. There are only two signal nets. - -net_p = "p" -net_n = "n" - -# Place the signal vias. - -edb.padstacks.place( - position=["$pcb_len/3", "($ms_width+$ms_spacing+$via_spacing)/2"], - definition_name=signal_via_padstack, - net_name=net_p, - via_name="", - rotation=90.0, -) - -edb.padstacks.place( - position=["2*$pcb_len/3", "($ms_width+$ms_spacing+$via_spacing)/2"], - definition_name=signal_via_padstack, - net_name=net_p, - via_name="", - rotation=90.0, -) - -edb.padstacks.place( - position=["$pcb_len/3", "-($ms_width+$ms_spacing+$via_spacing)/2"], - definition_name=signal_via_padstack, - net_name=net_n, - via_name="", - rotation=-90.0, -) - -edb.padstacks.place( - position=["2*$pcb_len/3", "-($ms_width+$ms_spacing+$via_spacing)/2"], - definition_name=signal_via_padstack, - net_name=net_n, - via_name="", - rotation=-90.0, -) - - -# ### Draw parametrized traces -# -# Trace width and the routing (Microstrip-Stripline-Microstrip). -# Applies to both p and n nets. - -# Trace width, n and p -width = ["$ms_width", "$sl_width", "$ms_width"] -# Routing layer, n and p -route_layer = [layers[-1]["name"], layers[4]["name"], layers[-1]["name"]] - -# Define points for three traces in the "p" net - -points_p = [ - [ - ["0.0", "($ms_width+$ms_spacing)/2"], - ["$pcb_len/3-2*$via_spacing", "($ms_width+$ms_spacing)/2"], - ["$pcb_len/3-$via_spacing", "($ms_width+$ms_spacing+$via_spacing)/2"], - ["$pcb_len/3", "($ms_width+$ms_spacing+$via_spacing)/2"], - ], - [ - ["$pcb_len/3", "($ms_width+$sl_spacing+$via_spacing)/2"], - ["$pcb_len/3+$via_spacing", "($ms_width+$sl_spacing+$via_spacing)/2"], - ["$pcb_len/3+2*$via_spacing", "($sl_width+$sl_spacing)/2"], - ["2*$pcb_len/3-2*$via_spacing", "($sl_width+$sl_spacing)/2"], - ["2*$pcb_len/3-$via_spacing", "($ms_width+$sl_spacing+$via_spacing)/2"], - ["2*$pcb_len/3", "($ms_width+$sl_spacing+$via_spacing)/2"], - ], - [ - ["2*$pcb_len/3", "($ms_width+$ms_spacing+$via_spacing)/2"], - ["2*$pcb_len/3+$via_spacing", "($ms_width+$ms_spacing+$via_spacing)/2"], - ["2*$pcb_len/3+2*$via_spacing", "($ms_width+$ms_spacing)/2"], - ["$pcb_len", "($ms_width+$ms_spacing)/2"], - ], -] - -# Define points for three traces in the "n" net - -points_n = [ - [ - ["0.0", "-($ms_width+$ms_spacing)/2"], - ["$pcb_len/3-2*$via_spacing", "-($ms_width+$ms_spacing)/2"], - ["$pcb_len/3-$via_spacing", "-($ms_width+$ms_spacing+$via_spacing)/2"], - ["$pcb_len/3", "-($ms_width+$ms_spacing+$via_spacing)/2"], - ], - [ - ["$pcb_len/3", "-($ms_width+$sl_spacing+$via_spacing)/2"], - ["$pcb_len/3+$via_spacing", "-($ms_width+$sl_spacing+$via_spacing)/2"], - ["$pcb_len/3+2*$via_spacing", "-($ms_width+$sl_spacing)/2"], - ["2*$pcb_len/3-2*$via_spacing", "-($ms_width+$sl_spacing)/2"], - ["2*$pcb_len/3-$via_spacing", "-($ms_width+$sl_spacing+$via_spacing)/2"], - ["2*$pcb_len/3", "-($ms_width+$sl_spacing+$via_spacing)/2"], - ], - [ - ["2*$pcb_len/3", "-($ms_width+$ms_spacing+$via_spacing)/2"], - ["2*$pcb_len/3 + $via_spacing", "-($ms_width+$ms_spacing+$via_spacing)/2"], - ["2*$pcb_len/3 + 2*$via_spacing", "-($ms_width+$ms_spacing)/2"], - ["$pcb_len", "-($ms_width + $ms_spacing)/2"], - ], -] - -# Add traces to the EDB. - -trace_p = [] -trace_n = [] -for n in range(len(points_p)): - trace_p.append( - edb.modeler.create_trace( - points_p[n], route_layer[n], width[n], net_p, "Flat", "Flat" - ) - ) - trace_n.append( - edb.modeler.create_trace( - points_n[n], route_layer[n], width[n], net_n, "Flat", "Flat" - ) - ) - -# Create the wave ports - -edb.hfss.create_differential_wave_port( - trace_p[0].id, - ["0.0", "($ms_width+$ms_spacing)/2"], - trace_n[0].id, - ["0.0", "-($ms_width+$ms_spacing)/2"], - "wave_port_1", -) -edb.hfss.create_differential_wave_port( - trace_p[2].id, - ["$pcb_len", "($ms_width+$ms_spacing)/2"], - trace_n[2].id, - ["$pcb_len", "-($ms_width + $ms_spacing)/2"], - "wave_port_2", -) - -# Draw a conducting rectangle on the the ground layers. - -gnd_poly = [ - [0.0, "-$pcb_w/2"], - ["$pcb_len", "-$pcb_w/2"], - ["$pcb_len", "$pcb_w/2"], - [0.0, "$pcb_w/2"], -] -gnd_shape = edb.modeler.Shape("polygon", points=gnd_poly) - -# Void in ground for traces on the signal routing layer - -# + -void_poly = [ - [ - "$pcb_len/3", - "-($ms_width+$ms_spacing+$via_spacing+$anti_pad_diam)/2-$via_spacing/2", - ], - [ - "$pcb_len/3 + $via_spacing", - "-($ms_width+$ms_spacing+$via_spacing+$anti_pad_diam)/2-$via_spacing/2", - ], - [ - "$pcb_len/3 + 2*$via_spacing", - "-($ms_width+$ms_spacing+$via_spacing+$anti_pad_diam)/2", - ], - [ - "2*$pcb_len/3 - 2*$via_spacing", - "-($ms_width+$ms_spacing+$via_spacing+$anti_pad_diam)/2", - ], - [ - "2*$pcb_len/3 - $via_spacing", - "-($ms_width+$ms_spacing+$via_spacing+$anti_pad_diam)/2-$via_spacing/2", - ], - [ - "2*$pcb_len/3", - "-($ms_width+$ms_spacing+$via_spacing+$anti_pad_diam)/2-$via_spacing/2", - ], - [ - "2*$pcb_len/3", - "($ms_width+$ms_spacing+$via_spacing+$anti_pad_diam)/2+$via_spacing/2", - ], - [ - "2*$pcb_len/3 - $via_spacing", - "($ms_width+$ms_spacing+$via_spacing+$anti_pad_diam)/2+$via_spacing/2", - ], - [ - "2*$pcb_len/3 - 2*$via_spacing", - "($ms_width+$ms_spacing+$via_spacing+$anti_pad_diam)/2", - ], - [ - "$pcb_len/3 + 2*$via_spacing", - "($ms_width+$ms_spacing+$via_spacing+$anti_pad_diam)/2", - ], - [ - "$pcb_len/3 + $via_spacing", - "($ms_width+$ms_spacing+$via_spacing+$anti_pad_diam)/2+$via_spacing/2", - ], - [ - "$pcb_len/3", - "($ms_width+$ms_spacing+$via_spacing+$anti_pad_diam)/2+$via_spacing/2", - ], - ["$pcb_len/3", "($ms_width+$ms_spacing+$via_spacing+$anti_pad_diam)/2"], -] - -void_shape = edb.modeler.Shape("polygon", points=void_poly) -# - - -# Add ground conductors. - -for layer in layers[:-1:2]: - - # add void if the layer is the signal routing layer. - void = [void_shape] if layer["name"] == route_layer[1] else [] - - edb.modeler.create_polygon( - main_shape=gnd_shape, layer_name=layer["name"], voids=void, net_name="gnd" - ) - -# Plot the layout. - -edb.nets.plot(None) - -# Save the EDB. - -edb.save_edb() -edb.close_edb() - -# ## Open the project in HFSS 3D Layout. - -h3d = Hfss3dLayout( - project=aedb_path, - version=AEDT_VERSION, - non_graphical=NG_MODE, - new_desktop=True, -) - -# ### Add a HFSS simulation setup - -# + -setup = h3d.create_setup() -setup.props["AdaptiveSettings"]["SingleFrequencyDataList"]["AdaptiveFrequencyData"][ - "MaxPasses" -] = 3 - -h3d.create_linear_count_sweep( - setup=setup.name, - unit="GHz", - start_frequency=0, - stop_frequency=10, - num_of_freq_points=1001, - name="sweep1", - sweep_type="Interpolating", - interpolation_tol_percent=1, - interpolation_max_solutions=255, - save_fields=False, - use_q3d_for_dc=False, -) -# - - -# ### Define the differential pairs to used to calculate differential and common mode s-parameters - -h3d.set_differential_pair( - differential_mode="In", assignment="wave_port_1:T1", reference="wave_port_1:T2" -) -h3d.set_differential_pair( - differential_mode="Out", assignment="wave_port_2:T1", reference="wave_port_2:T2" -) - -# Solve the project. - -h3d.analyze(cores=NUM_CORES) - -# Plot the results and shut down AEDT. - -solutions = h3d.post.get_solution_data( - expressions=["dB(S(In,In))", "dB(S(In,Out))"], context="Differential Pairs" -) -solutions.plot() - -# ## Release AEDT - -h3d.save_project() -h3d.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# Note that the ground nets are only connected to each other due -# to the wave ports. The problem with poor grounding can be seen in the -# S-parameters. This example can be downloaded as a Jupyter Notebook, so -# you can modify it. Try changing parameters or adding ground vias to improve performance. -# -# The final cell cleans up the temporary directory, removing all files. - -temp_folder.cleanup() diff --git a/examples/high_frequency/multiphysics/_static/hfss_mechanical.png b/examples/high_frequency/multiphysics/_static/hfss_mechanical.png deleted file mode 100644 index d5ff1707d..000000000 Binary files a/examples/high_frequency/multiphysics/_static/hfss_mechanical.png and /dev/null differ diff --git a/examples/high_frequency/multiphysics/_static/mri.png b/examples/high_frequency/multiphysics/_static/mri.png deleted file mode 100644 index c5cfd4880..000000000 Binary files a/examples/high_frequency/multiphysics/_static/mri.png and /dev/null differ diff --git a/examples/high_frequency/multiphysics/hfss_mechanical.py b/examples/high_frequency/multiphysics/hfss_mechanical.py deleted file mode 100644 index 5789f698e..000000000 --- a/examples/high_frequency/multiphysics/hfss_mechanical.py +++ /dev/null @@ -1,166 +0,0 @@ -# # HFSS-Mechanical multiphysics analysis -# -# This example shows how to use PyAEDT to create a multiphysics workflow that -# includes Circuit, HFSS, and Mechanical. -# -# Keywords: **Multiphysics**, **HFSS**, **Mechanical AEDT**, **Circuit**. - -# ## Perform imports and define constants -# -# Perform required imports. - -# + -import tempfile -import time - -import ansys.aedt.core - -# - - -# Define constants. - -AEDT_VERSION = "2024.2" -NUM_CORES = 4 -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Download and open project -# -# Download and open the project. Save it to the temporary folder. - -project_name = ansys.aedt.core.downloads.download_via_wizard( - destination=temp_folder.name -) - -# ## Start HFSS -# -# Initialize HFSS. - -hfss = ansys.aedt.core.Hfss( - project=project_name, - version=AEDT_VERSION, - non_graphical=NG_MODE, - new_desktop=True, -) -hfss.change_material_override(True) - -# ## Initialize Circuit -# -# Initialize Circuit and add the HFSS dynamic link component. - -circuit = ansys.aedt.core.Circuit(version=AEDT_VERSION) -hfss_comp = circuit.modeler.schematic.add_subcircuit_dynamic_link(pyaedt_app=hfss) - -# ## Set up dynamic link options -# -# Set up dynamic link options. The argument for the ``set_sim_option_on_hfss_subcircuit()`` -# method can be the component name, component ID, or component object. - -circuit.modeler.schematic.refresh_dynamic_link(name=hfss_comp.composed_name) -circuit.modeler.schematic.set_sim_option_on_hfss_subcircuit(component=hfss_comp) -hfss_setup_name = hfss.setups[0].name + " : " + hfss.setups[0].sweeps[0].name -circuit.modeler.schematic.set_sim_solution_on_hfss_subcircuit( - component=hfss_comp.composed_name, solution_name=hfss_setup_name -) - -# ## Create ports and excitations -# -# Create ports and excitations. Find component pin locations and create interface -# ports on them. Define the voltage source on the input port. - -# + -circuit.modeler.schematic.create_interface_port( - name="Excitation_1", - location=[hfss_comp.pins[0].location[0], hfss_comp.pins[0].location[1]], -) -circuit.modeler.schematic.create_interface_port( - name="Excitation_2", - location=[hfss_comp.pins[1].location[0], hfss_comp.pins[1].location[1]], -) -circuit.modeler.schematic.create_interface_port( - name="Port_1", - location=[hfss_comp.pins[2].location[0], hfss_comp.pins[2].location[1]], -) -circuit.modeler.schematic.create_interface_port( - name="Port_2", - location=[hfss_comp.pins[3].location[0], hfss_comp.pins[3].location[1]], -) - -ports_list = ["Excitation_1", "Excitation_2"] -source = circuit.assign_voltage_sinusoidal_excitation_to_ports(ports_list) -source.ac_magnitude = 1 -source.phase = 0 -# - - -# ## Create setup - -setup_name = "MySetup" -LNA_setup = circuit.create_setup(name=setup_name) -sweep_list = ["LINC", str(4.3) + "GHz", str(4.4) + "GHz", str(1001)] -LNA_setup.props["SweepDefinition"]["Data"] = " ".join(sweep_list) - -# ## Solve and push excitations -# -# Solve the circuit and push excitations to the HFSS model to calculate the -# correct value of losses. - -circuit.analyze(cores=NUM_CORES) -circuit.push_excitations(instance="S1", setup=setup_name) - -# ## Start Mechanical -# -# Start Mechanical and copy bodies from the HFSS project. - -mech = ansys.aedt.core.Mechanical(version=AEDT_VERSION) -mech.copy_solid_bodies_from(design=hfss) -mech.change_material_override(True) - -# ## Get losses from HFSS and assign convection to Mechanical - -mech.assign_em_losses( - design=hfss.design_name, - setup=hfss.setups[0].name, - sweep="LastAdaptive", - map_frequency=hfss.setups[0].props["Frequency"], - surface_objects=hfss.get_all_conductors_names(), -) -diels = ["1_pd", "2_pd", "3_pd", "4_pd", "5_pd"] -for el in diels: - mech.assign_uniform_convection( - assignment=[mech.modeler[el].top_face_y, mech.modeler[el].bottom_face_y], - convection_value=3, - ) - -# ## Solve and plot thermal results - -mech.create_setup() -mech.save_project() -mech.analyze(cores=NUM_CORES) -surfaces = [] -for name in mech.get_all_conductors_names(): - surfaces.extend(mech.modeler.get_object_faces(name)) -mech.post.create_fieldplot_surface(assignment=surfaces, quantity="Temperature") - -# ## Release AEDT -# -# Release AEDT and close the example. - -mech.save_project() -mech.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/high_frequency/multiphysics/index.rst b/examples/high_frequency/multiphysics/index.rst deleted file mode 100644 index e010c0070..000000000 --- a/examples/high_frequency/multiphysics/index.rst +++ /dev/null @@ -1,102 +0,0 @@ -Multiphysics -~~~~~~~~~~~~ - -These examples use PyAEDT to show some multiphysics applications. - - -.. grid:: 2 - - .. grid-item-card:: HFSS-Mechanical MRI analysis - :padding: 2 2 2 2 - :link: mri - :link-type: doc - - .. image:: _static/mri.png - :alt: MRI - :width: 250px - :height: 200px - :align: center - - This example uses a coil tuned to 63.8 MHz to determine the temperature rise in a gel phantom near - an implant given a background SAR of 1 W/kg. - - .. grid-item-card:: HFSS-Mechanical multiphysics analysis - :padding: 2 2 2 2 - :link: hfss_mechanical - :link-type: doc - - .. image:: _static/hfss_mechanical.png - :alt: HFSS Mechanical - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create a multiphysics workflow that includes Circuit, HFSS, and Mechanical. - - - .. grid-item-card:: Import of a PCB and its components via IDF and EDB - :padding: 2 2 2 2 - :link: ../../electrothermal/ecad_import - :link-type: doc - - .. image:: ../../electrothermal/_static/ecad.png - :alt: Icepak ECAD - :width: 250px - :height: 200px - :align: center - - This example shows how to import a PCB and its components using IDF files (LDB and BDF). - You can also use a combination of EMN and EMP files in a similar way. - - .. grid-item-card:: Coaxial - :padding: 2 2 2 2 - :link: ../../electrothermal/coaxial_hfss_icepak - :link-type: doc - - .. image:: ../../electrothermal/_static/coaxial.png - :alt: Coaxial - :width: 250px - :height: 200px - :align: center - - This example shows how to create a project from scratch in HFSS and Icepak. - - .. grid-item-card:: Electrothermal analysis - :padding: 2 2 2 2 - :link: ../../electrothermal/electrothermal - :link-type: doc - - .. image:: ../../electrothermal/_static/electrothermal.png - :alt: Electrothermal - :width: 250px - :height: 200px - :align: center - - This example shows how to use the EDB for DC IR analysis and electrothermal analysis. - The EDB is loaded into SIwave for analysis and postprocessing. - In the end, an Icepak project is exported from SIwave. - - .. grid-item-card:: Circuit-HFSS-Icepak coupling workflow - :padding: 2 2 2 2 - :link: ../../electrothermal/icepak_circuit_hfss_coupling - :link-type: doc - - .. image:: ../../electrothermal/_static/ring.png - :alt: Ring - :width: 250px - :height: 200px - :align: center - - This example shows how to create a two-way coupling between HFSS and Icepak. - - - .. toctree:: - :hidden: - - mri - hfss_mechanical - ../../electrothermal/ecad_import - ../../electrothermal/coaxial_hfss_icepak - ../../electrothermal/electrothermal - ../../electrothermal/icepak_circuit_hfss_coupling - diff --git a/examples/high_frequency/multiphysics/mri.py b/examples/high_frequency/multiphysics/mri.py deleted file mode 100644 index 4561bbce3..000000000 --- a/examples/high_frequency/multiphysics/mri.py +++ /dev/null @@ -1,353 +0,0 @@ -# # HFSS-Mechanical MRI analysis -# -# This example uses a coil tuned to 63.8 MHz to determine the temperature -# rise in a gel phantom near an implant given a background SAR of 1 W/kg. -# -# Here is the workflow: - -# Step 1: Simulate the coil loaded by the empty phantom: -# Scale input to coil ports to produce desired background SAR of 1 W/kg at the location -# that is to contain the implant. - -# Step 2: Simulate the coil loaded by the phantom containing the implant in the proper location: -# View SAR in the tissue surrounding implant. - -# Step 3: Thermal simulation: -# Link HFSS to the transient thermal solver to find the temperature rise in the tissue near the implant -# versus the time. -# -# Keywords: **multiphysics**, **HFSS**, **Mechanical AEDT**, **Circuit**. - -# ## Perform imports and define constants -# Perform required imports. - -# + -import os.path -import tempfile -import time - -from ansys.aedt.core import Hfss, Icepak, Mechanical, downloads - -# - - -# Define constants. - -AEDT_VERSION = "2024.2" -NUM_CORES = 4 -NG_MODE = False # Open AEDT UI when it is launched. - - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - - -# ## Load project -# -# Open AEDT and the ``background_SAR.aedt`` project. This project -# contains the phantom and airbox. The phantom consists of two objects: ``phantom`` and ``implant_box``. -# -# Separate objects are used to selectively assign mesh operations. -# Material properties defined in this project already contain electrical and thermal properties. - -project_path = downloads.download_file(source="mri", destination=temp_folder.name) -project_name = os.path.join(project_path, "background_SAR.aedt") -hfss = Hfss( - project=project_name, - version=AEDT_VERSION, - non_graphical=NG_MODE, - new_desktop=True, -) - -# ## Insert 3D component -# -# The MRI coil is saved as a separate 3D component. - -# ‒ 3D components store geometry (including parameters), -# material properties, boundary conditions, mesh assignments, -# and excitations. -# ‒ 3D components make it easy to reuse and share parts of a simulation. - -component_file = os.path.join(project_path, "coil.a3dcomp") -hfss.modeler.insert_3d_component(input_file=component_file) - -# ## Define convergence criteria -# -# On the **Expression Cache** tab, define additional convergence criteria for self -# impedance of the four coil ports. - -# Set each of these convergence criteria to 2.5 ohm. -# This example limits the number of passes to two to reduce simulation time. - -# + -im_traces = hfss.get_traces_for_plot( - get_mutual_terms=False, category="im(Z", first_element_filter="Coil1_p*" -) - -hfss.setups[0].enable_expression_cache( - report_type="Modal Solution Data", - expressions=im_traces, - isconvergence=True, - isrelativeconvergence=False, - conv_criteria=2.5, - use_cache_for_freq=False, -) -hfss.setups[0].props["MaximumPasses"] = 1 -# - - -# ## Edit sources -# -# The 3D component of the MRI coil contains all the ports, -# but the sources for these ports are not yet defined. -# Browse to and select the ``sources.csv`` file. -# The sources in this file were determined by tuning the coil at 63.8 MHz. -# Notice that ``input_scale`` is a multiplier that lets you quickly adjust the coil excitation power. - -hfss.edit_sources_from_file(os.path.join(project_path, "sources.csv")) - -# ## Run simulation -# -# Save and analyze the project. - -hfss.save_project(file_name=os.path.join(project_path, "solved.aedt")) -hfss.analyze(cores=NUM_CORES) - -# ## Plot SAR on cut plane in phantom -# -# Ensure that the SAR averaging method is set to ``Gridless``. -# Plot ``Average_SAR`` on the global YZ plane. -# Draw ``Point1`` at the origin of the implant coordinate system. - -# + -hfss.sar_setup( - assignment=-1, - average_sar_method=1, - tissue_mass=1, - material_density=1, -) -hfss.post.create_fieldplot_cutplane( - assignment=["implant:YZ"], quantity="Average_SAR", filter_objects=["implant_box"] -) - -hfss.modeler.set_working_coordinate_system("implant") -hfss.modeler.create_point(position=[0, 0, 0], name="Point1") - -plot = hfss.post.plot_field( - quantity="Average_SAR", - assignment="implant:YZ", - plot_type="CutPlane", - show_legend=False, - filter_objects=["implant_box"], - export_path=hfss.working_directory, - show=False, -) -# - - -# ## Adjust input Power to MRI coil -# -# Adjust the MRI coil’s input power so that the average SAR at ``Point1`` is 1 W/kg. -# Note that the SAR and input power are linearly related. -# -# To determine therequired input, calculate -# ``input_scale = 1/AverageSAR`` at ``Point1``. - -# + -sol_data = hfss.post.get_solution_data( - expressions="Average_SAR", - primary_sweep_variable="Freq", - context="Point1", - report_category="Fields", -) -sol_data.data_real() - -hfss["input_scale"] = 1 / sol_data.data_real()[0] -# - - -# ## Analyze phantom with implant -# -# Import the implant geometry. -# Subtract the rod from the implant box. -# Assign titanium to the imported object rod. -# Analyze the project. - -# + -hfss.modeler.import_3d_cad(os.path.join(project_path, "implant_rod.sat")) - -hfss.modeler["implant_box"].subtract(tool_list="rod", keep_originals=True) -hfss.modeler["rod"].material_name = "titanium" -hfss.analyze(cores=NUM_CORES) -hfss.save_project() -# - - -# ## Run a thermal simulation -# -# Initialize a new Mechanical transient thermal analysis. -# This type of analysis is available in AEDT in 2023 R2 and later as a beta feature. - -mech = Mechanical(solution_type="Transient Thermal", version=AEDT_VERSION) - -# ## Copy geometries -# -# Copy bodies from the HFSS project. The 3D component is not copied. - -mech.copy_solid_bodies_from(hfss) - -# ## Link sources to EM losses -# -# Link sources to the EM losses. -# Assign external convection. - -exc = mech.assign_em_losses( - design=hfss.design_name, - setup=hfss.setups[0].name, - sweep="LastAdaptive", - map_frequency=hfss.setups[0].props["Frequency"], - surface_objects=mech.get_all_conductors_names(), -) -mech.assign_uniform_convection( - assignment=mech.modeler["Region"].faces, convection_value=1 -) - -# ## Create setup -# -# Create a setup and edit properties. - -# + -setup = mech.create_setup() -# setup.add_mesh_link("backgroundSAR") -# mech.create_dataset1d_design("PowerMap", [0, 239, 240, 360], [1, 1, 0, 0]) -# exc.props["LossMultiplier"] = "pwl(PowerMap,Time)" - -mech.modeler.set_working_coordinate_system("implant") -mech.modeler.create_point(position=[0, 0, 0], name="Point1") -setup.props["Stop Time"] = 30 -setup.props["Time Step"] = "10s" -setup.props["SaveFieldsType"] = "Every N Steps" -setup.props["N Steps"] = "2" -# - - -# ## Analyze project -# -# Analyze the Mechanical project. - -mech.analyze(cores=NUM_CORES) - -# ## Plot fields -# -# Plot the temperature on cut plane. -# Plot the temperature on the point. - -# + -mech.post.create_fieldplot_cutplane( - assignment=["implant:YZ"], - quantity="Temperature", - filter_objects=["implant_box"], - intrinsics={"Time": "10s"}, -) -mech.save_project() - -data = mech.post.get_solution_data( - expressions="Temperature", - primary_sweep_variable="Time", - context="Point1", - report_category="Fields", -) -data.plot() - -mech.post.plot_animated_field( - quantity="Temperature", - assignment="implant:YZ", - plot_type="CutPlane", - intrinsics={"Time": "10s"}, - variation_variable="Time", - variations=["10s", "30s"], - filter_objects=["implant_box"], - show=False, -) -# - - -# ## Run a new thermal simulation -# -# Initialize a new Icepak transient thermal analysis. - -ipk = Icepak(solution_type="Transient", version=AEDT_VERSION) -ipk.design_solutions.problem_type = "TemperatureOnly" - -# ## Copy geometries -# -# Copy bodies from the HFSS project. The 3D component is not copied. - -ipk.modeler.delete("Region") -ipk.copy_solid_bodies_from(hfss) - -# ## Link sources to EM losses -# -# Link sources to the EM losses. -# Assign external convection. - -ipk.assign_em_losses( - design=hfss.design_name, - setup=hfss.setups[0].name, - sweep="LastAdaptive", - map_frequency=hfss.setups[0].props["Frequency"], - surface_objects=ipk.get_all_conductors_names(), -) - -# ## Create setup -# -# Create a setup and edit properties. -# Simulation takes 30 seconds. - -# + -setup = ipk.create_setup() - -setup.props["Stop Time"] = 30 -setup.props["N Steps"] = 2 -setup.props["Time Step"] = 5 -setup.props["Convergence Criteria - Energy"] = 1e-12 -# - - -# ## Create mesh region -# -# Create a mesh region and change the accuracy level to 4. - -bound = ipk.modeler["implant_box"].bounding_box -mesh_box = ipk.modeler.create_box( - origin=bound[:3], - sizes=[bound[3] - bound[0], bound[4] - bound[1], bound[5] - bound[2]], -) -mesh_box.model = False -mesh_region = ipk.mesh.assign_mesh_region([mesh_box.name]) -mesh_region.UserSpecifiedSettings = False -mesh_region.Level = 4 -mesh_region.update() - -# ## Create point monitor -# -# Create a point monitor. - -ipk.modeler.set_working_coordinate_system("implant") -ipk.monitor.assign_point_monitor(point_position=[0, 0, 0], monitor_name="Point1") -ipk.assign_openings(ipk.modeler["Region"].top_face_z) -# - - -# ## Release AEDT -# -# Release AEDT and close the example. - -hfss.save_project() -hfss.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/high_frequency/radiofrequency_mmwave/_static/cpwg.png b/examples/high_frequency/radiofrequency_mmwave/_static/cpwg.png deleted file mode 100644 index 6c6f4e7c5..000000000 Binary files a/examples/high_frequency/radiofrequency_mmwave/_static/cpwg.png and /dev/null differ diff --git a/examples/high_frequency/radiofrequency_mmwave/_static/lumped_filter.png b/examples/high_frequency/radiofrequency_mmwave/_static/lumped_filter.png deleted file mode 100644 index b97f4f0ae..000000000 Binary files a/examples/high_frequency/radiofrequency_mmwave/_static/lumped_filter.png and /dev/null differ diff --git a/examples/high_frequency/radiofrequency_mmwave/_static/spiral.png b/examples/high_frequency/radiofrequency_mmwave/_static/spiral.png deleted file mode 100644 index 36e2ff2c7..000000000 Binary files a/examples/high_frequency/radiofrequency_mmwave/_static/spiral.png and /dev/null differ diff --git a/examples/high_frequency/radiofrequency_mmwave/_static/stripline.png b/examples/high_frequency/radiofrequency_mmwave/_static/stripline.png deleted file mode 100644 index ab70d8ad9..000000000 Binary files a/examples/high_frequency/radiofrequency_mmwave/_static/stripline.png and /dev/null differ diff --git a/examples/high_frequency/radiofrequency_mmwave/_static/wgf.png b/examples/high_frequency/radiofrequency_mmwave/_static/wgf.png deleted file mode 100644 index 0f3d78bf9..000000000 Binary files a/examples/high_frequency/radiofrequency_mmwave/_static/wgf.png and /dev/null differ diff --git a/examples/high_frequency/radiofrequency_mmwave/coplanar_waveguide.py b/examples/high_frequency/radiofrequency_mmwave/coplanar_waveguide.py deleted file mode 100644 index 0e88d3f08..000000000 --- a/examples/high_frequency/radiofrequency_mmwave/coplanar_waveguide.py +++ /dev/null @@ -1,248 +0,0 @@ -# # CPWG analysis - -# This example shows how to use PyAEDT to create a CPWG (coplanar waveguide with ground) design -# in 2D Extractor and run a simulation. -# -# Keywords: **Q2D**, **CPWG**. - -# ## Perform imports and define constants -# -# Perform required imports. - -import os -import tempfile -import time - -import ansys.aedt.core - -# Define constants. - -AEDT_VERSION = "2024.2" -NUM_CORES = 4 -NG_MODE = False # Run the example without opening the UI. - - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Launch AEDT and 2D Extractor -# -# Launch AEDT 2024.2 in graphical mode and launch 2D Extractor. This example -# uses SI units. - -q2d = ansys.aedt.core.Q2d( - version=AEDT_VERSION, - non_graphical=NG_MODE, - new_desktop=True, - project=os.path.join(temp_folder.name, "cpwg"), - design="coplanar_waveguide", -) - -# ## Create model -# -# Define variables. - -# + -e_factor = "e_factor" -sig_bot_w = "sig_bot_w" -co_gnd_w = "gnd_w" -clearance = "clearance" -cond_h = "cond_h" -d_h = "d_h" -sm_h = "sm_h" - -for var_name, var_value in { - "sig_bot_w": "150um", - "e_factor": "2", - "gnd_w": "500um", - "clearance": "150um", - "cond_h": "50um", - "d_h": "150um", - "sm_h": "20um", -}.items(): - q2d[var_name] = var_value - -delta_w_half = "({0}/{1})".format(cond_h, e_factor) -sig_top_w = "({1}-{0}*2)".format(delta_w_half, sig_bot_w) -co_gnd_top_w = "({1}-{0}*2)".format(delta_w_half, co_gnd_w) -model_w = "{}*2+{}*2+{}".format(co_gnd_w, clearance, sig_bot_w) -# - - -# Create primitives and define the layer heights. - -layer_1_lh = 0 -layer_1_uh = cond_h -layer_2_lh = layer_1_uh + "+" + d_h -layer_2_uh = layer_2_lh + "+" + cond_h - -# Create a signal conductor. - -base_line_obj = q2d.modeler.create_polyline( - points=[[0, layer_2_lh, 0], [sig_bot_w, layer_2_lh, 0]], name="signal" -) -top_line_obj = q2d.modeler.create_polyline( - points=[[0, layer_2_uh, 0], [sig_top_w, layer_2_uh, 0]] -) -q2d.modeler.move(assignment=[top_line_obj], vector=[delta_w_half, 0, 0]) -q2d.modeler.connect([base_line_obj, top_line_obj]) -q2d.modeler.move( - assignment=[base_line_obj], vector=["{}+{}".format(co_gnd_w, clearance), 0, 0] -) - -# Create a coplanar ground. - -# + -base_line_obj = q2d.modeler.create_polyline( - points=[[0, layer_2_lh, 0], [co_gnd_w, layer_2_lh, 0]], name="co_gnd_left" -) -top_line_obj = q2d.modeler.create_polyline( - points=[[0, layer_2_uh, 0], [co_gnd_top_w, layer_2_uh, 0]] -) -q2d.modeler.move(objid=[top_line_obj], vector=[delta_w_half, 0, 0]) -q2d.modeler.connect([base_line_obj, top_line_obj]) - -base_line_obj = q2d.modeler.create_polyline( - points=[[0, layer_2_lh, 0], [co_gnd_w, layer_2_lh, 0]], name="co_gnd_right" -) -top_line_obj = q2d.modeler.create_polyline( - points=[[0, layer_2_uh, 0], [co_gnd_top_w, layer_2_uh, 0]] -) -q2d.modeler.move(objid=[top_line_obj], vector=[delta_w_half, 0, 0]) -q2d.modeler.connect([base_line_obj, top_line_obj]) -q2d.modeler.move( - assignment=[base_line_obj], - vector=["{}+{}*2+{}".format(co_gnd_w, clearance, sig_bot_w), 0, 0], -) -# - - -# Create a reference ground plane. - -q2d.modeler.create_rectangle( - origin=[0, layer_1_lh, 0], sizes=[model_w, cond_h], name="ref_gnd" -) - -# Define the substrate. - -q2d.modeler.create_rectangle( - position=[0, layer_1_uh, 0], - dimension_list=[model_w, d_h], - name="Dielectric", - matname="FR4_epoxy", -) - -# Assign a conformal coating. - -# + -sm_obj_list = [] -ids = [1, 2, 3] -if AEDT_VERSION >= "2023.1": - ids = [0, 1, 2] - -for obj_name in ["signal", "co_gnd_left", "co_gnd_right"]: - obj = q2d.modeler.get_object_from_name(obj_name) - e_obj_list = [] - for i in ids: - e_obj = q2d.modeler.create_object_from_edge(obj.edges[i]) - e_obj_list.append(e_obj) - e_obj_1 = e_obj_list[0] - q2d.modeler.unite(e_obj_list) - new_obj = q2d.modeler.sweep_along_vector( - assignment=e_obj_1.id, sweep_vector=[0, sm_h, 0] - ) - sm_obj_list.append(e_obj_1) - -new_obj = q2d.modeler.create_rectangle( - origin=[co_gnd_w, layer_2_lh, 0], sizes=[clearance, sm_h] -) -sm_obj_list.append(new_obj) - -new_obj = q2d.modeler.create_rectangle( - origin=[co_gnd_w, layer_2_lh, 0], sizes=[clearance, sm_h] -) -q2d.modeler.move(assignment=[new_obj], vector=[sig_bot_w + "+" + clearance, 0, 0]) -sm_obj_list.append(new_obj) - -sm_obj = sm_obj_list[0] -q2d.modeler.unite(sm_obj_list) -sm_obj.material_name = "SolderMask" -sm_obj.color = (0, 150, 100) -sm_obj.name = "solder_mask" -# - - -# Assign a conductor to the signal. - -obj = q2d.modeler.get_object_from_name("signal") -q2d.assign_single_conductor( - name=obj.name, - assignment=[obj], - conductor_type="SignalLine", - solve_option="SolveOnBoundary", - units="mm", -) - -# Assign the reference ground. - -obj = [ - q2d.modeler.get_object_from_name(i) - for i in ["co_gnd_left", "co_gnd_right", "ref_gnd"] -] -q2d.assign_single_conductor( - name="gnd", - assignment=obj, - conductor_type="ReferenceGround", - solve_option="SolveOnBoundary", - units="mm", -) - -# Assign the Huray model for conductive losses on the signal trace. - -obj = q2d.modeler.get_object_from_name("signal") -q2d.assign_huray_finitecond_to_edges( - obj.edges, radius="0.5um", ratio=3, name="b_" + obj.name -) - -# ## Create the simulation setup -# -# Create the setup, analyze it, and plot solution data. - -# + -setup = q2d.create_setup(setupname="new_setup") - -sweep = setup.add_sweep(name="sweep1", sweep_type="Discrete") -sweep.props["RangeType"] = "LinearStep" -sweep.props["RangeStart"] = "1GHz" -sweep.props["RangeStep"] = "100MHz" -sweep.props["RangeEnd"] = "5GHz" -sweep.props["SaveFields"] = False -sweep.props["SaveRadFields"] = False -sweep.props["Type"] = "Interpolating" - -sweep.update() - -q2d.analyze(cores=NUM_CORES) - -data = q2d.post.get_solution_data(expressions="Z0(signal,signal)", context="Original") -data.plot() -# - - -# ## Release AEDT - -q2d.save_project() -q2d.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. -# If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell -# removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/high_frequency/radiofrequency_mmwave/index.rst b/examples/high_frequency/radiofrequency_mmwave/index.rst deleted file mode 100644 index c96f2e721..000000000 --- a/examples/high_frequency/radiofrequency_mmwave/index.rst +++ /dev/null @@ -1,140 +0,0 @@ -Radio frequency and millimeter wave -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -These examples use PyAEDT to show some radio frequency and millimeter wave applications. - - -.. grid:: 2 - - .. grid-item-card:: Inductive iris waveguide filter - :padding: 2 2 2 2 - :link: iris_filter - :link-type: doc - - .. image:: _static/wgf.png - :alt: Waveguide filter - :width: 250px - :height: 200px - :align: center - - This example shows how to build and analyze a four-pole X-Band waveguide filter using inductive irises. - - .. grid-item-card:: Spiral inductor - :padding: 2 2 2 2 - :link: spiral - :link-type: doc - - .. image:: _static/spiral.png - :alt: Spiral - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create a spiral inductor, solve it, and plot results. - - .. grid-item-card:: CPWG analysis - :padding: 2 2 2 2 - :link: coplanar_waveguide - :link-type: doc - - .. image:: _static/cpwg.png - :alt: CPWG - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create a CPWG (coplanar waveguide with ground) design in 2D Extractor and run a simulation. - - - .. grid-item-card:: Stripline analysis - :padding: 2 2 2 2 - :link: stripline - :link-type: doc - - .. image:: _static/stripline.png - :alt: Stripline - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create a differential stripline design in 2D Extractor and run a simulation. - - .. grid-item-card:: Lumped element filter design - :padding: 2 2 2 2 - :link: lumped_element - :link-type: doc - - .. image:: _static/lumped_filter.png - :alt: Lumped element filter - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to use the FilterSolutions module to design and visualize the frequency - response of a band-pass Butterworth filter. - - - .. grid-item-card:: Flex cable CPWG - :padding: 2 2 2 2 - :link: ../emc/flex_cable - :link-type: doc - - .. image:: ../emc/_static/flex_cable.png - :alt: Flex cable - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create a flex cable CPWG (coplanar waveguide with ground). - - .. grid-item-card:: Eigenmode filter - :padding: 2 2 2 2 - :link: ../emc/eigenmode - :link-type: doc - - .. image:: ../emc/_static/eigenmode.png - :alt: Eigenmode - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to automate the Eigenmode solver in HFSS. - - .. grid-item-card:: FSS unit cell simulation - :padding: 2 2 2 2 - :link: ../antenna/fss_unitcell - :link-type: doc - - .. image:: ../antenna/_static/unitcell.png - :alt: FSS - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to model and simulate a unit cell for a frequency-selective surface in HFSS. - - .. grid-item-card:: RF interference - :padding: 2 2 2 2 - :link: ../antenna/interferences/index - :link-type: doc - - .. image:: ../antenna/interferences/_static/emit_simple_cosite.png - :alt: EMIT logo - :width: 250px - :height: 200px - :align: center - - These examples use PyAEDT to show some general capabilities of EMIT for RF interference. - - .. toctree:: - :hidden: - - iris_filter - spiral - coplanar_waveguide - stripline - lumped_element - ../emc/flex_cable - ../emc/eigenmode - ../antenna/fss_unitcell - ../antenna/interferences/index diff --git a/examples/high_frequency/radiofrequency_mmwave/iris_filter.py b/examples/high_frequency/radiofrequency_mmwave/iris_filter.py deleted file mode 100644 index a0df6a421..000000000 --- a/examples/high_frequency/radiofrequency_mmwave/iris_filter.py +++ /dev/null @@ -1,277 +0,0 @@ -# # Inductive iris waveguide filter -# -# This example shows how to build and analyze a four-pole -# X-Band waveguide filter using inductive irises. -# -# Keywords: **HFSS**, **modal**, **waveguide filter**. - -# - -# ## Perform imports and define constants -# -# Perform required imports. -# - -import os -import tempfile -import time - -import ansys.aedt.core - -# Define constants. - -AEDT_VERSION = "2024.2" -NUM_CORES = 4 -NG_MODE = False # Open AEDT UI when it is launched. - - -# ## Launch AEDT - -# ### Define parameters and values for waveguide iris filter -# -# Define these parameters: - -# l: Length of the cavity from the mid-point of one iris -# to the midpoint of the next iris -# -# w: Width of the iris opening -# -# a: Long dimension of the waveguide cross-section (X-Band) -# -# b: Short dimension of the waveguide cross-section -# -# t: Metal thickness of the iris insert - -# + -wgparams = { - "l": [0.7428, 0.82188], - "w": [0.50013, 0.3642, 0.3458], - "a": 0.4, - "b": 0.9, - "t": 0.15, - "units": "in", -} -# - - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ### Create HFSS design - -project_name = os.path.join(temp_folder.name, "waveguide.aedt") -hfss = ansys.aedt.core.Hfss( - project=project_name, - version=AEDT_VERSION, - design="filter", - solution_type="Modal", - non_graphical=NG_MODE, - new_desktop=True, - close_on_exit=True, -) - - -# ### Initialize design parameters - -# + -hfss.modeler.model_units = "in" # Set to inches -var_mapping = dict() # Used by parse_expr to parse expressions. -for key in wgparams: - if type(wgparams[key]) in [int, float]: - hfss[key] = str(wgparams[key]) + wgparams["units"] - var_mapping[key] = wgparams[key] # Used for expression parsing. - elif type(wgparams[key]) == list: - count = 1 - for v in wgparams[key]: - this_key = key + str(count) - hfss[this_key] = str(v) + wgparams["units"] - var_mapping[ - this_key - ] = v # Used to parse expressions and generate numerical values. - count += 1 - -if len(wgparams["l"]) % 2 == 0: - zstart = "-t/2" # Even number of cavities, odd number of irises. - is_even = True -else: - zstart = "l1/2 - t/2" # Odd number of cavities, even number of irises. - is_even = False -# - - -# ### Draw parametric waveguide filter -# -# Define a function to place each iris at the correct longitudinal (z) position, -# Loop from the largest index (interior of the filter) to 1, which is the first -# iris nearest the waveguide ports. - - -def place_iris(z_pos, dz, param_count): - w_str = "w" + str(param_count) # Iris width parameter as a string. - this_name = "iris_a_" + str(param_count) # Iris object name in the HFSS project. - iris_new = [] # Return a list of the two objects that make up the iris. - if this_name in hfss.modeler.object_names: - this_name = this_name.replace("a", "c") - iris_new.append( - hfss.modeler.create_box( - ["-b/2", "-a/2", z_pos], - ["(b - " + w_str + ")/2", "a", dz], - name=this_name, - material="silver", - ) - ) - iris_new.append(iris_new[0].mirror([0, 0, 0], [1, 0, 0], duplicate=True)) - return iris_new - - -# ### Place irises -# -# Place the irises from inner (highest integer) to outer. - -zpos = zstart -for count in reversed(range(1, len(wgparams["w"]) + 1)): - if count < len(wgparams["w"]): # Update zpos - zpos = zpos + "".join([" + l" + str(count) + " + "])[:-3] - iris = place_iris(zpos, "t", count) - iris = place_iris("-(" + zpos + ")", "-t", count) - - else: # Place first iris - iris = place_iris(zpos, "t", count) - if not is_even: - iris = place_iris("-(" + zpos + ")", "-t", count) - -# ### Draw full waveguide with ports -# -# Use ``hfss.variable_manager``, which acts like a dictionary, to return an instance of -# the ``ansys.aedt.core.application.variables.VariableManager`` class for any variable. -# The ``VariableManager`` instance takes the HFSS variable name as a key. -# ``VariableManager`` properties enable access to update, modify, and -# evaluate variables. - -var_mapping["port_extension"] = 1.5 * wgparams["l"][0] -hfss["port_extension"] = str(var_mapping["port_extension"]) + wgparams["units"] -hfss["wg_z_start"] = "-(" + zpos + ") - port_extension" -hfss["wg_length"] = "2*(" + zpos + " + port_extension )" -wg_z_start = hfss.variable_manager["wg_z_start"] -wg_length = hfss.variable_manager["wg_length"] -hfss["u_start"] = "-a/2" -hfss["u_end"] = "a/2" -hfss.modeler.create_box( - ["-b/2", "-a/2", "wg_z_start"], - ["b", "a", "wg_length"], - name="waveguide", - material="vacuum", -) - -# ### Draw the entire waveguide -# -# The variable ``# wg_z`` is the total length of the waveguide, including the port extension. -# Note that the ``.evaluated_value`` provides access to the numerical value of -# ``wg_z_start``, which is an expression in HFSS. - -wg_z = [ - wg_z_start.evaluated_value, - hfss.value_with_units(wg_z_start.numeric_value + wg_length.numeric_value, "in"), -] - -# Assign wave ports to the end faces of the waveguide -# and define the calibration lines to ensure self-consistent -# polarization between wave ports. - -count = 0 -ports = [] -for n, z in enumerate(wg_z): - face_id = hfss.modeler.get_faceid_from_position([0, 0, z], assignment="waveguide") - u_start = [0, hfss.variable_manager["u_start"].evaluated_value, z] - u_end = [0, hfss.variable_manager["u_end"].evaluated_value, z] - - ports.append( - hfss.wave_port( - face_id, - integration_line=[u_start, u_end], - name="P" + str(n + 1), - renormalize=False, - ) - ) - -# ### Insert mesh adaptation setup -# -# Insert a mesh adaptation setup using refinement at two frequencies. -# This approach is useful for resonant structures because the coarse initial -# mesh impacts the resonant frequency and, hence, the field propagation through the -# filter. Adaptation at multiple frequencies helps to ensure that energy propagates -# through the resonant structure while the mesh is refined. - -# + -setup = hfss.create_setup( - "Setup1", - setup_type="HFSSDriven", - MultipleAdaptiveFreqsSetup=["9.8GHz", "10.2GHz"], - MaximumPasses=5, -) - -setup.create_frequency_sweep( - unit="GHz", - name="Sweep1", - start_frequency=9.5, - stop_frequency=10.5, - sweep_type="Interpolating", -) -# - - -# Solve the project with two tasks. -# Each frequency point is solved simultaneously. - - -setup.analyze(cores=NUM_CORES) - -# ### Postprocess -# -# The following commands fetch solution data from HFSS for plotting directly -# from the Python interpreter. -# -# **Caution:** The syntax for expressions must be identical to that used -# in HFSS. - -# + -traces_to_plot = hfss.get_traces_for_plot(second_element_filter="P1*") -report = hfss.post.create_report(traces_to_plot) # Creates a report in HFSS -solution = report.get_solution_data() - -plt = solution.plot(solution.expressions) # Matplotlib axes object. -# - - -# The following command generates a field plot in HFSS and uses PyVista -# to plot the field in Jupyter. - -plot = hfss.post.plot_field( - quantity="Mag_E", - assignment=["Global:XZ"], - plot_type="CutPlane", - setup=hfss.nominal_adaptive, - intrinsics={"Freq": "9.8GHz", "Phase": "0deg"}, - export_path=hfss.working_directory, - show=False, -) - -# ## Release AEDT -# -# The following command saves the project to a file and closes AEDT. - -hfss.save_project() -hfss.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. -# If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell removes -# all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/high_frequency/radiofrequency_mmwave/lumped_element.py b/examples/high_frequency/radiofrequency_mmwave/lumped_element.py deleted file mode 100644 index b7baa243e..000000000 --- a/examples/high_frequency/radiofrequency_mmwave/lumped_element.py +++ /dev/null @@ -1,81 +0,0 @@ -# # Lumped element filter design -# -# This example shows how to use PyAEDT to use the ``FilterSolutions`` module to design and -# visualize the frequency response of a band-pass Butterworth filter. -# -# Keywords: **filter solutions** - -# ## Perform imports and define constants -# -# Perform required imports. - -import ansys.aedt.core -import matplotlib.pyplot as plt -from ansys.aedt.core.filtersolutions_core.attributes import ( - FilterClass, FilterImplementation, FilterType) -from ansys.aedt.core.filtersolutions_core.ideal_response import \ - FrequencyResponseColumn - -# Define constants. - -AEDT_VERSION = "2025.1" - -# ## Define function used for plotting -# -# Define formal plot function. - - -def format_plot(): - plt.xlabel("Frequency (Hz)") - plt.ylabel("Magnitude S21 (dB)") - plt.title("Ideal Frequency Response") - plt.xscale("log") - plt.legend() - plt.grid() - - -# ## Create lumped filter design -# -# Create a lumped element filter design and assign the class, type, frequency, and order. - -design = ansys.aedt.core.FilterSolutions( - version=AEDT_VERSION, implementation_type=FilterImplementation.LUMPED -) -design.attributes.filter_class = FilterClass.BAND_PASS -design.attributes.filter_type = FilterType.BUTTERWORTH -design.attributes.pass_band_center_frequency = "1G" -design.attributes.pass_band_width_frequency = "500M" -design.attributes.filter_order = 5 - -# ## Plot frequency response of filter -# -# Plot the frequency response of the filter without any transmission zeros. - -freq, mag_db = design.ideal_response.frequency_response( - FrequencyResponseColumn.MAGNITUDE_DB -) -plt.plot(freq, mag_db, linewidth=2.0, label="Without Tx Zero") -format_plot() -plt.show() - -# ## Add a transmission zero to filter design -# -# Add a transmission zero that yields nulls separated by two times the pass band width (1 GHz). -# Plot the frequency response of the filter with the transmission zero. - -design.transmission_zeros_ratio.append_row("2.0") -freq_with_zero, mag_db_with_zero = design.ideal_response.frequency_response( - FrequencyResponseColumn.MAGNITUDE_DB -) -plt.plot(freq, mag_db, linewidth=2.0, label="Without Tx Zero") -plt.plot(freq_with_zero, mag_db_with_zero, linewidth=2.0, label="With Tx Zero") -format_plot() -plt.show() - -# ## Generate netlist for designed filter -# -# Generate and print the netlist for the designed filter with the added transmission zero to -# the filter. - -netlist = design.topology.circuit_response() -print("Netlist: \n", netlist) diff --git a/examples/high_frequency/radiofrequency_mmwave/spiral.py b/examples/high_frequency/radiofrequency_mmwave/spiral.py deleted file mode 100644 index f1e4dc923..000000000 --- a/examples/high_frequency/radiofrequency_mmwave/spiral.py +++ /dev/null @@ -1,234 +0,0 @@ -# # Spiral inductor -# -# This example shows how to use PyAEDT to create a spiral inductor, solve it, and plot results. -# -# Keywords: **HFSS**, **spiral**, **inductance**, **output variable**. - -# ## Perform imports and define constants -# -# Perform required imports. - -import os -import tempfile -import time - -import ansys.aedt.core - -# Define constants. - -AEDT_VERSION = "2024.2" -NUM_CORES = 4 -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Launch HFSS -# -# Create an HFSS design and change the units to microns. - -project_name = os.path.join(temp_folder.name, "spiral.aedt") -hfss = ansys.aedt.core.Hfss( - project=project_name, - version=AEDT_VERSION, - non_graphical=NG_MODE, - design="A1", - new_desktop=True, - solution_type="Modal", -) -hfss.modeler.model_units = "um" - -# ## Define variables -# -# Define input variables. You can use the values that follow or edit -# them. - -rin = 10 -width = 2 -spacing = 1 -thickness = 1 -Np = 8 -Nr = 10 -gap = 3 -hfss["Tsub"] = "6" + hfss.modeler.model_units - -# ## Standardize polyline -# -# Define a function that creates a polyline using the ``create_line()`` method. This -# function creates a polyline having a fixed width, thickness, and material. - - -def create_line(pts): - hfss.modeler.create_polyline( - pts, - xsection_type="Rectangle", - xsection_width=width, - xsection_height=thickness, - material="copper", - ) - - -# ## Create spiral inductor -# -# Create the spiral inductor. This spiral inductor is not -# parametric, but you could parametrize it later. - -ind = hfss.modeler.create_spiral( - internal_radius=rin, - width=width, - spacing=spacing, - turns=Nr, - faces=Np, - thickness=thickness, - material="copper", - name="Inductor1", -) - - -# ## Center return path -# -# Center the return path. - -x0, y0, z0 = ind.points[0] -x1, y1, z1 = ind.points[-1] -create_line([(x0 - width / 2, y0, -gap), (abs(x1) + 5, y0, -gap)]) -hfss.modeler.create_box( - [x0 - width / 2, y0 - width / 2, -gap - thickness / 2], - [width, width, gap + thickness], - matname="copper", -) - -# Create port 1. - -hfss.modeler.create_rectangle( - orientation=ansys.aedt.core.constants.PLANE.YZ, - origin=[abs(x1) + 5, y0 - width / 2, -gap - thickness / 2], - sizes=[width, "-Tsub+{}{}".format(gap, hfss.modeler.model_units)], - name="port1", -) -hfss.lumped_port(assignment="port1", integration_line=ansys.aedt.core.constants.AXIS.Z) - -# Create port 2. - -create_line([(x1 + width / 2, y1, 0), (x1 - 5, y1, 0)]) -hfss.modeler.create_rectangle( - ansys.aedt.core.constants.PLANE.YZ, - [x1 - 5, y1 - width / 2, -thickness / 2], - [width, "-Tsub"], - name="port2", -) -hfss.lumped_port(assignment="port2", integration_line=ansys.aedt.core.constants.AXIS.Z) - -# Create the silicon substrate and the ground plane. - -# + -hfss.modeler.create_box( - [x1 - 20, x1 - 20, "-Tsub-{}{}/2".format(thickness, hfss.modeler.model_units)], - [-2 * x1 + 40, -2 * x1 + 40, "Tsub"], - material="silicon", -) - -hfss.modeler.create_box( - [x1 - 20, x1 - 20, "-Tsub-{}{}/2".format(thickness, hfss.modeler.model_units)], - [-2 * x1 + 40, -2 * x1 + 40, -0.1], - material="PEC", -) -# - - -# ## Set up model -# -# Create the air box and radiation boundary condition. - -# + -box = hfss.modeler.create_box( - [ - x1 - 20, - x1 - 20, - "-Tsub-{}{}/2 - 0.1{}".format( - thickness, hfss.modeler.model_units, hfss.modeler.model_units - ), - ], - [-2 * x1 + 40, -2 * x1 + 40, 100], - name="airbox", - material="air", -) - -hfss.assign_radiation_boundary_to_objects("airbox") -# - - -# Assign a material override that allows object intersections, -# assigning conductors higher priority than insulators. - -hfss.change_material_override() - -# View the model. - -hfss.plot( - show=False, - output_file=os.path.join(hfss.working_directory, "Image.jpg"), - plot_air_objects=False, -) - -# ## Generate the solution -# -# Create the setup, including a frequency sweep. Then, solve the project. - -setup1 = hfss.create_setup(name="setup1") -setup1.props["Frequency"] = "10GHz" -hfss.create_linear_count_sweep( - setup="setup1", - units="GHz", - start_frequency=1e-3, - stop_frequency=50, - num_of_freq_points=451, - sweep_type="Interpolating", -) -hfss.save_project() -hfss.analyze(cores=NUM_CORES) - -# ## Postprocess -# -# Get report data and use the following formulas to calculate -# the inductance and quality factor. - -L_formula = "1e9*im(1/Y(1,1))/(2*pi*freq)" -Q_formula = "im(Y(1,1))/re(Y(1,1))" - -# Define the inductance as a postprocessing variable. - -hfss.create_output_variable("L", L_formula, solution="setup1 : LastAdaptive") - -# Plot the results using Matplotlib. - -data = hfss.post.get_solution_data([L_formula, Q_formula]) -data.plot( - curves=[L_formula, Q_formula], formula="re", x_label="Freq", y_label="L and Q" -) - -# Export results to a CSV file - -data.export_data_to_csv(os.path.join(hfss.toolkit_directory, "output.csv")) - -# ## Save project and close AEDT -# -# Save the project and close AEDT. - -hfss.save_project() -hfss.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. -# If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell removes -# all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/high_frequency/radiofrequency_mmwave/stripline.py b/examples/high_frequency/radiofrequency_mmwave/stripline.py deleted file mode 100644 index 3412f13b0..000000000 --- a/examples/high_frequency/radiofrequency_mmwave/stripline.py +++ /dev/null @@ -1,266 +0,0 @@ -# # Stripline analysis - -# This example shows how to use PyAEDT to create a differential stripline design in -# 2D Extractor and run a simulation. -# -# Keywords: **Q2D**, **Stripline**. - -# ## Perform imports and define constants -# -# Perform required imports. - -# + -import os -import tempfile -import time - -import ansys.aedt.core - -# - - -# Define constants. - -AEDT_VERSION = "2024.2" -NUM_CORES = 4 - - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Launch AEDT and 2D Extractor -# -# Launch AEDT 2024.2 in graphical mode and launch 2D Extractor. This example -# uses SI units. - -q2d = ansys.aedt.core.Q2d( - project=os.path.join(temp_folder.name, "stripline"), - design="differential_stripline", - version=AEDT_VERSION, - non_graphical=False, - new_desktop=True, -) - -# ## Define variables -# -# Define variables. - -# + -e_factor = "e_factor" -sig_w = "sig_bot_w" -sig_gap = "sig_gap" -co_gnd_w = "gnd_w" -clearance = "clearance" -cond_h = "cond_h" -core_h = "core_h" -pp_h = "pp_h" - -for var_name, var_value in { - "e_factor": "2", - "sig_bot_w": "150um", - "sig_gap": "150um", - "gnd_w": "500um", - "clearance": "150um", - "cond_h": "17um", - "core_h": "150um", - "pp_h": "150um", -}.items(): - q2d[var_name] = var_value - -delta_w_half = "({0}/{1})".format(cond_h, e_factor) -sig_top_w = "({1}-{0}*2)".format(delta_w_half, sig_w) -co_gnd_top_w = "({1}-{0}*2)".format(delta_w_half, co_gnd_w) -model_w = "{}*2+{}*2+{}*2+{}".format(co_gnd_w, clearance, sig_w, sig_gap) -# - - -# ## Create primitives -# -# Create primitives and define the layer heights. - -layer_1_lh = 0 -layer_1_uh = cond_h -layer_2_lh = layer_1_uh + "+" + core_h -layer_2_uh = layer_2_lh + "+" + cond_h -layer_3_lh = layer_2_uh + "+" + pp_h -layer_3_uh = layer_3_lh + "+" + cond_h - -# ## Create positive signal -# -# Create a positive signal. - -signal_p_1 = q2d.modeler.create_polyline( - points=[[0, layer_2_lh, 0], [sig_w, layer_2_lh, 0]], name="signal_p_1" -) - -signal_p_2 = q2d.modeler.create_polyline( - points=[[0, layer_2_uh, 0], [sig_top_w, layer_2_uh, 0]], name="signal_p_2" -) -q2d.modeler.move([signal_p_2], [delta_w_half, 0, 0]) -q2d.modeler.connect([signal_p_1, signal_p_2]) -q2d.modeler.move( - assignment=[signal_p_1], vector=["{}+{}".format(co_gnd_w, clearance), 0, 0] -) - -# ## Create negative signal -# -# Create a negative signal. - -signal_n_1 = q2d.modeler.create_polyline( - points=[[0, layer_2_lh, 0], [sig_w, layer_2_lh, 0]], name="signal_n_1" -) - -signal_n_2 = q2d.modeler.create_polyline( - points=[[0, layer_2_uh, 0], [sig_top_w, layer_2_uh, 0]], name="signal_n_2" -) - -q2d.modeler.move(assignment=[signal_n_2], vector=[delta_w_half, 0, 0]) -q2d.modeler.connect([signal_n_1, signal_n_2]) -q2d.modeler.move( - assignment=[signal_n_1], - vector=["{}+{}+{}+{}".format(co_gnd_w, clearance, sig_w, sig_gap), 0, 0], -) - -# ## Create reference ground plane -# -# Create a reference ground plane. - -ref_gnd_u = q2d.modeler.create_rectangle( - origin=[0, layer_1_lh, 0], sizes=[model_w, cond_h], name="ref_gnd_u" -) -ref_gnd_l = q2d.modeler.create_rectangle( - origin=[0, layer_3_lh, 0], sizes=[model_w, cond_h], name="ref_gnd_l" -) - -# ## Create dielectric -# -# Create a dielectric. - -q2d.modeler.create_rectangle( - origin=[0, layer_1_uh, 0], - sizes=[model_w, core_h], - name="Core", - material="FR4_epoxy", -) -q2d.modeler.create_rectangle( - origin=[0, layer_2_uh, 0], - sizes=[model_w, pp_h], - name="Prepreg", - material="FR4_epoxy", -) -q2d.modeler.create_rectangle( - origin=[0, layer_2_lh, 0], - sizes=[model_w, cond_h], - name="Filling", - material="FR4_epoxy", -) - -# ## Assign conductors -# -# Assign conductors to the signal. - -# + -q2d.assign_single_conductor( - name=signal_p_1.name, - assignment=[signal_p_1], - conductor_type="SignalLine", - solve_option="SolveOnBoundary", - units="mm", -) - -q2d.assign_single_conductor( - name=signal_n_1.name, - assignment=[signal_n_1], - conductor_type="SignalLine", - solve_option="SolveOnBoundary", - units="mm", -) -# - - -# ## Create reference ground -# -# Create a reference ground. - -q2d.assign_single_conductor( - name="gnd", - assignment=[ref_gnd_u, ref_gnd_l], - conductor_type="ReferenceGround", - solve_option="SolveOnBoundary", - units="mm", -) - -# ## Assign Huray model on signals -# -# Assign the Huray model on the signals. - -# + -q2d.assign_huray_finitecond_to_edges( - signal_p_1.edges, radius="0.5um", ratio=3, name="b_" + signal_p_1.name -) - -q2d.assign_huray_finitecond_to_edges( - signal_n_1.edges, radius="0.5um", ratio=3, name="b_" + signal_n_1.name -) -# - - -# ## Define differential pair -# -# Define the differential pair. - -matrix = q2d.insert_reduced_matrix( - operation_name=q2d.MATRIXOPERATIONS.DiffPair, - assignment=["signal_p_1", "signal_n_1"], - reduced_matrix="diff_pair", -) - -# ## Create setup, analyze, and plot -# -# Create a setup, analyze, and plot solution data. - -# Create a setup. - -setup = q2d.create_setup(name="new_setup") - -# Add a sweep. - -sweep = setup.add_sweep(name="sweep1", sweep_type="Discrete") -sweep.props["RangeType"] = "LinearStep" -sweep.props["RangeStart"] = "1GHz" -sweep.props["RangeStep"] = "100MHz" -sweep.props["RangeEnd"] = "5GHz" -sweep.props["SaveFields"] = False -sweep.props["SaveRadFields"] = False -sweep.props["Type"] = "Interpolating" -sweep.update() - -# Analyze the nominal design and plot characteristic impedance. - -q2d.analyze(cores=NUM_CORES) -plot_sources = matrix.get_sources_for_plot(category="Z0") - -# Get simulation results as a ``SolutionData`` object and plot to a JPG file. - -data = q2d.post.get_solution_data(expressions=plot_sources, context=matrix.name) -data.plot(snapshot_path=os.path.join(temp_folder.name, "plot.jpg")) - -# - - -# ## Release AEDT - -q2d.save_project() -q2d.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. -# If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell -# removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/index.rst b/examples/index.rst index 5dce8a4ea..1d9b581c6 100644 --- a/examples/index.rst +++ b/examples/index.rst @@ -7,71 +7,6 @@ This repository contains end-to-end embedding examples that demonstrate how to u .. grid:: 2 - .. grid-item-card:: PyAEDT basics - :padding: 2 2 2 2 - :link: https://aedt.docs.pyansys.com/version/stable/User_guide/index.html - :link-type: url - - .. image:: basic/_static/logo.png - :alt: PyAEDT logo - :width: 250px - :height: 200px - :align: center - - Links to brief tutorials provided in the PyAEDT documentation. - - .. grid-item-card:: Examples by AEDT application - :padding: 2 2 2 2 - :link: aedt/index - :link-type: doc - - .. image:: aedt/_static/aedt.png - :alt: AEDT - :width: 250px - :height: 200px - :align: center - - Provides examples organized by AEDT applications. - - .. grid-item-card:: High Frequency - :padding: 2 2 2 2 - :link: high_frequency/index - :link-type: doc - - .. image:: high_frequency/_static/hf.png - :alt: High frequency IC - :width: 250px - :height: 200px - :align: center - - Provides examples of PyAEDT capabilities for high-frequency applications. - - .. grid-item-card:: Low Frequency - :padding: 2 2 2 2 - :link: low_frequency/index - :link-type: doc - - .. image:: low_frequency/_static/motor_maxwell.png - :alt: Low frequency motor - :width: 250px - :height: 200px - :align: center - - Provides examples of PyAEDT capabilities for low-frequency applications. - - .. grid-item-card:: Electrothermal - :padding: 2 2 2 2 - :link: electrothermal/index - :link-type: doc - - .. image:: electrothermal/_static/icepak_logo.png - :alt: Icepak - :width: 250px - :height: 200px - :align: center - - Provides examples of PyAEDT capabilities for electrothermal applications. - .. grid-item-card:: Pre-processing and post-processing :padding: 2 2 2 2 :link: aedt_general/index @@ -90,8 +25,4 @@ This repository contains end-to-end embedding examples that demonstrate how to u :hidden: :maxdepth: 2 - aedt/index - high_frequency/index - low_frequency/index - electrothermal/index aedt_general/index \ No newline at end of file diff --git a/examples/low_frequency/_static/CFD_coil.png b/examples/low_frequency/_static/CFD_coil.png deleted file mode 100644 index 3de4b2fdb..000000000 Binary files a/examples/low_frequency/_static/CFD_coil.png and /dev/null differ diff --git a/examples/low_frequency/_static/TEAM.png b/examples/low_frequency/_static/TEAM.png deleted file mode 100644 index cfc087a22..000000000 Binary files a/examples/low_frequency/_static/TEAM.png and /dev/null differ diff --git a/examples/low_frequency/_static/general.png b/examples/low_frequency/_static/general.png deleted file mode 100644 index 24c90dd9c..000000000 Binary files a/examples/low_frequency/_static/general.png and /dev/null differ diff --git a/examples/low_frequency/_static/magnetic.png b/examples/low_frequency/_static/magnetic.png deleted file mode 100644 index f812ba0b2..000000000 Binary files a/examples/low_frequency/_static/magnetic.png and /dev/null differ diff --git a/examples/low_frequency/_static/motor_maxwell.png b/examples/low_frequency/_static/motor_maxwell.png deleted file mode 100644 index b0f49570a..000000000 Binary files a/examples/low_frequency/_static/motor_maxwell.png and /dev/null differ diff --git a/examples/low_frequency/_static/pcb_stress.png b/examples/low_frequency/_static/pcb_stress.png deleted file mode 100644 index 5b1e260c4..000000000 Binary files a/examples/low_frequency/_static/pcb_stress.png and /dev/null differ diff --git a/examples/low_frequency/general/_static/control_program.png b/examples/low_frequency/general/_static/control_program.png deleted file mode 100644 index e64ee23a5..000000000 Binary files a/examples/low_frequency/general/_static/control_program.png and /dev/null differ diff --git a/examples/low_frequency/general/_static/dc.png b/examples/low_frequency/general/_static/dc.png deleted file mode 100644 index ff3fa23ba..000000000 Binary files a/examples/low_frequency/general/_static/dc.png and /dev/null differ diff --git a/examples/low_frequency/general/_static/eddy_current.png b/examples/low_frequency/general/_static/eddy_current.png deleted file mode 100644 index f354a609c..000000000 Binary files a/examples/low_frequency/general/_static/eddy_current.png and /dev/null differ diff --git a/examples/low_frequency/general/_static/electrostatic.png b/examples/low_frequency/general/_static/electrostatic.png deleted file mode 100644 index e6013dae9..000000000 Binary files a/examples/low_frequency/general/_static/electrostatic.png and /dev/null differ diff --git a/examples/low_frequency/general/_static/external_circuit.png b/examples/low_frequency/general/_static/external_circuit.png deleted file mode 100644 index f1f73bdfe..000000000 Binary files a/examples/low_frequency/general/_static/external_circuit.png and /dev/null differ diff --git a/examples/low_frequency/general/_static/field.png b/examples/low_frequency/general/_static/field.png deleted file mode 100644 index 35b73fcc4..000000000 Binary files a/examples/low_frequency/general/_static/field.png and /dev/null differ diff --git a/examples/low_frequency/general/_static/resistance.png b/examples/low_frequency/general/_static/resistance.png deleted file mode 100644 index c0f27a8de..000000000 Binary files a/examples/low_frequency/general/_static/resistance.png and /dev/null differ diff --git a/examples/low_frequency/general/control_program.py b/examples/low_frequency/general/control_program.py deleted file mode 100644 index 6340792dd..000000000 --- a/examples/low_frequency/general/control_program.py +++ /dev/null @@ -1,106 +0,0 @@ -# # Control program enablement - -# This example shows how to use PyAEDT to enable a control program in a Maxwell 2D project. -# It shows how to create the geometry, load material properties from an Excel file, and -# set up the mesh settings. Moreover, it focuses on postprocessing operations, in particular how to -# plot field line traces, which are relevant for an electrostatic analysis. -# -# Keywords: **Maxwell 2D**, **control program**. - -# ## Perform imports and define constants -# -# Perform required imports. - -import tempfile -import time - -from ansys.aedt.core import Maxwell2d, downloads - -# Define constants. - -AEDT_VERSION = "2024.2" -NUM_CORES = 4 -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Download project file -# -# Download the files required to run this example to the temporary working folder. - -aedt_file = downloads.download_file( - source="maxwell_ctrl_prg", - name="ControlProgramDemo.aedt", - destination=temp_folder.name, -) -ctrl_prg_file = downloads.download_file( - source="maxwell_ctrl_prg", name="timestep_only.py", destination=temp_folder.name -) - -# ## Launch Maxwell 2D -# -# Create an instance of the ``Maxwell2d`` class named ``m2d``. - -m2d = Maxwell2d( - project=aedt_file, - version=AEDT_VERSION, - new_desktop=True, - non_graphical=NG_MODE, -) - -# ## Set active design - -m2d.set_active_design("1 time step control") - -# ## Get setup -# -# Get the simulation setup for this design so that the control program can be enabled. - -setup = m2d.setups[0] - -# ## Enable control program -# -# Enable the control program by giving the path to the file. - -setup.enable_control_program(control_program_path=ctrl_prg_file) - -# ## Analyze setup -# -# Run the analysis. - -m2d.save_project() -m2d.analyze(setup=setup.name, cores=NUM_CORES, use_auto_settings=False) - -# ## Plot results -# -# Display the simulation results. - -sols = m2d.post.get_solution_data( - expressions="FluxLinkage(Winding1)", - variations={"Time": ["All"]}, - primary_sweep_variable="Time", -) -sols.plot() - -# ## Release AEDT - -m2d.save_project() -m2d.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. -# If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell -# removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/low_frequency/general/dc_analysis.py b/examples/low_frequency/general/dc_analysis.py deleted file mode 100644 index c9d65bbbf..000000000 --- a/examples/low_frequency/general/dc_analysis.py +++ /dev/null @@ -1,143 +0,0 @@ -# # Electro DC analysis - -# This example shows how to use PyAEDT to create a Maxwell DC analysis, -# compute mass center, and move coordinate systems. -# -# Keywords: **Maxwell 3D**, **DC**. - -# ## Perform imports and define constants -# -# Perform required imports. - -import os -import tempfile -import time - -from ansys.aedt.core import Maxwell3d - -# Define constants. - -AEDT_VERSION = "2024.2" -NUM_CORES = 4 -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Launch AEDT -# -# Create an instance of the ``Maxwell3d`` class named ``m3d`` by providing -# the project name, the version, and the graphical mode. - -project_name = os.path.join(temp_folder.name, "conductor_example.aedt") -m3d = Maxwell3d( - project=project_name, - version=AEDT_VERSION, - new_desktop=True, - non_graphical=NG_MODE, -) - -# ## Set up Maxwell solution -# -# Set up the Maxwell solution to DC. - -m3d.solution_type = m3d.SOLUTIONS.Maxwell3d.ElectroDCConduction - -# ## Create conductor -# -# Create a conductor using copper, a predefined material in the Maxwell material library. - -conductor = m3d.modeler.create_box( - origin=[7, 4, 22], sizes=[10, 5, 30], name="Conductor", material="copper" -) - -# ## Create setup and assign voltage - -m3d.assign_voltage(assignment=conductor.faces, amplitude=0) -m3d.create_setup() - -# ## Solve setup - -m3d.analyze(cores=NUM_CORES) - -# ## Compute mass center -# -# Compute mass center using PyAEDT advanced fields calculator. - -scalar_function = "" -mass_center = { - "name": "", - "description": "Mass center computation", - "design_type": ["Maxwell 3D"], - "fields_type": ["Fields"], - "primary_sweep": "distance", - "assignment": "", - "assignment_type": ["Solid"], - "operations": [ - scalar_function, - "EnterVolume('assignment')", - "Operation('VolumeValue')", - "Operation('Mean')", - ], - "report": ["Data Table"], -} -mass_center["name"] = "CM_X" -scalar_function = "Scalar_Function(FuncValue='X')" -mass_center["operations"][0] = scalar_function -m3d.post.fields_calculator.add_expression(mass_center, conductor.name) -mass_center["name"] = "CM_Y" -scalar_function = "Scalar_Function(FuncValue='Y')" -mass_center["operations"][0] = scalar_function -m3d.post.fields_calculator.add_expression(mass_center, conductor.name) -mass_center["name"] = "CM_Z" -scalar_function = "Scalar_Function(FuncValue='Z')" -mass_center["operations"][0] = scalar_function -m3d.post.fields_calculator.add_expression(mass_center, conductor.name) - -# ## Get mass center -# -# Get mass center using the fields calculator. - -xval = m3d.post.get_scalar_field_value(quantity="CM_X") -yval = m3d.post.get_scalar_field_value(quantity="CM_Y") -zval = m3d.post.get_scalar_field_value(quantity="CM_Z") - -# ## Create variables -# -# Create variables with mass center values. - -m3d[conductor.name + "x"] = str(xval * 1e3) + "mm" -m3d[conductor.name + "y"] = str(yval * 1e3) + "mm" -m3d[conductor.name + "z"] = str(zval * 1e3) + "mm" - -# ## Create coordinate system -# -# Create a parametric coordinate system. - -cs1 = m3d.modeler.create_coordinate_system( - origin=[conductor.name + "x", conductor.name + "y", conductor.name + "z"], - reference_cs="Global", - name=conductor.name + "CS", -) - -# ## Release AEDT - -m3d.save_project() -m3d.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. -# If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell -# removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/low_frequency/general/eddy_current.py b/examples/low_frequency/general/eddy_current.py deleted file mode 100644 index 94184957c..000000000 --- a/examples/low_frequency/general/eddy_current.py +++ /dev/null @@ -1,132 +0,0 @@ -# # Eddy current analysis and reduced matrix - -# This example shows how to leverage PyAEDT to assign a matrix -# and perform series or parallel connections in a Maxwell 2D design. -# -# Keywords: **Maxwell 2D**, **eddy current**, *matrix**. - -# ## Perform imports and define constants -# -# Perform required imports. - -import tempfile -import time - -import ansys.aedt.core - -# Define constants. - -AEDT_VERSION = "2024.2" -NUM_CORES = 4 -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Download AEDT file -# -# Set the local temporary folder to export the AEDT file to. - -project_path = ansys.aedt.core.downloads.download_file( - source="maxwell_ec_reduced_matrix", - name="m2d_eddy_current.aedt", - destination=temp_folder.name, -) - -# ## Launch AEDT and Maxwell 2D -# -# Launch AEDT and Maxwell 2D, providing the version, path to the project, and the graphical mode. - -m2d = ansys.aedt.core.Maxwell2d( - project=project_path, - version=AEDT_VERSION, - design="EC_Planar", - non_graphical=NG_MODE, -) - -# ## Assign a matrix -# -# Assign a matrix given the list of sources to assign the matrix to and the return path. - -matrix = m2d.assign_matrix( - assignment=["pri", "sec", "terz"], matrix_name="Matrix1", return_path="infinite" -) - -# ## Assign reduced matrices -# -# Assign reduced matrices to the parent matrix previously created. -# For 2D/3D Eddy current solvers, two or more excitations can be joined -# either in series or parallel connection. The result is known as a reduced matrix. - -series = matrix.join_series(sources=["pri", "sec"], matrix_name="ReducedMatrix1") -parallel = matrix.join_parallel(sources=["sec", "terz"], matrix_name="ReducedMatrix2") - -# ## Analyze setup -# -# Run the analysis. - -m2d.save_project() -m2d.analyze(setup=m2d.setup_names[0], cores=NUM_CORES, use_auto_settings=False) - -# ## Get expressions -# -# Get the available report quantities given the context -# and the quantities category ``L``. - -expressions = m2d.post.available_report_quantities( - report_category="EddyCurrent", - display_type="Data Table", - context={"Matrix1": "ReducedMatrix1"}, - quantities_category="L", -) - -# ## Create report and get solution data -# -# Create a data table report and get report data given the matrix context. - -report = m2d.post.create_report( - expressions=expressions, - context={"Matrix1": "ReducedMatrix1"}, - plot_type="Data Table", - setup_sweep_name="Setup1 : LastAdaptive", - plot_name="reduced_matrix", -) -data = m2d.post.get_solution_data( - expressions=expressions, - context={"Matrix1": "ReducedMatrix1"}, - report_category="EddyCurrent", - setup_sweep_name="Setup1 : LastAdaptive", -) - -# ## Get matrix data -# -# Get inductance results for the join connections in ``nH``. - -ind = ansys.aedt.core.generic.constants.unit_converter( - data.data_magnitude()[0], - unit_system="Inductance", - input_units=data.units_data[expressions[0]], - output_units="uH", -) - -# ## Release AEDT - -m2d.save_project() -m2d.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. -# If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell -# removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/low_frequency/general/electrostatic.py b/examples/low_frequency/general/electrostatic.py deleted file mode 100644 index 598008ffb..000000000 --- a/examples/low_frequency/general/electrostatic.py +++ /dev/null @@ -1,227 +0,0 @@ -# # Electrostatic analysis - -# This example shows how to use PyAEDT to create a Maxwell 2D electrostatic analysis. -# It shows how to create the geometry, load material properties from a Microsoft Excel file, and -# set up the mesh settings. Moreover, it focuses on postprocessing operations, in particular how to -# plot field line traces, which are relevant for an electrostatic analysis. -# -# Keywords: **Maxwell 2D**, **electrostatic**. - -# ## Perform imports and define constants -# -# Perform required imports. - -import os -import tempfile -import time - -import ansys.aedt.core - -# Define constants. - -AEDT_VERSION = "2024.2" -NUM_CORES = 4 -NG_MODE = False - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``.. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Download Excel file -# -# Set the local temporary folder to export the Excel (XLSX) file to. - -file_name_xlsx = ansys.aedt.core.downloads.download_file( - source="field_line_traces", name="my_copper.xlsx", destination=temp_folder.name -) - -# ## Initialize dictionaries -# -# Initialize the dictionaries that contain all the definitions for the design variables. - -# + -geom_params_circle = { - "circle_x0": "-10mm", - "circle_y0": "0mm", - "circle_z0": "0mm", - "circle_axis": "Z", - "circle_radius": "1mm", -} - -geom_params_rectangle = { - "r_x0": "1mm", - "r_y0": "5mm", - "r_z0": "0mm", - "r_axis": "Z", - "r_dx": "-1mm", - "r_dy": "-10mm", -} -# - - -# ## Launch AEDT and Maxwell 2D -# -# Launch AEDT and Maxwell 2D after first setting up the project and design names, -# the solver, and the version. The following code also creates an instance of the -# ``Maxwell2d`` class named ``m2d``. - -project_name = os.path.join(temp_folder.name, "M2D_Electrostatic.aedt") -m2d = ansys.aedt.core.Maxwell2d( - project=project_name, - version=AEDT_VERSION, - design="Design1", - solution_type="Electrostatic", - new_desktop=True, - non_graphical=NG_MODE, -) - -# ## Set modeler units -# -# Set modeler units to ``mm``. - -m2d.modeler.model_units = "mm" - -# ## Define variables from dictionaries -# -# Define design variables from the created dictionaries. - -for k, v in geom_params_circle.items(): - m2d[k] = v -for k, v in geom_params_rectangle.items(): - m2d[k] = v - -# ## Read materials from Excel file -# -# Read materials from the Excel file into the design. - -mats = m2d.materials.import_materials_from_excel(file_name_xlsx) - -# ## Create design geometries -# -# Create a rectangle and a circle. Assign the material read from the Excel file. -# Create two new polylines and a region. - -# + -rect = m2d.modeler.create_rectangle( - origin=["r_x0", "r_y0", "r_z0"], - sizes=["r_dx", "r_dy", 0], - name="Ground", - material=mats[0], -) -rect.color = (0, 0, 255) # rgb -rect.solve_inside = False - -circle = m2d.modeler.create_circle( - origin=["circle_x0", "circle_y0", "circle_z0"], - radius="circle_radius", - num_sides="0", - is_covered=True, - name="Electrode", - material=mats[0], -) -circle.color = (0, 0, 255) # rgb -circle.solve_inside = False - -poly1_points = [[-9, 2, 0], [-4, 2, 0], [2, -2, 0], [8, 2, 0]] -poly2_points = [[-9, 0, 0], [9, 0, 0]] -poly1_id = m2d.modeler.create_polyline( - points=poly1_points, segment_type="Spline", name="Poly1" -) -poly2_id = m2d.modeler.create_polyline(points=poly2_points, name="Poly2") -m2d.modeler.split(assignment=[poly1_id, poly2_id], plane="YZ", sides="NegativeOnly") -m2d.modeler.create_region(pad_value=[20, 100, 20, 100]) -# - - -# ## Define excitations -# -# Assign voltage excitations to the rectangle and circle. - -m2d.assign_voltage(assignment=rect.id, amplitude=0, name="Ground") -m2d.assign_voltage(assignment=circle.id, amplitude=50e6, name="50kV") - -# ## Create initial mesh settings -# -# Assign a surface mesh to the rectangle. - -m2d.mesh.assign_surface_mesh_manual(assignment=["Ground"], surface_deviation=0.001) - -# ## Create, validate, and analyze setup - -setup_name = "MySetupAuto" -setup = m2d.create_setup(name=setup_name) -setup.props["PercentError"] = 0.5 -setup.update() -m2d.validate_simple() -m2d.analyze_setup(name=setup_name, use_auto_settings=False, cores=NUM_CORES) - -# ## Evaluate the E Field tangential component -# -# Evaluate the E Field tangential component along the given polylines. -# Add these operations to the **Named Expression** list in the field calculator. - -e_line = m2d.post.fields_calculator.add_expression( - calculation="e_line", assignment=None -) -m2d.post.fields_calculator.expression_plot( - calculation="e_line", assignment="Poly1", names=[e_line] -) -m2d.post.fields_calculator.expression_plot( - calculation="e_line", assignment="Poly12", names=[e_line] -) - -# ## Create field line traces plot -# -# Create a field line traces plot specifying as seeding faces -# the ground, the electrode, and the region -# and as ``In surface objects`` only the region. - -plot = m2d.post.create_fieldplot_line_traces( - seeding_faces=["Ground", "Electrode", "Region"], - in_volume_tracing_objs=["Region"], - plot_name="LineTracesTest", -) - -# ## Update field line traces plot -# -# Update the field line traces plot. -# Update the seeding points number, line style, and line width. - -plot.SeedingPointsNumber = 20 -plot.LineStyle = "Cylinder" -plot.LineWidth = 3 -plot.update() - -# ## Export field line traces plot -# -# Export the field line traces plot. -# For the field lint traces plot, the export file format is ``.fldplt``. - -m2d.post.export_field_plot( - plot_name="LineTracesTest", output_dir=temp_folder.name, file_format="fldplt" -) - -# ## Export mesh field plot -# -# Export the mesh to an AEDTPLT file. - -m2d.post.export_mesh_obj(setup=m2d.nominal_adaptive) - -# ## Release AEDT - -m2d.save_project() -m2d.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. -# If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell -# removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/low_frequency/general/external_circuit.py b/examples/low_frequency/general/external_circuit.py deleted file mode 100644 index 53c731ddf..000000000 --- a/examples/low_frequency/general/external_circuit.py +++ /dev/null @@ -1,258 +0,0 @@ -# # External delta circuit -# -# This example shows how to create an external delta circuit and connect it with a Maxwell 2D design. -# -# Keywords: **Maxwell 2D**, **Circuit**, **netlist** - -# ## Perform imports and define constants - -import os -import tempfile -import time - -import ansys.aedt.core - -# Define constants. - -AEDT_VERSION = "2024.2" -NUM_CORES = 4 -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Launch AEDT and Maxwell 2D -# -# Launch AEDT and Maxwell 2D providing the version, path to the project, and the graphical mode. - -project_name = os.path.join(temp_folder.name, "Maxwell_circuit_example.aedt") -design_name = "1 Maxwell" -circuit_name = "2 Delta circuit" - -m2d = ansys.aedt.core.Maxwell2d( - version=AEDT_VERSION, - new_desktop=False, - design=design_name, - project=project_name, - solution_type="TransientXY", - non_graphical=NG_MODE, -) - -# ## Initialize dictionaries and define variables -# -# Initialize dictionaries that contain all design variable definitions. - -voltage = "230V" -frequency = "50Hz" - -transient_parameters = { - "voltage": voltage, - "frequency": frequency, - "electric_period": "1 / frequency s", - "stop_time": "2 * electric_period s", - "time_step": "electric_period / 20 s", -} - -circuit_parameters = { - "voltage": voltage, - "frequency": frequency, - "resistance_value": "1Ohm", -} - -for k, v in transient_parameters.items(): - m2d[k] = v - -# ## Create geometry -# -# Create copper coils and a vacuum region. Assign mesh operations, and then assign a balloon boundary to the region edges. - -coil1_id = m2d.modeler.create_circle( - orientation="Z", origin=[0, 0, 0], radius=10, name="coil1", material="copper" -) -coil2_id = m2d.modeler.create_circle( - orientation="Z", origin=[25, 0, 0], radius=10, name="coil2", material="copper" -) -coil3_id = m2d.modeler.create_circle( - orientation="Z", origin=[50, 0, 0], radius=10, name="coil3", material="copper" -) - -region = m2d.modeler.create_region(pad_value=[200, 400, 200, 400]) - -m2d.mesh.assign_length_mesh( - assignment=[coil1_id, coil2_id, coil3_id, region], maximum_length=5 -) - -m2d.assign_vector_potential(assignment=region.edges, vector_value=0) - -# ## Assign excitations -# -# Assign external windings - -wdg1 = m2d.assign_winding( - assignment=["coil1"], - is_solid=False, - winding_type="External", - name="winding1", - current=0, -) -wdg2 = m2d.assign_winding( - assignment=["coil2"], - is_solid=False, - winding_type="External", - name="winding2", - current=0, -) -wdg3 = m2d.assign_winding( - assignment=["coil3"], - is_solid=False, - winding_type="External", - name="winding3", - current=0, -) - -# ## Create simulation setup -# -# Create the simulation setup, defining the stop time and time step. - -setup = m2d.create_setup() -setup["StopTime"] = "stop_time" -setup["TimeStep"] = "time_step" - -# ## Create external circuit -# -# Create the circuit design, including all windings of type ``External`` in the Maxwell design. - -circuit = m2d.create_external_circuit(circuit_design=circuit_name) - -# ## Define variables from dictionaries -# -# Define design variables from the created dictionaries. - -for k, v in circuit_parameters.items(): - circuit[k] = v - -windings = [ - circuit.modeler.schematic.components[k] - for k in list(circuit.modeler.schematic.components.keys()) - if circuit.modeler.schematic.components[k].parameters["Info"] == "Winding" -] - -# ## Finalize external circuit -# -# Draw these other components: resistors, voltage sources, and grounds - -circuit.modeler.schematic_units = "mil" - -resistors = [] -v_sources = [] -ground = [] - -for i in range(len(windings)): - r = circuit.modeler.schematic.create_resistor( - name="R" + str(i + 1), value="resistance_value", location=[1000, i * 1000] - ) - resistors.append(r) - - v = circuit.modeler.schematic.create_component( - component_library="Sources", - component_name="VSin", - location=[2000, i * 1000], - angle=90, - ) - v_sources.append(v) - - v.parameters["Va"] = "voltage" - v.parameters["VFreq"] = "frequency" - v.parameters["Phase"] = str(i * 120) + "deg" - - g = circuit.modeler.schematic.create_gnd([2300, i * 1000], angle=90) - ground.append(g) - -# ## Connect components -# -# Connect the components by drawing wires. - -windings[2].pins[1].connect_to_component(resistors[2].pins[0], use_wire=True) -windings[1].pins[1].connect_to_component(resistors[1].pins[0], use_wire=True) -windings[0].pins[1].connect_to_component(resistors[0].pins[0], use_wire=True) - -resistors[2].pins[1].connect_to_component(v_sources[2].pins[1], use_wire=True) -resistors[1].pins[1].connect_to_component(v_sources[1].pins[1], use_wire=True) -resistors[0].pins[1].connect_to_component(v_sources[0].pins[1], use_wire=True) - -circuit.modeler.schematic.create_wire( - points=[ - resistors[2].pins[1].location, - [1200, 2500], - [-600, 2500], - [-600, 0], - windings[0].pins[0].location, - ] -) -circuit.modeler.schematic.create_wire( - points=[ - resistors[1].pins[1].location, - [1200, 1500], - [-300, 1500], - [-300, 2000], - windings[2].pins[0].location, - ] -) -circuit.modeler.schematic.create_wire( - points=[ - resistors[0].pins[1].location, - [1200, 500], - [-300, 500], - [-300, 1000], - windings[1].pins[0].location, - ] -) - -# ## Export and import netlist -# -# Export the netlist file and then import it to Maxwell 2D. - -netlist_file = os.path.join(temp_folder.name, "_netlist.sph") -circuit.export_netlist_from_schematic(netlist_file) - -m2d.edit_external_circuit( - netlist_file_path=netlist_file, schematic_design_name=circuit_name -) - -# ## Analyze setup -# - -setup.analyze(cores=NUM_CORES) - -# ## Create rectangular plot -# -# Plot winding currents - -m2d.post.create_report( - expressions=["Current(winding1)", "Current(winding2)", "Current(winding3)"], - domain="Sweep", - primary_sweep_variable="Time", - plot_name="Winding Currents", -) - -# ## Release AEDT - -m2d.save_project() -m2d.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_dir.name``. -# If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell -# removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/low_frequency/general/field_export.py b/examples/low_frequency/general/field_export.py deleted file mode 100644 index ffecb04f8..000000000 --- a/examples/low_frequency/general/field_export.py +++ /dev/null @@ -1,188 +0,0 @@ -# # Fields export in transient analysis -# -# This example shows how to leverage PyAEDT to set up a Maxwell 3D transient analysis and then -# compute the average value of the current density field over a specific coil surface -# and the magnitude of the current density field over all coil surfaces at each time step -# of the transient analysis. -# -# Keywords: **Maxwell 3D**, **transient**, **fields calculator**, **field export**. - -# ## Perform imports and define constant -# -# Perform required imports. - -import tempfile -import time - -import ansys.aedt.core - -# Define constants. - -AEDT_VERSION = "2024.2" -NUM_CORES = 4 -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name`` - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Import project -# -# The files required to run this example are downloaded into the temporary working folder. - -project_path = ansys.aedt.core.downloads.download_file( - source="maxwell_transient_fields", - name="M3D_Transient_StrandedWindings.aedt", - destination=temp_folder.name, -) - -# ## Initialize and launch Maxwell 3D -# -# Initialize and launch Maxwell 3D, providing the version and the path of the project. - -m3d = ansys.aedt.core.Maxwell3d( - project=project_path, version=AEDT_VERSION, non_graphical=NG_MODE -) - -# ## Create setup and validate -# -# Create the setup specifying general settings such as ``StopTime``, ``TimeStep``, -# and ``SaveFieldsType``. - -setup = m3d.create_setup(name="Setup1") -setup.props["StopTime"] = "0.02s" -setup.props["TimeStep"] = "0.002s" -setup.props["SaveFieldsType"] = "Every N Steps" -setup.props["N Steps"] = "2" -setup.props["Steps From"] = "0s" -setup.props["Steps To"] = "0.02s" -setup.update() - -# ## Create field expressions -# -# Create a field expression to evaluate the J field normal to a surface using the advanced fields calculator. -# The expression is created as a dictionary and then provided as an argument to the ``add_expression()`` method. - -j_normal = { - "name": "Jn", - "description": "J field normal to a surface", - "design_type": ["Maxwell 3D"], - "fields_type": ["Fields"], - "primary_sweep": "Time", - "assignment": "", - "assignment_type": [""], - "operations": [ - "NameOfExpression('')", - "Operation('Normal')", - "Operation('Dot')", - ], - "report": ["Field_3D"], -} -m3d.post.fields_calculator.add_expression(j_normal, None) - -# Calculate the average value of the J field normal using the advanced fields calculator. - -j_avg = { - "name": "Jn_avg", - "description": "Average J field normal to a surface", - "design_type": ["Maxwell 3D"], - "fields_type": ["Fields"], - "primary_sweep": "Time", - "assignment": "Coil_A2_ObjectFromFace1", - "assignment_type": [""], - "operations": [ - "NameOfExpression('Jn')", - "EnterSurface('assignment')", - "Operation('SurfaceValue')", - "Operation('Mean')", - ], - "report": ["Field_3D"], -} -m3d.post.fields_calculator.add_expression(j_avg, None) - -# ## Analyze setup specifying setup name - -m3d.analyze_setup(name=setup.name, cores=NUM_CORES) - -# ## Get available report quantities -# -# Get the available report quantities given a specific report category. -# In this case, ``Calculator Expressions`` is the category. - -report_types = m3d.post.available_report_types -quantity = m3d.post.available_report_quantities( - report_category="Fields", quantities_category="Calculator Expressions" -) - -# ## Compute time steps of the analysis -# -# Create a fields report object given the nominal sweep. -# Get the report solution data to compute the time steps of the transient analysis. - -sol = m3d.post.reports_by_category.fields(setup=m3d.nominal_sweep) -data = sol.get_solution_data() -time_steps = data.intrinsics["Time"] - -# ## Create field plots over the coil surfaces and export field data -# -# Convert each time step into millimeters. -# Create field plots over the surface of each coil by specifying the coil object, -# the quantity to plot, and the time step. -# -# The average value of the J field normal is plotted on the ``Coil_A2`` surface for every time step. -# The J field is plotted on the surface of each coil for every time-step. -# Fields data is exported to the temporary folder as an AEDTPLT file. - -for time_step in time_steps: - t = ansys.aedt.core.generic.constants.unit_converter( - time_step, - unit_system="Time", - input_units=data.units_sweeps["Time"], - output_units="ms", - ) - m3d.post.create_fieldplot_surface( - assignment=m3d.modeler.objects_by_name["Coil_A2"], - quantity=quantity[0], - plot_name="J_{}_ms".format(t), - intrinsics={"Time": "{}ms".format(t)}, - ) - mean_j_field_export = m3d.post.export_field_plot( - plot_name="J_{}_ms".format(t), - output_dir=temp_folder.name, - file_format="aedtplt", - ) - m3d.post.create_fieldplot_surface( - assignment=[ - o for o in m3d.modeler.solid_objects if o.material_name == "copper" - ], - quantity="Mag_J", - plot_name="Mag_J_Coils_{}_ms".format(t), - intrinsics={"Time": "{}ms".format(t)}, - ) - mag_j_field_export = m3d.post.export_field_plot( - plot_name="Mag_J_Coils_{}_ms".format(t), - output_dir=temp_folder.name, - file_format="aedtplt", - ) - - -# ## Release AEDT - -m3d.save_project() -m3d.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. -# If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell -# removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/low_frequency/general/index.rst b/examples/low_frequency/general/index.rst deleted file mode 100644 index e047ecd94..000000000 --- a/examples/low_frequency/general/index.rst +++ /dev/null @@ -1,130 +0,0 @@ -General -~~~~~~~ - -These examples use PyAEDT to show some general applications. - -.. grid:: 2 - - .. grid-item-card:: Control program enablement - :padding: 2 2 2 2 - :link: control_program - :link-type: doc - - .. image:: _static/control_program.png - :alt: Maxwell general - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to enable a control program in a Maxwell 2D project. - - - .. grid-item-card:: Resistance calculation - :padding: 2 2 2 2 - :link: resistance - :link-type: doc - - .. image:: _static/resistance.png - :alt: Maxwell resistance - :width: 250px - :height: 200px - :align: center - - This example uses PyAEDT to set up a resistance calculation and solve it using the Maxwell 2D DCConduction solver. - - - .. grid-item-card:: Eddy current analysis and reduced matrix - :padding: 2 2 2 2 - :link: eddy_current - :link-type: doc - - .. image:: _static/eddy_current.png - :alt: Maxwell Eddy current - :width: 250px - :height: 200px - :align: center - - This example shows how to leverage PyAEDT to assign a matrix and perform series or parallel connections in a Maxwell 2D design. - - - .. grid-item-card:: Electrostatic analysis - :padding: 2 2 2 2 - :link: electrostatic - :link-type: doc - - .. image:: _static/electrostatic.png - :alt: Maxwell electrostatic - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create a Maxwell 2D electrostatic analysis. - - - .. grid-item-card:: External delta circuit - :padding: 2 2 2 2 - :link: external_circuit - :link-type: doc - - .. image:: _static/external_circuit.png - :alt: External circuit - :width: 250px - :height: 200px - :align: center - - This example shows how to create an external delta circuit and connect it with a Maxwell 2D design. - - - .. grid-item-card:: Electro DC analysis - :padding: 2 2 2 2 - :link: dc_analysis - :link-type: doc - - .. image:: _static/dc.png - :alt: Maxwell DC - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create a Maxwell DC analysis, compute mass center, and move coordinate systems. - - - .. grid-item-card:: Fields export in transient analysis - :padding: 2 2 2 2 - :link: field_export - :link-type: doc - - .. image:: _static/field.png - :alt: Maxwell field - :width: 250px - :height: 200px - :align: center - - This example shows how to leverage PyAEDT to set up a Maxwell 3D transient analysis and then - compute the average value of the current density field over a specific coil surface and the magnitude - of the current density field over all coil surfaces at each time step of the transient analysis. - - .. grid-item-card:: Twin builder - :padding: 2 2 2 2 - :link: twin_builder/index - :link-type: doc - - .. image:: twin_builder/_static/rectifier.png - :alt: Rectifier - :width: 250px - :height: 200px - :align: center - - Twin builder examples. - - .. toctree:: - :hidden: - - control_program - resistance - eddy_current - electrostatic - external_circuit - dc_analysis - field_export - twin_builder/index diff --git a/examples/low_frequency/general/resistance.py b/examples/low_frequency/general/resistance.py deleted file mode 100644 index 6023cef0c..000000000 --- a/examples/low_frequency/general/resistance.py +++ /dev/null @@ -1,326 +0,0 @@ -# # Resistance calculation - -# This example uses PyAEDT to set up a resistance calculation -# and solve it using the Maxwell 2D DCConduction solver. -# -# Keywords: **Maxwell 2D**, **DXF import**, **material sweep**, **expression cache**. - -# ## Perform imports and define constants -# -# Perform required imports. - -import os.path -import tempfile -import time - -import ansys.aedt.core -from ansys.aedt.core.visualization.plot.pdf import AnsysReport - -# Define constants. - -AEDT_VERSION = "2024.2" -NG_MODE = False -NUM_CORES = 4 - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Launch AEDT and Maxwell 2D -# -# Launch AEDT and Maxwell 2D after first setting up the project and design names, -# the solver, and the version. The following code also creates an instance of the -# ``Maxwell2d`` class named ``m2d``. - -project_name = os.path.join(temp_folder.name, "M2D_DC_Conduction.aedt") -m2d = ansys.aedt.core.Maxwell2d( - version=AEDT_VERSION, - new_desktop=True, - close_on_exit=True, - solution_type="DCConduction", - project=project_name, - design="Ansys_resistor", - non_graphical=NG_MODE, -) - -# ## Import geometry as a DXF file -# -# You can test importing a DXF or a Parasolid file by commenting and uncommenting -# the following lines. -# Importing DXF files only works in graphical mode. - -# + -# DXFPath = ansys.aedt.core.downloads.download_file("dxf", "Ansys_logo_2D.dxf") -# dxf_layers = m2d.get_dxf_layers(DXFPath) -# m2d.import_dxf(DXFPath, dxf_layers, scale=1E-05) - -parasolid_path = ansys.aedt.core.downloads.download_file( - source="x_t", name="Ansys_logo_2D.x_t", destination=temp_folder.name -) -m2d.modeler.import_3d_cad(parasolid_path) -# - - -# ## Define variables -# -# Define the conductor thickness in the z-direction, the material array with four materials, -# and the material index referring to the material array. - -m2d["MaterialThickness"] = "5mm" -m2d["ConductorMaterial"] = '["Copper", "Aluminum", "silver", "gold"]' -material_index = 0 -m2d["MaterialIndex"] = str(material_index) -no_materials = 4 - -# ## Assign materials -# -# Voltage ports are defined as gold. The conductor -# gets the material defined by the 0th entry of the material array. - -m2d.assign_material(assignment=["ANSYS_LOGO_2D_1", "ANSYS_LOGO_2D_2"], material="gold") -m2d.modeler["ANSYS_LOGO_2D_3"].material_name = "ConductorMaterial[MaterialIndex]" - -# ## Assign voltages - -m2d.assign_voltage(assignment=["ANSYS_LOGO_2D_1"], amplitude=1, name="1V") -m2d.assign_voltage(assignment=["ANSYS_LOGO_2D_2"], amplitude=0, name="0V") - -# ## Set up conductance calculation -# -# ``1V`` is the source. ``0V`` is the ground. - -m2d.assign_matrix(assignment=["1V"], group_sources=["0V"], matrix_name="Matrix1") - -# ## Assign mesh operation -# -# Assign three millimeters as the maximum length. - -m2d.mesh.assign_length_mesh( - assignment=["ANSYS_LOGO_2D_3"], - name="conductor", - maximum_length=3, - maximum_elements=None, -) - -# ## Create simulation setup and enable expression cache -# -# Create the simulation setup with a minimum of four adaptive passes to ensure convergence. -# Enable the expression cache to observe the convergence. - -setup = m2d.create_setup(name="Setup1", MinimumPasses=4) -setup.enable_expression_cache( - report_type="DCConduction", - expressions="1/Matrix1.G(1V,1V)/MaterialThickness", - isconvergence=True, - conv_criteria=1, - use_cache_for_freq=False, -) - -# ## Analyze setup -# -# Run the analysis. - -m2d.save_project() -m2d.analyze(setup=setup.name, cores=NUM_CORES, use_auto_settings=False) - -# ## Create parametric sweep -# -# Create a parametric sweep to sweep all the entries in the material array. -# Save fields and mesh. Use the mesh for all the materials. - -sweep = m2d.parametrics.add( - variable="MaterialIndex", - start_point=0, - end_point=no_materials - 1, - step=1, - variation_type="LinearStep", - name="MaterialSweep", -) -sweep["SaveFields"] = True -sweep["CopyMesh"] = True -sweep["SolveWithCopiedMeshOnly"] = True -sweep.analyze(cores=NUM_CORES) - -# ## Output variable -# -# Define output variable. - -expression = "1/Matrix1.G(1V,1V)/MaterialThickness" -m2d.ooutput_variable.CreateOutputVariable( - "out1", expression, m2d.nominal_sweep, "DCConduction", [] -) - -# ## Create report -# -# Create a material resistance versus material index report. - -# + -variations = {"MaterialIndex": ["All"], "MaterialThickness": ["Nominal"]} -report = m2d.post.create_report( - expressions="out1", - primary_sweep_variable="MaterialIndex", - report_category="DCConduction", - plot_type="Data Table", - variations=variations, - plot_name="Resistance vs. Material", -) - -# ## Get solution data -# -# Get solution data using the ``report``` object to get resistance values -# and plot data outside AEDT. - -data = report.get_solution_data() -resistance = data.data_magnitude() -material_index = data.primary_sweep_values -data.primary_sweep = "MaterialIndex" -data.plot(snapshot_path=os.path.join(temp_folder.name, "M2D_DCConduction.jpg")) - -# ## Create material index versus resistance table -# -# Create material index versus resistance table to use in the PDF report generator. -# Create ``colors`` table to customize each row of the material index versus resistance table. - -material_index_vs_resistance = [["Material", "Resistance"]] -colors = [[(255, 255, 255), (0, 255, 0)]] -for i in range(len(data.primary_sweep_values)): - material_index_vs_resistance.append( - [str(data.primary_sweep_values[i]), str(resistance[i])] - ) - colors.append([None, None]) -# - - -# ## Overlay fields -# -# Plot the electric field and current density on the conductor surface. - -conductor_surface = m2d.modeler["ANSYS_LOGO_2D_3"].faces -plot1 = m2d.post.create_fieldplot_surface( - assignment=conductor_surface, quantity="Mag_E", plot_name="Electric Field" -) -plot2 = m2d.post.create_fieldplot_surface( - assignment=conductor_surface, quantity="Mag_J", plot_name="Current Density" -) - -# ## Overlay fields using PyVista -# -# Plot electric field using PyVista and save to an image file. - -py_vista_plot = m2d.post.plot_field( - quantity="Mag_E", assignment=conductor_surface, plot_cad_objs=False, show=False -) -py_vista_plot.isometric_view = False -py_vista_plot.camera_position = [0, 0, 7] -py_vista_plot.focal_point = [0, 0, 0] -py_vista_plot.roll_angle = 0 -py_vista_plot.elevation_angle = 0 -py_vista_plot.azimuth_angle = 0 -py_vista_plot.plot(os.path.join(temp_folder.name, "mag_E.jpg")) - -# ## Plot field animation -# -# Plot current density verus the material index. - -animated_plot = m2d.post.plot_animated_field( - quantity="Mag_J", - assignment=conductor_surface, - export_path=temp_folder.name, - variation_variable="MaterialIndex", - variations=[0, 1, 2, 3], - show=False, - export_gif=False, - log_scale=True, -) -animated_plot.isometric_view = False -animated_plot.camera_position = [0, 0, 7] -animated_plot.focal_point = [0, 0, 0] -animated_plot.roll_angle = 0 -animated_plot.elevation_angle = 0 -animated_plot.azimuth_angle = 0 -animated_plot.animate() - -# ## Export model picture - -model_picture = m2d.post.export_model_picture() - -# ## Generate PDF report -# -# Generate a PDF report with the output of the simulation. - -pdf_report = AnsysReport( - project_name=m2d.project_name, design_name=m2d.design_name, version=AEDT_VERSION -) - -# Customize the text font. - -pdf_report.report_specs.font = "times" -pdf_report.report_specs.text_font_size = 10 - -# Create the report - -pdf_report.create() - -# Add project's design information to the report. - -pdf_report.add_project_info(m2d) - -# Add the model picture in a new chapter. Then, add text. - -pdf_report.add_chapter("Model Picture") -pdf_report.add_text("This section contains the model picture.") -pdf_report.add_image(path=model_picture, caption="Model Picture", width=80, height=60) - -# Add field overlay plots in a new chapter. - -pdf_report.add_chapter("Field overlay") -pdf_report.add_sub_chapter("Plots") -pdf_report.add_text("This section contains the fields overlay.") -pdf_report.add_image( - os.path.join(temp_folder.name, "mag_E.jpg"), caption="Mag E", width=120, height=80 -) -pdf_report.add_page_break() - -# Add a new section to display results. - -pdf_report.add_section() -pdf_report.add_chapter("Results") -pdf_report.add_sub_chapter("Resistance vs. Material") -pdf_report.add_text("This section contains resistance versus material data.") -# Aspect ratio is automatically calculated if only width is provided -pdf_report.add_image(os.path.join(temp_folder.name, "M2D_DCConduction.jpg"), width=130) - -# Add a new subchapter to display resistance data from the previously created table. - -pdf_report.add_sub_chapter("Resistance data table") -pdf_report.add_text("This section contains resistance data.") -pdf_report.add_table( - title="Resistance Data", - content=material_index_vs_resistance, - formatting=colors, - col_widths=[75, 100], -) - -# Add a table of contents and save the PDF. - -pdf_report.add_toc() -pdf_report.save_pdf(temp_folder.name, "AEDT_Results.pdf") - -# ## Release AEDT - -m2d.save_project() -m2d.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. -# If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell -# removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/low_frequency/general/twin_builder/_static/dynamic_rom_plot.png b/examples/low_frequency/general/twin_builder/_static/dynamic_rom_plot.png deleted file mode 100644 index 15e4b3161..000000000 Binary files a/examples/low_frequency/general/twin_builder/_static/dynamic_rom_plot.png and /dev/null differ diff --git a/examples/low_frequency/general/twin_builder/_static/lti_rom.png b/examples/low_frequency/general/twin_builder/_static/lti_rom.png deleted file mode 100644 index e87162462..000000000 Binary files a/examples/low_frequency/general/twin_builder/_static/lti_rom.png and /dev/null differ diff --git a/examples/low_frequency/general/twin_builder/_static/rc.png b/examples/low_frequency/general/twin_builder/_static/rc.png deleted file mode 100644 index d02449273..000000000 Binary files a/examples/low_frequency/general/twin_builder/_static/rc.png and /dev/null differ diff --git a/examples/low_frequency/general/twin_builder/_static/rectifier.png b/examples/low_frequency/general/twin_builder/_static/rectifier.png deleted file mode 100644 index eebc301bb..000000000 Binary files a/examples/low_frequency/general/twin_builder/_static/rectifier.png and /dev/null differ diff --git a/examples/low_frequency/general/twin_builder/_static/rectifier_response.png b/examples/low_frequency/general/twin_builder/_static/rectifier_response.png deleted file mode 100644 index ca9487aee..000000000 Binary files a/examples/low_frequency/general/twin_builder/_static/rectifier_response.png and /dev/null differ diff --git a/examples/low_frequency/general/twin_builder/_static/static_rom.png b/examples/low_frequency/general/twin_builder/_static/static_rom.png deleted file mode 100644 index 1df47a814..000000000 Binary files a/examples/low_frequency/general/twin_builder/_static/static_rom.png and /dev/null differ diff --git a/examples/low_frequency/general/twin_builder/dynamic_rom.py b/examples/low_frequency/general/twin_builder/dynamic_rom.py deleted file mode 100644 index 2f8ffc901..000000000 --- a/examples/low_frequency/general/twin_builder/dynamic_rom.py +++ /dev/null @@ -1,212 +0,0 @@ -# # Dynamic ROM -# -# This example shows how to use PyAEDT to create a dynamic reduced order model (ROM) -# in Twin Builder and run a Twin Builder time-domain simulation. -# -# > **Note:** This example uses functionality only available in Twin -# > Builder 2023 R2 and later. -# -# Keywords: **Twin Builder**, **Dynamic ROM**. - -# ## Perform imports and define constants -# -# Perform required imports. - -import os -import shutil -import tempfile -import time - -import ansys.aedt.core -import matplotlib.pyplot as plt - -# Define constants. - -AEDT_VERSION = "2024.2" -NUM_CORES = 4 -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Set up input data -# -# Define the file name. - -source_snapshot_data_zipfilename = "Ex1_Mechanical_DynamicRom.zip" -source_build_conf_file = "dynarom_build.conf" - -# Download data from the ``example_data`` repository. - -_ = ansys.aedt.core.downloads.download_twin_builder_data( - file_name=source_snapshot_data_zipfilename, - force_download=True, - destination=temp_folder.name, -) -source_data_folder = ansys.aedt.core.downloads.download_twin_builder_data( - source_build_conf_file, True, temp_folder.name -) - -# Toggle these for local testing. - -data_folder = os.path.join(source_data_folder, "Ex03") - -# Unzip training data and config file -ansys.aedt.core.downloads.unzip( - os.path.join(source_data_folder, source_snapshot_data_zipfilename), data_folder -) -shutil.copyfile( - os.path.join(source_data_folder, source_build_conf_file), - os.path.join(data_folder, source_build_conf_file), -) - - -# ## Launch Twin Builder and build ROM component -# -# Launch Twin Builder using an implicit declaration and add a new design with -# the default setup for building the dynamic ROM component. - -project_name = os.path.join(temp_folder.name, "dynamic_rom.aedt") -tb = ansys.aedt.core.TwinBuilder( - project=project_name, - version=AEDT_VERSION, - non_graphical=NG_MODE, - new_desktop=True, -) - -# ## Configure AEDT -# -# > **Note:** Only run the following cell if AEDT is not configured to run Twin Builder. -# > -# > The following cell configures AEDT and the schematic editor -# > to use the ``Twin Builder`` configuration. -# > The dynamic ROM feature is only available with a Twin Builder license. -# > A cell at the end of this example restores the AEDT configuration. If your -# > environment is set up to use the ``Twin Builder`` configuration, you do not -# > need to run these code blocks. - -current_desktop_config = tb._odesktop.GetDesktopConfiguration() -current_schematic_environment = tb._odesktop.GetSchematicEnvironment() -tb._odesktop.SetDesktopConfiguration("Twin Builder") -tb._odesktop.SetSchematicEnvironment(1) - -# Get the dynamic ROM builder object. -rom_manager = tb._odesign.GetROMManager() -dynamic_rom_builder = rom_manager.GetDynamicROMBuilder() - -# Build the dynamic ROM with the specified configuration file. -conf_file_path = os.path.join(data_folder, source_build_conf_file) -dynamic_rom_builder.Build(conf_file_path.replace("\\", "/")) - -# Test if the ROM was created successfully -dynamic_rom_path = os.path.join(data_folder, "DynamicRom.dyn") -if os.path.exists(dynamic_rom_path): - tb._odesign.AddMessage( - "Info", "path exists: {}".format(dynamic_rom_path.replace("\\", "/")), "" - ) -else: - tb._odesign.AddMessage( - "Info", "path does not exist: {}".format(dynamic_rom_path), "" - ) - -# Create the ROM component definition in Twin Builder. -rom_manager.CreateROMComponent(dynamic_rom_path.replace("\\", "/"), "dynarom") - - -# ## Create schematic -# -# Place components to create a schematic. - -# Define the grid distance for ease in calculations. - -G = 0.00254 - -# Place a dynamic ROM component. - -rom1 = tb.modeler.schematic.create_component("ROM1", "", "dynarom", [36 * G, 28 * G]) - -# Place two excitation sources. - -source1 = tb.modeler.schematic.create_periodic_waveform_source( - None, "PULSE", 190, 0.002, "300deg", 210, 0, [20 * G, 29 * G] -) -source2 = tb.modeler.schematic.create_periodic_waveform_source( - None, "PULSE", 190, 0.002, "300deg", 210, 0, [20 * G, 25 * G] -) - -# Connect components with wires. - -tb.modeler.schematic.create_wire([[22 * G, 29 * G], [33 * G, 29 * G]]) -tb.modeler.schematic.create_wire( - [[22 * G, 25 * G], [30 * G, 25 * G], [30 * G, 28 * G], [33 * G, 28 * G]] -) - -# Zoom to fit the schematic. -tb.modeler.zoom_to_fit() - -# ## Parametrize transient setup -# -# Parametrize the default transient setup by setting the end time. - -tb.set_end_time("1000s") -tb.set_hmin("1s") -tb.set_hmax("1s") - -# ## Solve transient setup - -tb.analyze_setup("TR", cores=NUM_CORES) - - -# ## Get report data and plot using Matplotlib -# -# Get report data and plot it using Matplotlib. The following code gets and plots -# the values for the voltage on the pulse voltage source and the values for the -# output of the dynamic ROM. - -input_excitation = "PULSE1.VAL" -x = tb.post.get_solution_data(input_excitation, "TR", "Time") -plt.plot(x.intrinsics["Time"], x.data_real(input_excitation)) - -output_temperature = "ROM1.Temperature_history" -x = tb.post.get_solution_data(output_temperature, "TR", "Time") -plt.plot(x.intrinsics["Time"], x.data_real(output_temperature)) - -plt.grid() -plt.xlabel("Time") -plt.ylabel("Temperature History Variation with Input Temperature Pulse") -plt.show() - - -# ## Close Twin Builder -# -# After the simulation is completed, you can close Twin Builder or release it. -# All methods provide for saving the project before closing. - -# Clean up the downloaded data. -shutil.rmtree(source_data_folder) - -# Restore the earlier AEDT configuration and schematic environment. -tb._odesktop.SetDesktopConfiguration(current_desktop_config) -tb._odesktop.SetSchematicEnvironment(current_schematic_environment) - -# ## Release AEDT -# -# Release AEDT and close the example. - -tb.save_project() -tb.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/low_frequency/general/twin_builder/index.rst b/examples/low_frequency/general/twin_builder/index.rst deleted file mode 100644 index ed7d665b3..000000000 --- a/examples/low_frequency/general/twin_builder/index.rst +++ /dev/null @@ -1,83 +0,0 @@ -Twin Builder -~~~~~~~~~~~~ - -These examples use PyAEDT to show some Twin Builder applications. - -.. grid:: 2 - - .. grid-item-card:: RC circuit design analysis - :padding: 2 2 2 2 - :link: rc_circuit - :link-type: doc - - .. image:: _static/rc.png - :alt: TB RC - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create a Twin Builder design and run a Twin Builder time-domain simulation. - - .. grid-item-card:: Wiring of a rectifier with a capacitor filter - :padding: 2 2 2 2 - :link: rectifier - :link-type: doc - - .. image:: _static/rectifier_response.png - :alt: TB Rectifier response - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create a Twin Builder design and run a Twin Builder time-domain simulation. - - - .. grid-item-card:: Static ROM - :padding: 2 2 2 2 - :link: static_rom - :link-type: doc - - .. image:: _static/static_rom.png - :alt: Static ROM - :width: 250px - :height: 200px - :align: center - - This example shows how to create a static reduced order model (ROM) in Twin Builder and run a transient simulation. - - .. grid-item-card:: Dynamic ROM - :padding: 2 2 2 2 - :link: dynamic_rom - :link-type: doc - - .. image:: _static/dynamic_rom_plot.png - :alt: Dynamic ROM plot - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create a dynamic reduced order model (ROM) in Twin Builder and run a Twin Builder time-domain simulation. - - .. grid-item-card:: LTI ROM - :padding: 2 2 2 2 - :link: lti_rom_sml - :link-type: doc - - .. image:: _static/lti_rom.png - :alt: LTI ROM plot - :width: 250px - :height: 200px - :align: center - - This example shows how you can use PyAEDT to create a Linear Time Invariant (LTI) ROM in Twin Builder - and run a Twin Builder time-domain simulation. - - - .. toctree:: - :hidden: - - rc_circuit - rectifier - static_rom - dynamic_rom - lti_rom_sml diff --git a/examples/low_frequency/general/twin_builder/lti_rom_sml.py b/examples/low_frequency/general/twin_builder/lti_rom_sml.py deleted file mode 100644 index 9d1c12a7c..000000000 --- a/examples/low_frequency/general/twin_builder/lti_rom_sml.py +++ /dev/null @@ -1,252 +0,0 @@ -# # LTI ROM creation and simulation - -# This example shows how you can use PyAEDT to create a Linear Time Invariant (LTI) ROM in Twin Builder -# and run a Twin Builder time-domain simulation. Inputs data are defined using Datapairs blocks with CSV files. -# -# Keywords: **Twin Builder**, **LTI**, **ROM**. - -# ## Perform imports and define constants -# -# Perform required imports. - -import datetime -import os -import subprocess -import tempfile -import time - -import matplotlib.pyplot as plt -from ansys.aedt.core import TwinBuilder, downloads -from ansys.aedt.core.application.variables import CSVDataset - -# Define constants - -AEDT_VERSION = "2024.2" -NUM_CORES = 4 -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Set paths and define input files and variables -# -# Set paths. - -training_data_folder = "LTI_training_data.zip" -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") -input_dir = downloads.download_twin_builder_data( - training_data_folder, True, temp_folder.name -) - -# Download data from example_data repository - -data_folder = os.path.join(input_dir, "LTI_training") - -# Unzip training data and parse ports names - -downloads.unzip(os.path.join(input_dir, training_data_folder), data_folder) -ports_names_file = "Input_PortNames.txt" - - -# ## Get ports information from file - - -def get_ports_info(ports_file): - with open(ports_file, "r") as PortNameFile: - res = [] - line = PortNameFile.readline() - line_list = list(line.split()) - for i in range(len(line_list)): - res.append("Input" + str(i + 1) + "_" + line_list[i]) - - line = PortNameFile.readline() - line_list = list(line.split()) - for i in range(len(line_list)): - res.append("Output" + str(i + 1) + "_" + line_list[i]) - return res - - -pin_names = get_ports_info(os.path.join(data_folder, ports_names_file)) - -# ## Launch Twin Builder -# -# Launch Twin Builder using an implicit declaration and add a new design with -# the default setup. - -project_name = os.path.join(temp_folder.name, "LTI_ROM.aedt") -tb = TwinBuilder( - project=project_name, version=AEDT_VERSION, non_graphical=NG_MODE, new_desktop=True -) - -# ## Build the LTI ROM with specified configuration file - -install_dir = tb.odesktop.GetRegistryString("Desktop/InstallationDirectory") -fitting_exe = os.path.join(install_dir, "FittingTool.exe") -path = '"' + fitting_exe + '"' + " " + '"t"' + " " + '"' + data_folder + '"' -process = subprocess.Popen( - path, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE -) -tb.logger.info("Fitting the LTI ROM training data") -exec = True -startTime = datetime.datetime.now() -execTime = 0.0 -while ( - exec and execTime < 60.0 -): # limiting the fitting process execution time to 1 minute - out, err = process.communicate() - execTime = (datetime.datetime.now() - startTime).total_seconds() - if "An LTI ROM has been generated" in str(out): - process.terminate() - exec = False - -rom_file = "" -model_name_sml = "" - -for i in os.listdir(data_folder): - if i.endswith(".sml"): - model_name_sml = i.split(".")[0] - rom_file = os.path.join(data_folder, i) - -if os.path.exists(rom_file): - tb.logger.info("Built intermediate ROM file successfully at: %s", rom_file) -else: - tb.logger.info("ROM file does not exist at the expected location : %s", rom_file) - - -# ## Import the ROM component model - -is_created = tb.modeler.schematic.create_component_from_sml( - input_file=rom_file, model=model_name_sml, pins_names=pin_names -) -os.remove(rom_file) -tb.logger.info("LTI ROM model successfully imported.") - -# ## Import the ROM component model in Twin Builder -# -# Place components to create a schematic. - -# Define the grid distance for ease in calculations - -grid_distance = 0.00254 - -# Place the ROM component - -rom1 = tb.modeler.schematic.create_component( - "ROM1", "", model_name_sml, [36 * grid_distance, 28 * grid_distance] -) - -# Place datapairs blocks for inputs definition - -source1 = tb.modeler.schematic.create_component( - "source1", - "", - "Simplorer Elements\\Basic Elements\\Tools\\Time Functions:DATAPAIRS", - [20 * grid_distance, 29 * grid_distance], -) -source2 = tb.modeler.schematic.create_component( - "source2", - "", - "Simplorer Elements\\Basic Elements\\Tools\\Time Functions:DATAPAIRS", - [20 * grid_distance, 25 * grid_distance], -) - -# Import Datasets - -data1 = CSVDataset(os.path.join(data_folder, "data1.csv")) -data2 = CSVDataset(os.path.join(data_folder, "data2.csv")) -dataset1 = tb.create_dataset("data1", data1.data["time"], data1.data["input1"]) -dataset2 = tb.create_dataset("data2", data2.data["time"], data2.data["input2"]) - -source1.parameters["CH_DATA"] = dataset1.name -source2.parameters["CH_DATA"] = dataset2.name - -tb.modeler.schematic.update_quantity_value(source1.composed_name, "PERIO", "0") - -tb.modeler.schematic.update_quantity_value( - source1.composed_name, "TPERIO", "Tend+1", "s" -) - -tb.modeler.schematic.update_quantity_value(source2.composed_name, "PERIO", "0") - -tb.modeler.schematic.update_quantity_value( - source2.composed_name, "TPERIO", "Tend+1", "s" -) - -# Connect components with wires - -tb.modeler.schematic.create_wire( - points=[source1.pins[0].location, rom1.pins[0].location] -) -tb.modeler.schematic.create_wire( - points=[source2.pins[0].location, rom1.pins[1].location] -) - -# Zoom to fit the schematic - -tb.modeler.zoom_to_fit() - -# ## Parametrize transient setup -# -# Parametrize the default transient setup by setting the end time and minimum/maximum time steps. - -tb.set_end_time("700s") -tb.set_hmin("0.001s") -tb.set_hmax("1s") - -# ## Solve transient setup -# -# Solve the transient setup. - -tb.analyze_setup("TR") - -# ## Get report data and plot using Matplotlib -# -# Get report data and plot it using Matplotlib. The following code gets and plots -# the values for the inputs and outputs of the LTI ROM. - -# Units used are based on AEDT default units. - -variables_postprocessing = [] -pin_names_str = ",".join(pin_names) -rom_pins = pin_names_str.lower().split(",") -fig, ax = plt.subplots(ncols=1, nrows=2, figsize=(18, 7)) -fig.subplots_adjust(hspace=0.5) - -for i in range(0, 2): - variable = "ROM1." + rom_pins[i] - x = tb.post.get_solution_data(variable, "TR", "Time") - ax[0].plot( - [el for el in x.intrinsics["Time"]], x.data_real(variable), label=variable - ) - -ax[0].set_title("ROM inputs") -ax[0].legend(loc="upper left") - -for i in range(2, 4): - variable = "ROM1." + rom_pins[i] - x = tb.post.get_solution_data(variable, "TR", "Time") - ax[1].plot( - [el for el in x.intrinsics["Time"]], x.data_real(variable), label=variable - ) - -ax[1].set_title("ROM outputs") -ax[1].legend(loc="upper left") - -# Show plot - -plt.show() - -# ## Release AEDT -# -# Release AEDT and close the example. - -tb.save_project() -tb.release_desktop() - -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. - -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/low_frequency/general/twin_builder/rc_circuit.py b/examples/low_frequency/general/twin_builder/rc_circuit.py deleted file mode 100644 index a369e0a1e..000000000 --- a/examples/low_frequency/general/twin_builder/rc_circuit.py +++ /dev/null @@ -1,108 +0,0 @@ -# # RC circuit design analysis -# -# This example shows how to use PyAEDT to create a Twin Builder design -# and run a Twin Builder time-domain simulation. -# -# Keywords: **Twin Builder**, **RC**. - -# ## Perform imports and define constantss -# -# Perform required imports. - -import os -import tempfile -import time - -import ansys.aedt.core - -# Define constants. - -AEDT_VERSION = "2024.2" -NUM_CORES = 4 -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Launch Twin Builder -# -# Launch Twin Builder using an implicit declaration and add a new design with -# a default setup. - -project_name = os.path.join(temp_folder.name, "rc_circuit.aedt") -tb = ansys.aedt.core.TwinBuilder( - project=project_name, - version=AEDT_VERSION, - non_graphical=NG_MODE, - new_desktop=True, -) -tb.modeler.schematic_units = "mil" - -# ## Create components for RC circuit -# -# Create components for an RC circuit driven by a pulse voltage source. -# Create components, such as a voltage source, resistor, and capacitor. - -source = tb.modeler.schematic.create_voltage_source("E1", "EPULSE", 10, 10, [0, 0]) -resistor = tb.modeler.schematic.create_resistor("R1", 10000, [1000, 1000], 90) -capacitor = tb.modeler.schematic.create_capacitor("C1", 1e-6, [2000, 0]) - -# ## Create ground -# -# Create a ground, which is needed for an analog analysis. - -gnd = tb.modeler.components.create_gnd([0, -1000]) - -# ## Connect components -# -# Connects components with pins. - -source.pins[1].connect_to_component(resistor.pins[0]) -resistor.pins[1].connect_to_component(capacitor.pins[0]) -capacitor.pins[1].connect_to_component(source.pins[0]) -source.pins[0].connect_to_component(gnd.pins[0]) - -# ## Parametrize transient setup -# -# Parametrize the default transient setup by setting the end time. - -tb.set_end_time("300ms") - -# ## Solve transient setup - -tb.analyze_setup("TR") - - -# ## Get report data and plot using Matplotlib -# -# Get report data and plot it using Matplotlib. The following code gets and plots -# the values for the voltage on the pulse voltage source and the values for the -# voltage on the capacitor in the RC circuit. - -E_Value = "E1.V" -C_Value = "C1.V" - -x = tb.post.get_solution_data([E_Value, C_Value], "TR", "Time") -x.plot([E_Value, C_Value], x_label="Time", y_label="Capacitor Voltage vs Input Pulse") - -# ## Release AEDT -# -# Release AEDT and close the example. - -tb.save_project() -tb.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/low_frequency/general/twin_builder/rectifier.py b/examples/low_frequency/general/twin_builder/rectifier.py deleted file mode 100644 index 508a1792e..000000000 --- a/examples/low_frequency/general/twin_builder/rectifier.py +++ /dev/null @@ -1,188 +0,0 @@ -# # Wiring of a rectifier with a capacitor filter -# -# This example shows how to use PyAEDT to create a Twin Builder design -# and run a Twin Builder time-domain simulation. -# -# -# -# Keywords: **Twin Builder**, **rectifier**, **filter**. - -# ## Perform imports and define constants -# -# Perform required imports. - -import os -import tempfile -import time - -import ansys.aedt.core -import matplotlib.pyplot as plt - -# Define constants. - -AEDT_VERSION = "2024.2" -NUM_CORES = 4 -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Launch Twin Builder -# -# Launch Twin Builder using an implicit declaration and add a new design with -# the default setup. - -project_name = os.path.join(temp_folder.name, "TB_Rectifier_Demo.aedt") -tb = ansys.aedt.core.TwinBuilder( - project=project_name, - version=AEDT_VERSION, - non_graphical=NG_MODE, - new_desktop=True, -) - -# ## Create components -# -# Place components for a bridge rectifier and a capacitor filter in the schematic editor. -# -# Specify the grid spacing to use for placement -# of components in the schematic editor. Components are placed using the named -# argument ``location`` as a list of ``[x, y]`` values in millimeters. - -G = 0.00254 - -# Create an AC sinosoidal voltage source. - -source = tb.modeler.schematic.create_voltage_source( - "V_AC", "ESINE", 100, 50, location=[-1 * G, 0] -) - -# Place the four diodes of the bridge rectifier. The named argument ``angle`` is the rotation angle -# of the component in radians. - -diode1 = tb.modeler.schematic.create_diode( - name="D1", location=[10 * G, 6 * G], angle=270 -) -diode2 = tb.modeler.schematic.create_diode( - name="D2", location=[20 * G, 6 * G], angle=270 -) -diode3 = tb.modeler.schematic.create_diode( - name="D3", location=[10 * G, -4 * G], angle=270 -) -diode4 = tb.modeler.schematic.create_diode( - name="D4", location=[20 * G, -4 * G], angle=270 -) - -# Place a capacitor filter. - -capacitor = tb.modeler.schematic.create_capacitor( - name="C_FILTER", value=1e-6, location=[29 * G, -10 * G] -) - -# Place a load resistor. - -resistor = tb.modeler.schematic.create_resistor( - name="RL", value=100000, location=[39 * G, -10 * G] -) - -# Place the ground component. - -gnd = tb.modeler.components.create_gnd(location=[5 * G, -16 * G]) - -# ## Connect components -# -# Connect components with wires, and connect the diode pins to create the bridge. - -tb.modeler.schematic.create_wire( - points=[diode1.pins[0].location, diode3.pins[0].location] -) -tb.modeler.schematic.create_wire( - points=[diode2.pins[1].location, diode4.pins[1].location] -) -tb.modeler.schematic.create_wire( - points=[diode1.pins[1].location, diode2.pins[0].location] -) -tb.modeler.schematic.create_wire( - points=[diode3.pins[1].location, diode4.pins[0].location] -) - -# Connect the voltage source to the bridge. - -tb.modeler.schematic.create_wire( - points=[source.pins[1].location, [0, 10 * G], [15 * G, 10 * G], [15 * G, 5 * G]] -) -tb.modeler.schematic.create_wire( - points=[source.pins[0].location, [0, -10 * G], [15 * G, -10 * G], [15 * G, -5 * G]] -) - -# Connect the filter capacitor and load resistor. - -tb.modeler.schematic.create_wire( - points=[resistor.pins[0].location, [40 * G, 0], [22 * G, 0]] -) -tb.modeler.schematic.create_wire(points=[capacitor.pins[0].location, [30 * G, 0]]) - -# Add the ground connection. - -tb.modeler.schematic.create_wire( - points=[resistor.pins[1].location, [40 * G, -15 * G], gnd.pins[0].location] -) -tb.modeler.schematic.create_wire(points=[capacitor.pins[1].location, [30 * G, -15 * G]]) -tb.modeler.schematic.create_wire(points=[gnd.pins[0].location, [5 * G, 0], [8 * G, 0]]) - -# Zoom to fit the schematic -tb.modeler.zoom_to_fit() - -# The circuit schematic should now be visible in the Twin Builder -# schematic editor and look like -# the image shown at the beginning of the example. -# -# ## Run the simulation -# -# Update the total time to be simulated and run the analysis. - -tb.set_end_time("100ms") -tb.analyze_setup("TR") - -# ## Get report data and plot using Matplotlib -# -# Get report data and plot it using Matplotlib. The following code gets and plots -# the values for the voltage on the pulse voltage source and the values for the -# voltage on the capacitor in the RC circuit. - -src_name = source.InstanceName + ".V" -x = tb.post.get_solution_data(src_name, "TR", "Time") -plt.plot(x.intrinsics["Time"], x.data_real(src_name)) -plt.grid() -plt.xlabel("Time") -plt.ylabel("AC Voltage") -plt.show() - -r_voltage = resistor.InstanceName + ".V" -x = tb.post.get_solution_data(r_voltage, "TR", "Time") -plt.plot(x.intrinsics["Time"], x.data_real(r_voltage)) -plt.grid() -plt.xlabel("Time") -plt.ylabel("AC to DC Conversion using Rectifier") -plt.show() - -# ## Release AEDT -# -# Release AEDT and close the example. - -tb.save_project() -tb.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/low_frequency/general/twin_builder/static_rom.py b/examples/low_frequency/general/twin_builder/static_rom.py deleted file mode 100644 index 4dec1fcec..000000000 --- a/examples/low_frequency/general/twin_builder/static_rom.py +++ /dev/null @@ -1,228 +0,0 @@ -# # Static ROM -# -# This example shows how to create a static reduced order model (ROM) -# in Twin Builder and run a transient simulation. -# -# > **Note:** This example uses functionality only available in Twin Builder 2024 R2 and later. -# -# Keywords: **Twin Builder**, **Static ROM**. - -# ## Perform imports and define constants -# -# Perform required imports. - -import os -import shutil -import tempfile -import time - -from ansys.aedt.core import TwinBuilder, downloads - -# Define constants. - -AEDT_VERSION = "2024.2" -NUM_CORES = 4 -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Set up input data -# -# The following files are downloaded along with the -# other project data used to run this example. - -source_snapshot_data_zipfilename = "Ex1_Fluent_StaticRom.zip" -source_build_conf_file = "SROMbuild.conf" -source_props_conf_file = "SROM_props.conf" - -# ## Download example data -# -# The following cell downloads the required files needed to run this example and -# extracts them in a local folder named ``"Ex04"``. - -# + -_ = downloads.download_twin_builder_data( - file_name=source_snapshot_data_zipfilename, - force_download=True, - destination=temp_folder.name, -) - -_ = downloads.download_twin_builder_data(source_build_conf_file, True, temp_folder.name) -source_data_folder = downloads.download_twin_builder_data( - source_props_conf_file, True, temp_folder.name -) - -# Target folder to extract project files. -data_folder = os.path.join(source_data_folder, "Ex04") - -# Unzip training data and config file -downloads.unzip( - os.path.join(source_data_folder, source_snapshot_data_zipfilename), data_folder -) -shutil.copyfile( - os.path.join(source_data_folder, source_build_conf_file), - os.path.join(data_folder, source_build_conf_file), -) -shutil.copyfile( - os.path.join(source_data_folder, source_props_conf_file), - os.path.join(data_folder, source_props_conf_file), -) -# - - -# ## Launch Twin Builder and build ROM component -# -# Launch Twin Builder using an implicit declaration and add a new design with -# the default setup for building the static ROM component. - -project_name = os.path.join(temp_folder.name, "static_rom.aedt") -tb = TwinBuilder( - project=project_name, - version=AEDT_VERSION, - non_graphical=NG_MODE, - new_desktop=True, -) - -# ## Configure AEDT -# -# > **Note:** Only run the following cell if AEDT is not configured to run Twin Builder. -# > -# > The following cell configures AEDT and the schematic editor -# > to use the ``Twin Builder`` configuration. -# > The Static ROM feature is only available with a Twin Builder license. -# > A cell at the end of this example restores the AEDT configuration. If your -# > environment is set up to use the ``Twin Builder`` configuration, you do not -# > need to run these sections. - -current_desktop_config = tb._odesktop.GetDesktopConfiguration() -current_schematic_environment = tb._odesktop.GetSchematicEnvironment() -tb._odesktop.SetDesktopConfiguration("Twin Builder") -tb._odesktop.SetSchematicEnvironment(1) - -# + -# Get the static ROM builder object. -rom_manager = tb._odesign.GetROMManager() -static_rom_builder = rom_manager.GetStaticROMBuilder() - -# Build the static ROM with the specified configuration file -confpath = os.path.join(data_folder, source_build_conf_file) -static_rom_builder.Build(confpath.replace("\\", "/")) - -# Test if the ROM was created successfully. -static_rom_path = os.path.join(data_folder, "StaticRom.rom") -if os.path.exists(static_rom_path): - tb.logger.info("Built intermediate rom file successfully at: %s", static_rom_path) -else: - tb.logger.error("Intermediate rom file not found at: %s", static_rom_path) - -# Create the ROM component definition in Twin Builder. -rom_manager.CreateROMComponent(static_rom_path.replace("\\", "/"), "staticrom") -# - - -# ## Create schematic -# -# Place components to create the schematic. - -# + -# Define the grid distance for ease in calculations. -G = 0.00254 - -# Place a dynamic ROM component. -rom1 = tb.modeler.schematic.create_component("ROM1", "", "staticrom", [40 * G, 25 * G]) - -# Place two excitation sources. -source1 = tb.modeler.schematic.create_periodic_waveform_source( - None, "SINE", 2.5, 0.01, 0, 7.5, 0, [20 * G, 29 * G] -) -source2 = tb.modeler.schematic.create_periodic_waveform_source( - None, "SINE", 50, 0.02, 0, 450, 0, [20 * G, 25 * G] -) -# - - -# Connect components with wires. - -tb.modeler.schematic.create_wire([[22 * G, 29 * G], [33 * G, 29 * G]]) -tb.modeler.schematic.create_wire( - [[22 * G, 25 * G], [30 * G, 25 * G], [30 * G, 28 * G], [33 * G, 28 * G]] -) - -# Enable storage of views. - -rom1.set_property("store_snapshots", 1) -rom1.set_property("view1_storage_period", "10s") -rom1.set_property("view2_storage_period", "10s") - -# Zoom to fit the schematic -tb.modeler.zoom_to_fit() - -# ## Parametrize transient setup -# -# Parametrize the default transient setup by setting the end time. - -tb.set_end_time("300s") -tb.set_hmin("1s") -tb.set_hmax("1s") - -# ## Solve transient setup -# -# Solve the transient setup. Skipping this step in case the documentation is being built. - -# > **Note:** The following code can be uncommented. -# -# tb.analyze_setup("TR") - -# ## Get report data and plot using Matplotlib -# -# Get report data and plot it using Matplotlib. The following code gets and plots -# the values for the voltage on the pulse voltage source and the values for the -# output of the dynamic ROM. - -# > **Note:** The following code can be uncommented, but it depends on the previous commented code. -# -# e_value = "ROM1.outfield_mode_1" -# x = tb.post.get_solution_data(e_value, "TR", "Time") -# x.plot() -# e_value = "ROM1.outfield_mode_2" -# x = tb.post.get_solution_data(e_value, "TR", "Time") -# x.plot() -# e_value = "SINE1.VAL" -# x = tb.post.get_solution_data(e_value, "TR", "Time") -# x.plot() -# e_value = "SINE2.VAL" -# x = tb.post.get_solution_data(e_value, "TR", "Time") -# x.plot() - - -# ## Close Twin Builder -# -# After the simulation is completed, either close Twin Builder or release it. -# All methods provide for saving the project before closing. - -# Clean up the downloaded data. -shutil.rmtree(source_data_folder) - -# Restore earlier desktop configuration and schematic environment. -tb._odesktop.SetDesktopConfiguration(current_desktop_config) -tb._odesktop.SetSchematicEnvironment(current_schematic_environment) - -# ## Release AEDT -# -# Release AEDT and close the example. - -tb.save_project() -tb.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/low_frequency/index.rst b/examples/low_frequency/index.rst deleted file mode 100644 index 1e47fea45..000000000 --- a/examples/low_frequency/index.rst +++ /dev/null @@ -1,95 +0,0 @@ -Low frequency -============= - -These end-to-end examples show how to use PyAEDT for low-frequency applications. - - -.. grid:: 2 - - .. grid-item-card:: General - :padding: 2 2 2 2 - :link: general/index - :link-type: doc - - .. image:: _static/general.png - :alt: Maxwell general - :width: 250px - :height: 200px - :align: center - - General examples - - .. grid-item-card:: Motor - :padding: 2 2 2 2 - :link: motor/index - :link-type: doc - - .. image:: _static/motor_maxwell.png - :alt: PCB - :width: 250px - :height: 200px - :align: center - - Motor examples - - .. grid-item-card:: Magnetics - :padding: 2 2 2 2 - :link: magnetic/index - :link-type: doc - - .. image:: _static/magnetic.png - :alt: Filter - :width: 250px - :height: 200px - :align: center - - Magnetics examples - - .. grid-item-card:: T.E.A.M - :padding: 2 2 2 2 - :link: team_problem/index - :link-type: doc - - .. image:: _static/TEAM.png - :alt: Filter - :width: 250px - :height: 200px - :align: center - - T.E.A.M. problems set by COMPUMAG - - .. grid-item-card:: Multiphysics - :padding: 2 2 2 2 - :link: multiphysics/index - :link-type: doc - - .. image:: _static/CFD_coil.png - :alt: Stress PCB - :width: 250px - :height: 200px - :align: center - - Multiphysics examples - - .. grid-item-card:: Report - :padding: 2 2 2 2 - :link: ../aedt_general/report/index - :link-type: doc - - .. image:: ../aedt_general/_static/touchstone.png - :alt: Components - :width: 250px - :height: 200px - :align: center - - These examples use PyAEDT to show some report capabilities. - - .. toctree:: - :hidden: - - general/index - motor/index - magnetic/index - team_problem/index - multiphysics/index - ../aedt_general/report/index diff --git a/examples/low_frequency/magnetic/_static/choke.png b/examples/low_frequency/magnetic/_static/choke.png deleted file mode 100644 index 925749435..000000000 Binary files a/examples/low_frequency/magnetic/_static/choke.png and /dev/null differ diff --git a/examples/low_frequency/magnetic/_static/lorentz_actuator.png b/examples/low_frequency/magnetic/_static/lorentz_actuator.png deleted file mode 100644 index f6be0c6a7..000000000 Binary files a/examples/low_frequency/magnetic/_static/lorentz_actuator.png and /dev/null differ diff --git a/examples/low_frequency/magnetic/_static/magneto.png b/examples/low_frequency/magnetic/_static/magneto.png deleted file mode 100644 index 3e6889ce5..000000000 Binary files a/examples/low_frequency/magnetic/_static/magneto.png and /dev/null differ diff --git a/examples/low_frequency/magnetic/_static/transient.png b/examples/low_frequency/magnetic/_static/transient.png deleted file mode 100644 index 3d6b48bb7..000000000 Binary files a/examples/low_frequency/magnetic/_static/transient.png and /dev/null differ diff --git a/examples/low_frequency/magnetic/choke.py b/examples/low_frequency/magnetic/choke.py deleted file mode 100644 index 7640f72ec..000000000 --- a/examples/low_frequency/magnetic/choke.py +++ /dev/null @@ -1,274 +0,0 @@ -# # Choke setup -# -# This example shows how to use PyAEDT to create a choke setup in Maxwell 3D. -# -# Keywords: **Maxwell 3D**, **choke**. - -# ## Perform imports and define constants -# -# Perform required imports. - -import json -import os -import tempfile -import time - -import ansys.aedt.core - -# Define constants. - -AEDT_VERSION = "2024.2" -NG_MODE = False # Open AEDT UI when it is launched. - - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name`` - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Launch Maxwell3D -# -# Launch Maxwell 3D 2024 R2 in graphical mode. - -project_name = os.path.join(temp_folder.name, "choke.aedt") -m3d = ansys.aedt.core.Maxwell3d( - project=project_name, - solution_type="EddyCurrent", - version=AEDT_VERSION, - non_graphical=NG_MODE, - new_desktop=True, -) - -# ## Define parameters -# -# The dictionary values contain the different parameter values of the core and -# the windings that compose the choke. You must not change the main structure of -# the dictionary. The dictionary has many primary keys, including -# ``"Number of Windings"``, ``"Layer"``, and ``"Layer Type"``, that have -# dictionaries as values. The keys of these dictionaries are secondary keys -# of the dictionary values, such as ``"1"``, ``"2"``, ``"3"``, ``"4"``, and -# ``"Simple"``. -# -# You must not modify the primary or secondary keys. You can modify only their values. -# You must not change the data types for these keys. For the dictionaries from -# ``"Number of Windings"`` through ``"Wire Section"``, values must be Boolean. Only -# one value per dictionary can be ``True``. If all values are ``True``, only the first one -# remains set to ``True``. If all values are ``False``, the first value is chosen as the -# correct one by default. For the dictionaries from ``"Core"`` through ``"Inner Winding"``, -# values must be strings, floats, or integers. -# -# Descriptions follow for the primary keys: -# -# - ``"Number of Windings"``: Number of windings around the core. -# - ``"Layer"``: Number of layers of all windings. -# - ``"Layer Type"``: Whether layers of a winding are linked to each other -# - ``"Similar Layer"``: Whether layers of a winding have the same number of turns and -# same spacing between turns. -# - ``"Mode"``: When there are only two windows, whether they are in common or differential mode. -# - ``"Wire Section"``: Type of wire section and number of segments. -# - ``"Core"``: Design of the core. -# - ``"Outer Winding"``: Design of the first layer or outer layer of a winding and the common -# parameters for all layers. -# - ``"Mid Winding"``: Turns and turns spacing (``Coil Pit``) for the second or -# mid layer if it is necessary. -# - ``"Inner Winding"``: Turns and turns spacing (``Coil Pit``) for the third or inner -# layer if it is necessary. -# - ``"Occupation(%)"``: An informative parameter that is useless to modify. -# -# The following parameter values work. You can modify them if you want. - -values = { - "Number of Windings": {"1": False, "2": False, "3": True, "4": False}, - "Layer": {"Simple": False, "Double": False, "Triple": True}, - "Layer Type": {"Separate": False, "Linked": True}, - "Similar Layer": {"Similar": False, "Different": True}, - "Mode": {"Differential": True, "Common": False}, - "Wire Section": {"None": False, "Hexagon": False, "Octagon": True, "Circle": False}, - "Core": { - "Name": "Core", - "Material": "ferrite", - "Inner Radius": 100, - "Outer Radius": 143, - "Height": 25, - "Chamfer": 0.8, - }, - "Outer Winding": { - "Name": "Winding", - "Material": "copper", - "Inner Radius": 100, - "Outer Radius": 143, - "Height": 25, - "Wire Diameter": 5, - "Turns": 2, - "Coil Pit(deg)": 4, - "Occupation(%)": 0, - }, - "Mid Winding": {"Turns": 7, "Coil Pit(deg)": 4, "Occupation(%)": 0}, - "Inner Winding": {"Turns": 10, "Coil Pit(deg)": 4, "Occupation(%)": 0}, -} - -# ## Convert dictionary to JSON file -# -# Convert the dictionary to a JSON file. PyAEDT methods ask for the path of the -# JSON file as an argument. You can convert a dictionary to a JSON file. - -# + -json_path = os.path.join(temp_folder.name, "choke_example.json") - -with open(json_path, "w") as outfile: - json.dump(values, outfile) -# - - -# ## Verify parameters of JSON file -# -# Verify parameters of the JSON file. The ``check_choke_values()`` method takes -# the JSON file path as an argument and does the following: -# -# - Checks if the JSON file is correctly written (as explained earlier) -# - Checks equations on windings parameters to avoid having unintended intersections - -dictionary_values = m3d.modeler.check_choke_values( - input_dir=json_path, create_another_file=False -) -print(dictionary_values) - -# ## Create choke -# -# Create the choke. The ``create_choke()`` method takes the JSON file path as an -# argument. - -list_object = m3d.modeler.create_choke(input_file=json_path) -print(list_object) -core = list_object[1] -first_winding_list = list_object[2] -second_winding_list = list_object[3] -third_winding_list = list_object[4] - -# ## Assign excitations - -first_winding_faces = m3d.modeler.get_object_faces( - assignment=first_winding_list[0].name -) -second_winding_faces = m3d.modeler.get_object_faces( - assignment=second_winding_list[0].name -) -third_winding_faces = m3d.modeler.get_object_faces( - assignment=third_winding_list[0].name -) -m3d.assign_current( - assignment=[first_winding_faces[-1]], - amplitude=1000, - phase="0deg", - swap_direction=False, - name="phase_1_in", -) -m3d.assign_current( - assignment=[first_winding_faces[-2]], - amplitude=1000, - phase="0deg", - swap_direction=True, - name="phase_1_out", -) -m3d.assign_current( - assignment=[second_winding_faces[-1]], - amplitude=1000, - phase="120deg", - swap_direction=False, - name="phase_2_in", -) -m3d.assign_current( - assignment=[second_winding_faces[-2]], - amplitude=1000, - phase="120deg", - swap_direction=True, - name="phase_2_out", -) -m3d.assign_current( - assignment=[third_winding_faces[-1]], - amplitude=1000, - phase="240deg", - swap_direction=False, - name="phase_3_in", -) -m3d.assign_current( - assignment=[third_winding_faces[-2]], - amplitude=1000, - phase="240deg", - swap_direction=True, - name="phase_3_out", -) - -# ## Assign matrix - -m3d.assign_matrix( - assignment=["phase_1_in", "phase_2_in", "phase_3_in"], matrix_name="current_matrix" -) - -# ## Create mesh operation - -mesh = m3d.mesh -mesh.assign_skin_depth( - assignment=[first_winding_list[0], second_winding_list[0], third_winding_list[0]], - skin_depth=0.20, - triangulation_max_length="10mm", - name="skin_depth", -) -mesh.assign_surface_mesh_manual( - assignment=[first_winding_list[0], second_winding_list[0], third_winding_list[0]], - surface_deviation=None, - normal_dev="30deg", - name="surface_approx", -) - -# ## Create boundaries -# -# Create the boundaries. A region with openings is needed to run the analysis. - -region = m3d.modeler.create_air_region( - x_pos=100, y_pos=100, z_pos=100, x_neg=100, y_neg=100, z_neg=0 -) - -# ## Create setup -# -# Create a setup with a sweep to run the simulation. Depending on your machine's -# computing power, the simulation can take some time to run. - -setup = m3d.create_setup("MySetup") -print(setup.props) -setup.props["Frequency"] = "100kHz" -setup.props["PercentRefinement"] = 15 -setup.props["MaximumPasses"] = 10 -setup.props["HasSweepSetup"] = True -setup.add_eddy_current_sweep( - range_type="LinearCount", start=100, end=1000, count=12, units="kHz", clear=True -) - -# ## Save project - -m3d.save_project() -m3d.modeler.fit_all() -m3d.plot( - show=False, - output_file=os.path.join(temp_folder.name, "Image.jpg"), - plot_air_objects=True, -) - -# ## Release AEDT - -m3d.save_project() -m3d.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. -# If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell -# removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/low_frequency/magnetic/index.rst b/examples/low_frequency/magnetic/index.rst deleted file mode 100644 index 5bbf88c65..000000000 --- a/examples/low_frequency/magnetic/index.rst +++ /dev/null @@ -1,68 +0,0 @@ -Magnetics -~~~~~~~~~ - -These examples use PyAEDT to show some magnetics applications. - -.. grid:: 2 - - .. grid-item-card:: Transient winding analysis - :padding: 2 2 2 2 - :link: transient_winding - :link-type: doc - - .. image:: _static/transient.png - :alt: Maxwell transient - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create a project in Maxwell 2D and run a transient simulation. - - .. grid-item-card:: Choke setup - :padding: 2 2 2 2 - :link: choke - :link-type: doc - - .. image:: _static/choke.png - :alt: Maxwell choke - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create a choke setup in Maxwell 3D. - - - .. grid-item-card:: Magnetomotive force - :padding: 2 2 2 2 - :link: magneto_motive_line - :link-type: doc - - .. image:: _static/magneto.png - :alt: Maxwell magneto force - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to calculate the magnetomotive force. - - - .. grid-item-card:: Lorentz actuator - :padding: 2 2 2 2 - :link: lorentz_actuator - :link-type: doc - - .. image:: _static/lorentz_actuator.png - :alt: Maxwell general - :width: 250px - :height: 200px - :align: center - - This example uses PyAEDT to set up a Lorentz actuator and solve it using the Maxwell 2D transient solver. - - .. toctree:: - :hidden: - - transient_winding - choke - magneto_motive_line - lorentz_actuator diff --git a/examples/low_frequency/magnetic/lorentz_actuator.py b/examples/low_frequency/magnetic/lorentz_actuator.py deleted file mode 100644 index 28d7a1a5a..000000000 --- a/examples/low_frequency/magnetic/lorentz_actuator.py +++ /dev/null @@ -1,324 +0,0 @@ -# # Lorentz actuator -# -# This example uses PyAEDT to set up a Lorentz actuator -# and solve it using the Maxwell 2D transient solver. -# -# Keywords: **Maxwell2D**, **transient**, **translational motion**, **mechanical transient** - -# ## Perform imports and define constantss -# -# Perform required imports. - -import os -import tempfile -import time - -import ansys.aedt.core - -# Define constants. - -AEDT_VERSION = "2024.2" -NUM_CORES = 4 -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Initialize dictionaries -# -# Initialize the following: -# -# - Electric and geometric parameters for the actuator -# - Simulation specifications -# - Materials for the actuator component - -dimensions = { - "Core_outer_x": "100mm", - "Core_outer_y": "80mm", - "Core_thickness": "10mm", - "Magnet_thickness": "10mm", - "Coil_width": "30mm", - "Coil_thickness": "5mm", - "Coil_inner_diameter": "20mm", - "Coil_magnet_distance": "5mm", - "Coil_start_position": "3mm", - "Band_clearance": "1mm", -} - -coil_specifications = { - "Winding_current": "5A", - "No_of_turns": "100", - "Coil_mass": "0.2kg", -} - -simulation_specifications = { - "Mesh_bands": "0.5mm", - "Mesh_other_objects": "2mm", - "Stop_time": "10ms", - "Time_step": "0.5ms", - "Save_fields_interval": "1", -} - -materials = { - "Coil_material": "copper", - "Core_material": "steel_1008", - "Magnet_material": "NdFe30", -} - -# ## Launch AEDT and Maxwell 2D -# -# Launch AEDT and Maxwell 2D after first setting up the project name. -# The following code also creates an instance of the -# ``Maxwell2d`` class named ``m2d`` by providing -# the project name, the design name, the solver, the version, and the graphical mode. - -project_name = os.path.join(temp_folder.name, "Lorentz_actuator.aedt") -m2d = ansys.aedt.core.Maxwell2d( - project=project_name, - design="1 transient 2D", - solution_type="TransientXY", - version=AEDT_VERSION, - non_graphical=NG_MODE, -) - -# ## Define variables from dictionaries -# -# Define design variables from the created dictionaries. - -m2d.variable_manager.set_variable(name="Dimensions") -for k, v in dimensions.items(): - m2d[k] = v - -m2d.variable_manager.set_variable(name="Winding data") -for k, v in coil_specifications.items(): - m2d[k] = v - -m2d.variable_manager.set_variable(name="Simulation data") -for k, v in simulation_specifications.items(): - m2d[k] = v - -# Definem materials. - -m2d.variable_manager.set_variable(name="Material data") -m2d.logger.clear_messages() -for i, key in enumerate(materials.keys()): - if key == "Coil_material": - coil_mat_index = i - elif key == "Core_material": - core_mat_index = i - elif key == "Magnet_material": - magnet_mat_index = i -material_array = [] -for k, v in materials.items(): - material_array.append('"' + v + '"') -s = ", ".join(material_array) -m2d["Materials"] = "[{}]".format(s) - -# ## Create geometry -# -# Create magnetic core, coils, and magnets. Assign materials and create a coordinate system to -# define the magnet orientation. - -core_id = m2d.modeler.create_rectangle( - origin=[0, 0, 0], - sizes=["Core_outer_x", "Core_outer_y"], - name="Core", - material="Materials[" + str(core_mat_index) + "]", -) - -hole_id = m2d.modeler.create_rectangle( - origin=["Core_thickness", "Core_thickness", 0], - sizes=["Core_outer_x-2*Core_thickness", "Core_outer_y-2*Core_thickness"], - name="hole", -) -m2d.modeler.subtract(blank_list=[core_id], tool_list=[hole_id]) - -magnet_n_id = m2d.modeler.create_rectangle( - origin=["Core_thickness", "Core_outer_y-2*Core_thickness", 0], - sizes=["Core_outer_x-2*Core_thickness", "Magnet_thickness"], - name="magnet_n", - material="Materials[" + str(magnet_mat_index) + "]", -) -magnet_s_id = m2d.modeler.create_rectangle( - origin=["Core_thickness", "Core_thickness", 0], - sizes=["Core_outer_x-2*Core_thickness", "Magnet_thickness"], - name="magnet_s", - material="Materials[" + str(magnet_mat_index) + "]", -) - -m2d.modeler.create_coordinate_system( - origin=[0, 0, 0], x_pointing=[0, 1, 0], y_pointing=[1, 0, 0], name="cs_x_positive" -) -m2d.modeler.create_coordinate_system( - origin=[0, 0, 0], x_pointing=[0, -1, 0], y_pointing=[1, 0, 0], name="cs_x_negative" -) -magnet_s_id.part_coordinate_system = "cs_x_positive" -magnet_n_id.part_coordinate_system = "cs_x_negative" -m2d.modeler.set_working_coordinate_system("Global") - -# ## Assign current -# -# Create coil terminals with 100 turns and winding with 5A current. - -coil_in_id = m2d.modeler.create_rectangle( - origin=[ - "Core_thickness+Coil_start_position", - "Core_thickness+Magnet_thickness+Coil_magnet_distance", - 0, - ], - sizes=["Coil_width", "Coil_thickness"], - name="coil_in", - material="Materials[" + str(coil_mat_index) + "]", -) -coil_out_id = m2d.modeler.create_rectangle( - origin=[ - "Core_thickness+Coil_start_position", - "Core_thickness+Magnet_thickness+Coil_magnet_distance+Coil_inner_diameter+Coil_thickness", - 0, - ], - sizes=["Coil_width", "Coil_thickness"], - name="coil_out", - material="Materials[" + str(coil_mat_index) + "]", -) - -m2d.assign_coil( - assignment=[coil_in_id], - conductors_number="No_of_turns", - name="coil_terminal_in", - polarity="Negative", -) -m2d.assign_coil( - assignment=[coil_out_id], - conductors_number="No_of_turns", - name="coil_terminal_out", - polarity="Positive", -) -m2d.assign_winding(is_solid=False, current="Winding_current", name="Winding1") -m2d.add_winding_coils( - assignment="Winding1", coils=["coil_terminal_in", "coil_terminal_out"] -) - -# ## Assign motion -# -# Create band objects. All the objects within the band move. The inner band ensures that the mesh is good, -# and additionally it is required when there is more than one moving object. -# Assign linear motion with mechanical transient. - -band_id = m2d.modeler.create_rectangle( - origin=[ - "Core_thickness + Band_clearance", - "Core_thickness+Magnet_thickness+Band_clearance", - 0, - ], - sizes=[ - "Core_outer_x-2*(Core_thickness+Band_clearance)", - "Core_outer_y-2*(Core_thickness+Band_clearance+Magnet_thickness)", - ], - name="Motion_band", -) -inner_band_id = m2d.modeler.create_rectangle( - origin=[ - "Core_thickness+Coil_start_position-Band_clearance", - "Core_thickness+Magnet_thickness+Coil_magnet_distance-Band_clearance", - 0, - ], - sizes=[ - "Coil_width + 2*Band_clearance", - "Coil_inner_diameter+2*(Coil_thickness+Band_clearance)", - ], - name="Motion_band_inner", -) -motion_limit = "Core_outer_x-2*(Core_thickness+Band_clearance)-(Coil_width + 2*Band_clearance)-2*Band_clearance" -m2d.assign_translate_motion( - assignment="Motion_band", - axis="X", - periodic_translate=None, - mechanical_transient=True, - mass="Coil_mass", - start_position=0, - negative_limit=0, - positive_limit=motion_limit, -) - -# ## Create simulation domain -# -# Create a region and assign zero vector potential on the region edges. - -region_id = m2d.modeler.create_region(pad_percent=2) -m2d.assign_vector_potential(assignment=region_id.edges, boundary="VectorPotential1") - -# ## Assign mesh operations -# -# The transient solver does not have adaptive mesh refinement, so the mesh operations must be assigned. - -m2d.mesh.assign_length_mesh( - assignment=[band_id, inner_band_id], - maximum_length="Mesh_bands", - maximum_elements=None, - name="Bands", -) -m2d.mesh.assign_length_mesh( - assignment=[coil_in_id, coil_in_id, core_id, magnet_n_id, magnet_s_id, region_id], - maximum_length="Mesh_other_objects", - maximum_elements=None, - name="Coils_core_magnets", -) - -# ## Turn on eddy effects -# -# Assign eddy effects to the magnets. - -m2d.eddy_effects_on(assignment=["magnet_n", "magnet_s"]) - -# ## Turn on core loss -# -# Enable core loss for the core. - -m2d.set_core_losses(assignment="Core") - -# ## Create simulation setup - -setup = m2d.create_setup(name="Setup1") -setup.props["StopTime"] = "Stop_time" -setup.props["TimeStep"] = "Time_step" -setup.props["SaveFieldsType"] = "Every N Steps" -setup.props["N Steps"] = "Save_fields_interval" -setup.props["Steps From"] = "0ms" -setup.props["Steps To"] = "Stop_time" - -# ## Create report -# -# Create an XY-report with force on the coil, the position of the coil on the Y axis, -# and time on the X axis. - -m2d.post.create_report( - expressions=["Moving1.Force_x", "Moving1.Position"], - plot_name="Force on Coil and Position of Coil", - primary_sweep_variable="Time", -) - -# ## Analyze project - -setup.analyze(cores=NUM_CORES, use_auto_settings=False) - -# ## Release AEDT - -m2d.save_project() -m2d.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_dir.name``. -# If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell -# removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/low_frequency/magnetic/magneto_motive_line.py b/examples/low_frequency/magnetic/magneto_motive_line.py deleted file mode 100644 index 2c9a5cde8..000000000 --- a/examples/low_frequency/magnetic/magneto_motive_line.py +++ /dev/null @@ -1,208 +0,0 @@ -# # Magnetomotive force along a line -# -# This example shows how to use PyAEDT to calculate -# the magnetomotive force along a line that changes position. -# It shows how to leverage the PyAEDT advanced fields calculator -# to insert a custom formula, which in this case is the integral -# of the H field along a line. -# The example shows two options to achieve the intent. -# The first one creates many lines as to simulate a contour that changes position. -# The integral of the H field is computed for each line. -# The second option creates one parametric polyline and then uses a parametric sweep to change its position. -# The integral of the H field is computed for each position. - -# Keywords: **Maxwell 2D**, **magnetomotive force**. - -# ## Perform imports and define constants -# -# Perform required imports. - -import tempfile -import time - -import ansys.aedt.core - -# Define constants. - -AEDT_VERSION = "2024.2" -NUM_CORES = 4 -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Import project -# -# Download the files required to run this example to the temporary working folder. - -project_path = ansys.aedt.core.downloads.download_file( - source="maxwell_magnetic_force", - name="Maxwell_Magnetic_Force.aedt", - destination=temp_folder.name, -) - -# ## Initialize and launch Maxwell 2D -# -# Initialize and launch Maxwell 2D, providing the version and the path of the project. - -m2d = ansys.aedt.core.Maxwell2d( - version=AEDT_VERSION, - non_graphical=NG_MODE, - project=project_path, - design="Maxwell2DDesign1", -) - -# # First option - -# ## Create a polyline -# -# Create a polyline, specifying its ends. - -poly = m2d.modeler.create_polyline(points=[[10, -10, 0], [10, 10, 0]], name="polyline") - -# Duplicate the polyline along a vector. - -polys = [poly.name] -polys.extend(poly.duplicate_along_line(vector=[-0.5, 0, 0], clones=10)) - -# ## Compute magnetomotive force along each line -# -# Create and add a new formula to add in the PyAEDT advanced fields calculator. -# Create the fields report object and get field data. -# Create a data table report for the H field along each line and export it to a .csv file. - -my_expression = { - "name": None, - "description": "Magnetomotive force along a line", - "design_type": ["Maxwell 2D", "Maxwell 3D"], - "fields_type": ["Fields"], - "primary_sweep": "distance", - "assignment": None, - "assignment_type": ["Line"], - "operations": [ - "Fundamental_Quantity('H')", - "Operation('Tangent')", - "Operation('Dot')", - "EnterLine('assignment')", - "Operation('LineValue')", - "Operation('Integrate')", - ], - "report": ["Data Table"], -} - -quantities = [] -for p in polys: - quantity = "H_field_{}".format(p) - quantities.append(quantity) - my_expression["name"] = quantity - my_expression["assignment"] = quantity - m2d.post.fields_calculator.add_expression(my_expression, p) - report = m2d.post.create_report( - expressions=quantity, - context=p, - polyline_points=1, - report_category="Fields", - plot_type="Data Table", - plot_name=quantity, - ) - -# # Second option - -# ## Create a design variable -# -# Parametrize the polyline x position. - -m2d["xl"] = "10mm" - -# ## Create polyline -# -# Create a parametrized polyline, specifying its ends. - -poly = m2d.modeler.create_polyline( - points=[["xl", -10, 0], ["xl", 10, 0]], name="polyline_sweep" -) - -# ## Add parametric sweep -# -# Add a parametric sweep where the parameter to sweep is ``xl``. -# Create a linear step sweep from ``10mm`` to ``15mm`` every ``1mm`` step. - -param_sweep = m2d.parametrics.add( - variable="xl", - start_point="10mm", - end_point="15mm", - step=1, - variation_type="LinearStep", -) - -# ## Compute magnetomotive force along the line -# -# Create and add a new formula to add in the PyAEDT advanced fields calculator. - -quantity_sweep = "H_field_{}".format(poly.name) -my_expression["name"] = quantity_sweep -my_expression["assignment"] = poly.name -m2d.post.fields_calculator.add_expression(my_expression, poly.name) - -# ## Add parametric sweep calculation specifying the quantity (H) and save fields. - -param_sweep.add_calculation(calculation=quantity_sweep, report_type="Fields", ranges={}) -param_sweep.props["ProdOptiSetupDataV2"]["SaveFields"] = True - -# ## Create data table report -# -# Create a data table report to display H for each polyline position. - -report_sweep = m2d.post.create_report( - expressions=quantity_sweep, - report_category="Fields", - plot_type="Data Table", - plot_name=quantity_sweep, - primary_sweep_variable="xl", - variations={"xl": "All"}, -) - -# ## Analyze parametric sweep - -param_sweep.analyze(cores=NUM_CORES) - -# ## Export results -# -# Export results in a .csv file for the parametric sweep analysis (second option). - -m2d.post.export_report_to_csv( - project_dir=temp_folder.name, - plot_name=quantity_sweep, -) - -# Export results in a .csv file for each polyline (first option). - -[ - m2d.post.export_report_to_csv( - project_dir=temp_folder.name, - plot_name=q, - ) - for q in quantities -] - -# ## Release AEDT - -m2d.save_project() -m2d.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. -# If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell -# removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/low_frequency/magnetic/transient_winding.py b/examples/low_frequency/magnetic/transient_winding.py deleted file mode 100644 index 430c45628..000000000 --- a/examples/low_frequency/magnetic/transient_winding.py +++ /dev/null @@ -1,158 +0,0 @@ -# # Transient winding analysis -# -# This example shows how to use PyAEDT to create a project in Maxwell 2D -# and run a transient simulation. It runs only on Windows using CPython. -# -# The following libraries are required for the advanced postprocessing features -# used in this example: -# -# - [Matplotlib](https://pypi.org/project/matplotlib/) -# - [Numpy](https://pypi.org/project/numpy/) -# - [PyVista](https://pypi.org/project/pyvista/) -# -# Install these libraries with this command: -# -# ```console -# pip install numpy pyvista matplotlib -# ``` -# -# Keywords: **Maxwell 2D**, **transient**, **winding**. - -# ## Perform imports and define constants -# -# Perform required imports. - -import os -import tempfile -import time - -import ansys.aedt.core - -# Define constants. - -AEDT_VERSION = "2024.2" -NUM_CORES = 4 -NG_MODE = False # Open AEDT UI when it is launched. - - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Insert Maxwell 2D design - -project_name = os.path.join(temp_folder.name, "Transient.aedt") -m2d = ansys.aedt.core.Maxwell2d( - solution_type="TransientXY", - version=AEDT_VERSION, - non_graphical=NG_MODE, - new_desktop=True, - project=project_name, -) - -# ## Create rectangle and duplicate it - -rect1 = m2d.modeler.create_rectangle( - origin=[0, 0, 0], sizes=[10, 20], name="winding", material="copper" -) -duplicate = rect1.duplicate_along_line(vector=[14, 0, 0]) -rect2 = m2d.modeler[duplicate[0]] - -# ## Create air region -# -# Create an air region. - -region = m2d.modeler.create_region([100, 100, 100, 100]) - -# ## Assign windings and balloon -# -# Assigns windings to the sheets and a balloon to the air region. - -m2d.assign_winding( - assignment=[rect1.name, rect2.name], current="1*sin(2*pi*50*Time)", name="PHA" -) -m2d.assign_balloon(assignment=region.edges) - -# ## Create transient setup - -setup = m2d.create_setup() -setup.props["StopTime"] = "0.02s" -setup.props["TimeStep"] = "0.0002s" -setup.props["SaveFieldsType"] = "Every N Steps" -setup.props["N Steps"] = "1" -setup.props["Steps From"] = "0s" -setup.props["Steps To"] = "0.002s" - -# ## Create rectangular plot - -m2d.post.create_report( - expressions="InputCurrent(PHA)", - domain="Sweep", - primary_sweep_variable="Time", - plot_name="Winding Plot 1", -) - -# ## Solve model - -m2d.analyze(cores=NUM_CORES, use_auto_settings=False) - -# ## Create output and plot using PyVista - -# + -cutlist = ["Global:XY"] -face_lists = rect1.faces -face_lists += rect2.faces -timesteps = [str(i * 2e-4) + "s" for i in range(11)] -id_list = [f.id for f in face_lists] - -gif = m2d.post.plot_animated_field( - quantity="Mag_B", - assignment=id_list, - plot_type="Surface", - intrinsics={"Time": "0s"}, - variation_variable="Time", - variations=timesteps, - show=False, - export_gif=False, -) -gif.isometric_view = False -gif.camera_position = [15, 15, 80] -gif.focal_point = [15, 15, 0] -gif.roll_angle = 0 -gif.elevation_angle = 0 -gif.azimuth_angle = 0 - -# Set off_screen to False to visualize the animation. -# gif.off_screen = False -gif.animate() -# - - -# ## Generate plot outside of AEDT -# -# Generate the same plot outside AEDT. - -solutions = m2d.post.get_solution_data( - expressions="InputCurrent(PHA)", primary_sweep_variable="Time" -) -solutions.plot() - -# ## Release AEDT - -m2d.save_project() -m2d.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. -# If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell -# removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/low_frequency/motor/_static/motor.png b/examples/low_frequency/motor/_static/motor.png deleted file mode 100644 index bb00973ca..000000000 Binary files a/examples/low_frequency/motor/_static/motor.png and /dev/null differ diff --git a/examples/low_frequency/motor/_static/motorcad.png b/examples/low_frequency/motor/_static/motorcad.png deleted file mode 100644 index b835d8fbc..000000000 Binary files a/examples/low_frequency/motor/_static/motorcad.png and /dev/null differ diff --git a/examples/low_frequency/motor/aedt_motor/_static/ipm_optimization.png b/examples/low_frequency/motor/aedt_motor/_static/ipm_optimization.png deleted file mode 100644 index ebf8d3bdf..000000000 Binary files a/examples/low_frequency/motor/aedt_motor/_static/ipm_optimization.png and /dev/null differ diff --git a/examples/low_frequency/motor/aedt_motor/_static/magnet_segmentation.png b/examples/low_frequency/motor/aedt_motor/_static/magnet_segmentation.png deleted file mode 100644 index eb9f5302f..000000000 Binary files a/examples/low_frequency/motor/aedt_motor/_static/magnet_segmentation.png and /dev/null differ diff --git a/examples/low_frequency/motor/aedt_motor/_static/pm_synchronous.png b/examples/low_frequency/motor/aedt_motor/_static/pm_synchronous.png deleted file mode 100644 index ab8a4f3aa..000000000 Binary files a/examples/low_frequency/motor/aedt_motor/_static/pm_synchronous.png and /dev/null differ diff --git a/examples/low_frequency/motor/aedt_motor/_static/rmxpert.png b/examples/low_frequency/motor/aedt_motor/_static/rmxpert.png deleted file mode 100644 index 1a930682b..000000000 Binary files a/examples/low_frequency/motor/aedt_motor/_static/rmxpert.png and /dev/null differ diff --git a/examples/low_frequency/motor/aedt_motor/_static/transformer.png b/examples/low_frequency/motor/aedt_motor/_static/transformer.png deleted file mode 100644 index 6ca02cf61..000000000 Binary files a/examples/low_frequency/motor/aedt_motor/_static/transformer.png and /dev/null differ diff --git a/examples/low_frequency/motor/aedt_motor/_static/transformer2.png b/examples/low_frequency/motor/aedt_motor/_static/transformer2.png deleted file mode 100644 index cfa282103..000000000 Binary files a/examples/low_frequency/motor/aedt_motor/_static/transformer2.png and /dev/null differ diff --git a/examples/low_frequency/motor/aedt_motor/index.rst b/examples/low_frequency/motor/aedt_motor/index.rst deleted file mode 100644 index 213f3c267..000000000 --- a/examples/low_frequency/motor/aedt_motor/index.rst +++ /dev/null @@ -1,97 +0,0 @@ -AEDT Motor -~~~~~~~~~~ - -These examples use PyAEDT to show some motor applications in AEDT. - -.. grid:: 2 - - .. grid-item-card:: PM synchronous motor transient analysis - :padding: 2 2 2 2 - :link: pm_synchronous - :link-type: doc - - .. image:: _static/pm_synchronous.png - :alt: Maxwell general - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create a Maxwell 2D transient analysis for an interior permanent magnet (PM) electric motor. - - .. grid-item-card:: Magnet segmentation - :padding: 2 2 2 2 - :link: magnet_segmentation - :link-type: doc - - .. image:: _static/magnet_segmentation.png - :alt: Maxwell general - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to segment magnets of an electric motor. The method is valid and usable for any object you would like to segment. - - .. grid-item-card:: IPM motor design optimization - :padding: 2 2 2 2 - :link: ipm_optimization - :link-type: doc - - .. image:: _static/ipm_optimization.png - :alt: IPM Motor - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to find the best machine 2D geometry to achieve high torque and low losses with an optimetrics analysis. - - .. grid-item-card:: Transformer - :padding: 2 2 2 2 - :link: transformer - :link-type: doc - - .. image:: _static/transformer.png - :alt: Maxwell general - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to set core loss given a set of power-volume [kw/m^3] curves at different frequencies. - - - .. grid-item-card:: Transformer leakage inductance calculation - :padding: 2 2 2 2 - :link: transformer_inductance - :link-type: doc - - .. image:: _static/transformer2.png - :alt: Maxwell general - :width: 250px - :height: 200px - :align: center - - This example shows how to use PyAEDT to create a Maxwell 2D magnetostatic analysis to calculate transformer leakage inductance and reactance. - - - .. grid-item-card:: Motor creation and export - :padding: 2 2 2 2 - :link: rmxpert - :link-type: doc - - .. image:: _static/rmxpert.png - :alt: Maxwell general - :width: 250px - :height: 200px - :align: center - - This example uses PyAEDT to create a RMxprt project and export it to Maxwell 2D. - - - .. toctree:: - :hidden: - - pm_synchronous - magnet_segmentation - ipm_optimization - transformer - transformer_inductance - rmxpert diff --git a/examples/low_frequency/motor/aedt_motor/ipm_optimization.py b/examples/low_frequency/motor/aedt_motor/ipm_optimization.py deleted file mode 100644 index c2572c43e..000000000 --- a/examples/low_frequency/motor/aedt_motor/ipm_optimization.py +++ /dev/null @@ -1,207 +0,0 @@ -# # IPM geometry optimization -# -# This example shows how to use PyAEDT to find the best machine 2D geometry -# to achieve high torque and low losses. -# The example shows how to setup an optimetrics analysis to sweep geometries -# for a single value of stator current angle. -# The torque and losses results are then exported in a .csv file. -# -# Keywords: **Maxwell 2D**, **transient**, **motor**, **optimization**. - -# ## Perform imports and define constants -# -# Perform required imports. - -import csv -import os -import tempfile -import time - -import ansys.aedt.core - -# Define constants. - -AEDT_VERSION = "2024.2" -NUM_CORES = 4 -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Create temporary directory and download files -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Download AEDT file example -# -# Set the local temporary folder to export the AEDT file to. - -aedt_file = ansys.aedt.core.downloads.download_file( - source="maxwell_motor_optimization", - name="IPM_optimization.aedt", - destination=temp_folder.name, -) - -# ## Launch Maxwell 2D -# -# Launch AEDT and Maxwell 2D after first setting up the project, the version and the graphical mode. - -m2d = ansys.aedt.core.Maxwell2d( - project=aedt_file, - version=AEDT_VERSION, - new_desktop=True, - non_graphical=NG_MODE, -) - -# ## Add parametric setup -# -# Add a parametric setup made up of geometry variable sweep definitions and single value for the stator current angle. -# Note: Step variations have been minimized to reduce the analysis time. If needed they can be increased by changing -# the ``step`` argument. - -param_sweep = m2d.parametrics.add( - variable="bridge", - start_point="0.5mm", - end_point="1mm", - step="0.5mm", - variation_type="LinearStep", -) -param_sweep.add_variation( - sweep_variable="din", - start_point=70, - end_point=80, - step=10, - units="mm", - variation_type="LinearStep", -) -param_sweep.add_variation( - sweep_variable="phase_advance", - start_point=0, - end_point=45, - step=45, - units="deg", - variation_type="LinearStep", -) -param_sweep.add_variation( - sweep_variable="Ipeak", start_point=200, units="A", variation_type="SingleValue" -) - -# ## Analyze parametric sweep - -param_sweep.analyze(cores=NUM_CORES) - -# ## Post-processing -# -# Create reports to get torque and loss results for all variations. - -report_torque = m2d.post.create_report( - expressions="Moving1.Torque", - domain="Sweep", - variations={"bridge": "All", "din": "All", "Ipeak": "All"}, - primary_sweep_variable="Time", - plot_type="Rectangular Plot", - plot_name="TorqueAllVariations", -) - -report_solid_loss = m2d.post.create_report( - expressions="SolidLoss", - domain="Sweep", - variations={"bridge": "All", "din": "All", "Ipeak": "All"}, - primary_sweep_variable="Time", - plot_type="Rectangular Plot", - plot_name="SolidLossAllVariations", -) - -report_core_loss = m2d.post.create_report( - expressions="CoreLoss", - domain="Sweep", - variations={"bridge": "All", "din": "All", "Ipeak": "All"}, - primary_sweep_variable="Time", - plot_type="Rectangular Plot", - plot_name="CoreLossAllVariations", -) - -# Get torque and loss solution data for all available variations. - -torque_data = m2d.post.get_solution_data( - expressions=["Moving1.Torque"], - setup_sweep_name=m2d.nominal_sweep, - domain="Sweep", - variations={"bridge": "All", "din": "All", "Ipeak": "All"}, - primary_sweep_variable="Time", - report_category="Standard", -) - -solid_loss_data = m2d.post.get_solution_data( - expressions=["CoreLoss"], - setup_sweep_name=m2d.nominal_sweep, - domain="Sweep", - variations={"bridge": "All", "din": "All", "Ipeak": "All"}, - primary_sweep_variable="Time", - report_category="Standard", -) - -core_loss_data = m2d.post.get_solution_data( - expressions=["SolidLoss"], - setup_sweep_name=m2d.nominal_sweep, - domain="Sweep", - variations={"bridge": "All", "din": "All", "Ipeak": "All"}, - primary_sweep_variable="Time", - report_category="Standard", -) - -# Calculate torque and loss average values for each variation and write data in a .csv file. - -csv_data = [] -for var in core_loss_data.variations: - torque_data.active_variation = var - core_loss_data.active_variation = var - solid_loss_data.active_variation = var - - torque_values = torque_data.data_magnitude() - core_loss_values = core_loss_data.data_magnitude() - solid_loss_values = solid_loss_data.data_magnitude() - - torque_data_average = sum(torque_values) / len(torque_values) - core_loss_average = sum(core_loss_values) / len(core_loss_values) - solid_loss_average = sum(solid_loss_values) / len(solid_loss_values) - - csv_data.append( - { - "active_variation": str(torque_data.active_variation), - "average_torque": str(torque_data_average), - "average_core_loss": str(core_loss_average), - "average_solid_loss": str(solid_loss_average), - } - ) - - with open( - os.path.join(temp_folder.name, "motor_optimization.csv"), "w", newline="" - ) as csvfile: - fields = [ - "active_variation", - "average_torque", - "average_core_loss", - "average_solid_loss", - ] - writer = csv.DictWriter(csvfile, fieldnames=fields) - writer.writeheader() - writer.writerows(csv_data) - -# ## Release AEDT - -m2d.save_project() -m2d.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. -# If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell -# removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/low_frequency/motor/aedt_motor/magnet_segmentation.py b/examples/low_frequency/motor/aedt_motor/magnet_segmentation.py deleted file mode 100644 index c3d2411da..000000000 --- a/examples/low_frequency/motor/aedt_motor/magnet_segmentation.py +++ /dev/null @@ -1,118 +0,0 @@ -# # Magnet segmentation - -# This example shows how to use PyAEDT to segment magnets of an electric motor. -# The method is valid and usable for any object you would like to segment. -# -# Keywords: **Maxwell 3D**, **Magnet segmentation**. - -# ## Perform imports and define constants -# -# Perform required imports. - -import tempfile -import time - -import ansys.aedt.core - -# Define constants. - -AEDT_VERSION = "2024.2" -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Download AEDT file example -# -# Set the local temporary folder to export the AEDT file to. - -aedt_file = ansys.aedt.core.downloads.download_file( - source="object_segmentation", - name="Motor3D_obj_segments.aedt", - destination=temp_folder.name, -) - -# ## Launch Maxwell 3D -# -# Launch Maxwell 3D, providing the version, rgw path to the project, and the graphical mode. - -m3d = ansys.aedt.core.Maxwell3d( - project=aedt_file, - version=AEDT_VERSION, - new_desktop=True, - non_graphical=NG_MODE, -) - -# ## Segment first magnet by specifying number of segments -# -# Select the first magnet to segment by specifying the number of segments. -# The method accepts as input the list of magnets names to segment, -# magnet IDs, or the magnet :class:`ansys.aedt.core.modeler.cad.object3d.Object3d` object. -# When ``apply_mesh_sheets`` is enabled, the mesh sheets are also -# applied in the geometry. -# In the following code, the name of the magnet is also given as an input. - -segments_number = 2 -object_name = "PM_I1" -sheets_1 = m3d.modeler.objects_segmentation( - object_name, - segments=segments_number, - apply_mesh_sheets=True, - mesh_sheets=3, -) - -# ## Segment second magnet by specifying number of segments -# -# Select the second magnet to segment by specifying the number of segments. -# The following code gives the ID of the magnet as an input. - -segments_number = 2 -object_name = "PM_I1_1" -magnet_id = [obj.id for obj in m3d.modeler.object_list if obj.name == object_name][0] -sheets_2 = m3d.modeler.objects_segmentation( - magnet_id, segments=segments_number, apply_mesh_sheets=True -) - -# ## Segment third magnet by specifying segmentation thickness -# -# Select the third magnet to segment by specifying the segmentation thickness. -# The following code gives the magnet object type `ansys.aedt.core.modeler.cad.object3d.Object3d` -# as an input. - -segmentation_thickness = 1 -object_name = "PM_O1" -magnet = [obj for obj in m3d.modeler.object_list if obj.name == object_name][0] -sheets_3 = m3d.modeler.objects_segmentation( - magnet, segmentation_thickness=segmentation_thickness, apply_mesh_sheets=True -) - -# ## Segment fourth magnet by specifying number of segments -# -# Select the fourth magnet to segment by specifying the number of segments. -# The following code gives the name of the magnet as input and disables the mesh sheets. - -object_name = "PM_O1_1" -segments_number = 2 -sheets_4 = m3d.modeler.objects_segmentation(object_name, segments=segments_number) - -# ## Release AEDT - -m3d.save_project() -m3d.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. -# If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell -# removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/low_frequency/motor/aedt_motor/pm_synchronous.py b/examples/low_frequency/motor/aedt_motor/pm_synchronous.py deleted file mode 100644 index 680a73018..000000000 --- a/examples/low_frequency/motor/aedt_motor/pm_synchronous.py +++ /dev/null @@ -1,922 +0,0 @@ -# # PM synchronous motor transient analysis -# -# This example shows how to use PyAEDT to create a Maxwell 2D transient analysis for -# an interior permanent magnet (PM) electric motor. -# -# Keywords: **Maxwell 2D**, **transient**, **motor**. - -# ## Perform imports and define constants -# -# Perform required imports. - -import csv -import os -import tempfile -import time -from operator import attrgetter - -import ansys.aedt.core - -# Define constants. - -AEDT_VERSION = "2024.2" -NUM_CORES = 4 -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Create temporary directory and download files -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Initialize dictionaries -# -# Dictionaries contain all the definitions for the design variables and output variables. - -# ## Initialize definitions for th stator, rotor, and shaft -# -# Initialize geometry parameter definitions for the stator, rotor, and shaft. -# The naming refers to RMxprt primitives. - -geom_params = { - "DiaGap": "132mm", - "DiaStatorYoke": "198mm", - "DiaStatorInner": "132mm", - "DiaRotorLam": "130mm", - "DiaShaft": "44.45mm", - "DiaOuter": "198mm", - "Airgap": "1mm", - "SlotNumber": "48", - "SlotType": "3", -} - -# ## Initialize definitions for stator windings -# -# Initialize geometry parameter definitions for the stator windings. The naming -# refers to RMxprt primitives. - -wind_params = { - "Layers": "1", - "ParallelPaths": "2", - "R_Phase": "7.5mOhm", - "WdgExt_F": "5mm", - "SpanExt": "30mm", - "SegAngle": "0.25", - "CoilPitch": "5", # coil pitch in slots - "Coil_SetBack": "3.605732823mm", - "SlotWidth": "2.814mm", # RMxprt Bs0 - "Coil_Edge_Short": "3.769235435mm", - "Coil_Edge_Long": "15.37828521mm", -} - -# ## Initialize definitions for model setup -# -# Initialize geometry parameter definitions for the model setup. - -mod_params = { - "NumPoles": "8", - "Model_Length": "80mm", - "SymmetryFactor": "8", - "Magnetic_Axial_Length": "150mm", - "Stator_Lam_Length": "0mm", - "StatorSkewAngle": "0deg", - "NumTorquePointsPerCycle": "30", - "mapping_angle": "0.125*4deg", - "num_m": "16", - "Section_Angle": "360deg/SymmetryFactor", -} - -# ## Initialize definitions for operational machine -# -# Initialize geometry parameter definitions for the operational machine. This -# identifies the operating point for the transient setup. - -oper_params = { - "InitialPositionMD": "180deg/4", - "IPeak": "480A", - "MachineRPM": "3000rpm", - "ElectricFrequency": "MachineRPM/60rpm*NumPoles/2*1Hz", - "ElectricPeriod": "1/ElectricFrequency", - "BandTicksinModel": "360deg/NumPoles/mapping_angle", - "TimeStep": "ElectricPeriod/(2*BandTicksinModel)", - "StopTime": "ElectricPeriod", - "Theta_i": "135deg", -} - -# ## Launch AEDT and Maxwell 2D -# -# Launch AEDT and Maxwell 2D after first setting up the project and design names, -# the solver, and the version. The following code also creates an instance of the -# ``Maxwell2d`` class named ``m2d``. - -project_name = os.path.join(temp_folder.name, "PM_Motor.aedt") -m2d = ansys.aedt.core.Maxwell2d( - project=project_name, - version=AEDT_VERSION, - design="Sinusoidal", - solution_type="TransientXY", - new_desktop=True, - non_graphical=NG_MODE, -) - -# ## Define modeler units - -m2d.modeler.model_units = "mm" - -# ## Define variables from dictionaries -# -# Define design variables from the created dictionaries. - -for k, v in geom_params.items(): - m2d[k] = v -for k, v in wind_params.items(): - m2d[k] = v -for k, v in mod_params.items(): - m2d[k] = v -for k, v in oper_params.items(): - m2d[k] = v - -# ## Define path for non-linear material properties -# -# Define the path for non-linear material properties. -# Materials are stored in text files. - -filename_lam, filename_PM = ansys.aedt.core.downloads.download_leaf( - destination=temp_folder.name -) - -# ## Create first material -# -# Create the material ``"Copper (Annealed)_65C"``. - -mat_coils = m2d.materials.add_material("Copper (Annealed)_65C") -mat_coils.update() -mat_coils.conductivity = "49288048.9198" -mat_coils.permeability = "1" - -# ## Create second material -# -# Create the material ``"Arnold_Magnetics_N30UH_80C"``. -# The BH curve is read from a tabbed CSV file. A list named ``BH_List_PM`` -# is created. This list is passed to the ``mat_PM.permeability.value`` -# variable. - -mat_PM = m2d.materials.add_material(name="Arnold_Magnetics_N30UH_80C_new") -mat_PM.update() -mat_PM.conductivity = "555555.5556" -mat_PM.set_magnetic_coercivity(value=-800146.66287534, x=1, y=0, z=0) -mat_PM.mass_density = "7500" -BH_List_PM = [] -with open(filename_PM) as f: - reader = csv.reader(f, delimiter="\t") - next(reader) - for row in reader: - BH_List_PM.append([float(row[0]), float(row[1])]) -mat_PM.permeability.value = BH_List_PM - -# ## Create third material -# -# Create the laminated material ``30DH_20C_smooth``. -# This material has a BH curve and a core loss model, -# which is set to electrical steel. - -mat_lam = m2d.materials.add_material("30DH_20C_smooth") -mat_lam.update() -mat_lam.conductivity = "1694915.25424" -kh = 71.7180985413 -kc = 0.25092214579 -ke = 12.1625774023 -kdc = 0.001 -eq_depth = 0.001 -mat_lam.set_electrical_steel_coreloss(kh, kc, ke, kdc, eq_depth) -mat_lam.mass_density = "7650" -BH_List_lam = [] -with open(filename_lam) as f: - reader = csv.reader(f, delimiter="\t") - next(reader) - for row in reader: - BH_List_lam.append([float(row[0]), float(row[1])]) -mat_lam.permeability.value = BH_List_lam - -# ## Create geometry for stator -# -# Create the geometry for the stator. It is created via -# the RMxprt user-defined primitive (UDP). A list of lists is -# created with the proper UDP parameters. - -# + -udp_par_list_stator = [ - ["DiaGap", "DiaGap"], - ["DiaYoke", "DiaStatorYoke"], - ["Length", "Stator_Lam_Length"], - ["Skew", "StatorSkewAngle"], - ["Slots", "SlotNumber"], - ["SlotType", "SlotType"], - ["Hs0", "1.2mm"], - ["Hs01", "0mm"], - ["Hs1", "0.4834227384999mm"], - ["Hs2", "17.287669825502mm"], - ["Bs0", "2.814mm"], - ["Bs1", "4.71154109036mm"], - ["Bs2", "6.9777285790998mm"], - ["Rs", "2mm"], - ["FilletType", "1"], - ["HalfSlot", "0"], - ["VentHoles", "0"], - ["HoleDiaIn", "0mm"], - ["HoleDiaOut", "0mm"], - ["HoleLocIn", "0mm"], - ["HoleLocOut", "0mm"], - ["VentDucts", "0"], - ["DuctWidth", "0mm"], - ["DuctPitch", "0mm"], - ["SegAngle", "0deg"], - ["LenRegion", "Model_Length"], - ["InfoCore", "0"], -] - -stator_id = m2d.modeler.create_udp( - dll="RMxprt/VentSlotCore.dll", - parameters=udp_par_list_stator, - library="syslib", - name="my_stator", -) - -# - - -# ## Assign properties to stator -# -# Assign properties to the stator. The following code assigns -# the ``material``, ``name``, ``color``, and ``solve_inside`` properties. - -m2d.assign_material(assignment=stator_id, material="30DH_20C_smooth") -stator_id.name = "Stator" -stator_id.color = (0, 0, 255) # rgb - -# to be reassigned: m2d.assign material puts False if not dielectric -stator_id.solve_inside = True - -# ## Create outer and inner PMs -# -# Create the outer and inner PMs and assign color to them. - -IM1_points = [ - [56.70957112, 3.104886585, 0], - [40.25081875, 16.67243502, 0], - [38.59701538, 14.66621111, 0], - [55.05576774, 1.098662669, 0], -] -OM1_points = [ - [54.37758185, 22.52393189, 0], - [59.69688156, 9.68200639, 0], - [63.26490432, 11.15992981, 0], - [57.94560461, 24.00185531, 0], -] -IPM1_id = m2d.modeler.create_polyline( - points=IM1_points, - cover_surface=True, - name="PM_I1", - material="Arnold_Magnetics_N30UH_80C_new", -) -IPM1_id.color = (0, 128, 64) -OPM1_id = m2d.modeler.create_polyline( - points=OM1_points, - cover_surface=True, - name="PM_O1", - material="Arnold_Magnetics_N30UH_80C_new", -) -OPM1_id.color = (0, 128, 64) - - -# ## Create coordinate system for PMs -# -# Create the coordinate system for the PMs. -# In Maxwell 2D, you assign magnetization via the coordinate system. -# The inputs are the object name, coordinate system name, and inner or outer magnetization. - -# + -def create_cs_magnets(pm_id, cs_name, point_direction): - edges = sorted(pm_id.edges, key=attrgetter("length"), reverse=True) - - if point_direction == "outer": - my_axis_pos = edges[0] - elif point_direction == "inner": - my_axis_pos = edges[1] - - m2d.modeler.create_face_coordinate_system( - face=pm_id.faces[0], - origin=pm_id.faces[0], - axis_position=my_axis_pos, - axis="X", - name=cs_name, - ) - pm_id.part_coordinate_system = cs_name - m2d.modeler.set_working_coordinate_system("Global") - - -# - - -# ## Create coordinate system for PMs in face center -# -# Create the coordinate system for PMs in the face center. - -create_cs_magnets(IPM1_id, "CS_" + IPM1_id.name, "outer") -create_cs_magnets(OPM1_id, "CS_" + OPM1_id.name, "outer") - -# ## Duplicate and mirror PMs -# -# Duplicate and mirror the PMs along with the local coordinate system. - -m2d.modeler.duplicate_and_mirror( - assignment=[IPM1_id, OPM1_id], - origin=[0, 0, 0], - vector=[ - "cos((360deg/SymmetryFactor/2)+90deg)", - "sin((360deg/SymmetryFactor/2)+90deg)", - 0, - ], -) -id_PMs = m2d.modeler.get_objects_w_string(string_name="PM", case_sensitive=True) - -# ## Create coils - -coil_id = m2d.modeler.create_rectangle( - origin=["DiaRotorLam/2+Airgap+Coil_SetBack", "-Coil_Edge_Short/2", 0], - sizes=["Coil_Edge_Long", "Coil_Edge_Short", 0], - name="Coil", - material="Copper (Annealed)_65C", -) -coil_id.color = (255, 128, 0) -m2d.modeler.rotate(assignment=coil_id, axis="Z", angle="360deg/SlotNumber/2") -coil_id.duplicate_around_axis( - axis="Z", angle="360deg/SlotNumber", clones="CoilPitch+1", create_new_objects=True -) -id_coils = m2d.modeler.get_objects_w_string(string_name="Coil", case_sensitive=True) - -# ## Create shaft and region - -region_id = m2d.modeler.create_circle( - origin=[0, 0, 0], - radius="DiaOuter/2", - num_sides="SegAngle", - is_covered=True, - name="Region", -) -shaft_id = m2d.modeler.create_circle( - origin=[0, 0, 0], - radius="DiaShaft/2", - num_sides="SegAngle", - is_covered=True, - name="Shaft", -) - -# ## Create bands -# -# Create the inner band, band, and outer band. - -bandIN_id = m2d.modeler.create_circle( - origin=[0, 0, 0], - radius="(DiaGap - (1.5 * Airgap))/2", - num_sides="mapping_angle", - is_covered=True, - name="Inner_Band", -) -bandMID_id = m2d.modeler.create_circle( - origin=[0, 0, 0], - radius="(DiaGap - (1.0 * Airgap))/2", - num_sides="mapping_angle", - is_covered=True, - name="Band", -) -bandOUT_id = m2d.modeler.create_circle( - origin=[0, 0, 0], - radius="(DiaGap - (0.5 * Airgap))/2", - num_sides="mapping_angle", - is_covered=True, - name="Outer_Band", -) - -# ## Assign motion setup to object -# -# Assign a motion setup to a ``Band`` object named ``RotatingBand_mid``. - -m2d.assign_rotate_motion( - assignment="Band", - coordinate_system="Global", - axis="Z", - positive_movement=True, - start_position="InitialPositionMD", - angular_velocity="MachineRPM", -) - -# ## Create list of vacuum objects -# -# Create a list of vacuum objects and assign color. - -vacuum_obj_id = [ - shaft_id, - region_id, - bandIN_id, - bandMID_id, - bandOUT_id, -] # put shaft first -for item in vacuum_obj_id: - item.color = (128, 255, 255) - -# ## Create rotor -# -# Create the rotor. Holes are specific to the lamination. -# Allocated PMs are created. - -# + -rotor_id = m2d.modeler.create_circle( - origin=[0, 0, 0], - radius="DiaRotorLam/2", - num_sides=0, - name="Rotor", - material="30DH_20C_smooth", -) - -rotor_id.color = (0, 128, 255) -m2d.modeler.subtract(blank_list=rotor_id, tool_list=shaft_id, keep_originals=True) -void_small_1_id = m2d.modeler.create_circle( - origin=[62, 0, 0], radius="2.55mm", num_sides=0, name="void1", material="vacuum" -) - -m2d.modeler.duplicate_around_axis( - assignment=void_small_1_id, - axis="Z", - angle="360deg/SymmetryFactor", - clones=2, - create_new_objects=False, -) - -void_big_1_id = m2d.modeler.create_circle( - origin=[29.5643, 12.234389332712, 0], - radius="9.88mm/2", - num_sides=0, - name="void_big", - material="vacuum", -) -m2d.modeler.subtract( - blank_list=rotor_id, - tool_list=[void_small_1_id, void_big_1_id], - keep_originals=False, -) - -slot_IM1_points = [ - [37.5302872, 15.54555396, 0], - [55.05576774, 1.098662669, 0], - [57.33637589, 1.25, 0], - [57.28982158, 2.626565019, 0], - [40.25081875, 16.67243502, 0], -] -slot_OM1_points = [ - [54.37758185, 22.52393189, 0], - [59.69688156, 9.68200639, 0], - [63.53825619, 10.5, 0], - [57.94560461, 24.00185531, 0], -] -slot_IM_id = m2d.modeler.create_polyline( - points=slot_IM1_points, cover_surface=True, name="slot_IM1", material="vacuum" -) -slot_OM_id = m2d.modeler.create_polyline( - points=slot_OM1_points, cover_surface=True, name="slot_OM1", material="vacuum" -) - -m2d.modeler.duplicate_and_mirror( - assignment=[slot_IM_id, slot_OM_id], - origin=[0, 0, 0], - vector=[ - "cos((360deg/SymmetryFactor/2)+90deg)", - "sin((360deg/SymmetryFactor/2)+90deg)", - 0, - ], -) - -id_holes = m2d.modeler.get_objects_w_string(string_name="slot_", case_sensitive=True) -m2d.modeler.subtract(rotor_id, id_holes, keep_originals=True) -# - - -# ## Create section of machine -# -# Create a section of the machine. This allows you to take -# advantage of symmetries. - -# + -object_list = [stator_id, rotor_id] + vacuum_obj_id -m2d.modeler.create_coordinate_system( - origin=[0, 0, 0], - reference_cs="Global", - name="Section", - mode="axis", - x_pointing=["cos(360deg/SymmetryFactor)", "sin(360deg/SymmetryFactor)", 0], - y_pointing=["-sin(360deg/SymmetryFactor)", "cos(360deg/SymmetryFactor)", 0], -) - -m2d.modeler.set_working_coordinate_system("Section") -m2d.modeler.split(assignment=object_list, plane="ZX", sides="NegativeOnly") -m2d.modeler.set_working_coordinate_system("Global") -m2d.modeler.split(assignment=object_list, plane="ZX", sides="PositiveOnly") -# - - -# ## Create boundary conditions -# -# Create independent and dependent boundary conditions. -# Edges for assignment are picked by position. -# The points for edge picking are in the airgap. - -pos_1 = "((DiaGap - (1.0 * Airgap))/4)" -id_bc_1 = m2d.modeler.get_edgeid_from_position( - position=[pos_1, 0, 0], assignment="Region" -) -id_bc_2 = m2d.modeler.get_edgeid_from_position( - position=[ - pos_1 + "*cos((360deg/SymmetryFactor))", - pos_1 + "*sin((360deg/SymmetryFactor))", - 0, - ], - assignment="Region", -) -m2d.assign_master_slave( - independent=id_bc_1, - dependent=id_bc_2, - reverse_master=False, - reverse_slave=True, - same_as_master=False, - boundary="Matching", -) - -# ## Assign vector potential -# -# Assign a vector potential of ``0`` to the second position. - -pos_2 = "(DiaOuter/2)" -id_bc_az = m2d.modeler.get_edgeid_from_position( - position=[ - pos_2 + "*cos((360deg/SymmetryFactor/2))", - pos_2 + "*sin((360deg/SymmetryFactor)/2)", - 0, - ], - assignment="Region", -) -m2d.assign_vector_potential( - assignment=id_bc_az, vector_value=0, boundary="VectorPotentialZero" -) - -# ## Create excitations -# -# Create excitations, defining phase currents for the windings. - -ph_a_current = "IPeak * cos(2*pi*ElectricFrequency*time+Theta_i)" -ph_b_current = "IPeak * cos(2*pi * ElectricFrequency*time - 120deg+Theta_i)" -ph_c_current = "IPeak * cos(2*pi * ElectricFrequency*time - 240deg+Theta_i)" - -# ## Define windings in phase A - -m2d.assign_coil( - assignment=["Coil"], - conductors_number=6, - polarity="Positive", - name="CT_Ph1_P2_C1_Go", -) -m2d.assign_coil( - assignment=["Coil_5"], - conductors_number=6, - polarity="Negative", - name="CT_Ph1_P2_C1_Ret", -) -m2d.assign_winding( - assignment=None, - winding_type="Current", - is_solid=False, - current=ph_a_current, - parallel_branches=1, - name="Phase_A", -) -m2d.add_winding_coils( - assignment="Phase_A", coils=["CT_Ph1_P2_C1_Go", "CT_Ph1_P2_C1_Ret"] -) - -# ## Define windings in phase B - -m2d.assign_coil( - assignment="Coil_3", - conductors_number=6, - polarity="Positive", - name="CT_Ph3_P1_C2_Go", -) -m2d.assign_coil( - assignment="Coil_4", - conductors_number=6, - polarity="Positive", - name="CT_Ph3_P1_C1_Go", -) -m2d.assign_winding( - assignment=None, - winding_type="Current", - is_solid=False, - current=ph_b_current, - parallel_branches=1, - name="Phase_B", -) -m2d.add_winding_coils( - assignment="Phase_B", coils=["CT_Ph3_P1_C2_Go", "CT_Ph3_P1_C1_Go"] -) - -# ## Define windings in phase C - -m2d.assign_coil( - assignment="Coil_1", - conductors_number=6, - polarity="Negative", - name="CT_Ph2_P2_C2_Ret", -) -m2d.assign_coil( - assignment="Coil_2", - conductors_number=6, - polarity="Negative", - name="CT_Ph2_P2_C1_Ret", -) -m2d.assign_winding( - assignment=None, - winding_type="Current", - is_solid=False, - current=ph_c_current, - parallel_branches=1, - name="Phase_C", -) -m2d.add_winding_coils( - assignment="Phase_C", coils=["CT_Ph2_P2_C2_Ret", "CT_Ph2_P2_C1_Ret"] -) - -# ## Assign total current on PMs -# -# Assign a total current of ``0`` on the PMs. - -PM_list = id_PMs -for item in PM_list: - m2d.assign_current(assignment=item, amplitude=0, solid=True, name=item + "_I0") - -# ## Create mesh operations - -m2d.mesh.assign_length_mesh( - assignment=id_coils, - inside_selection=True, - maximum_length=3, - maximum_elements=None, - name="coils", -) -m2d.mesh.assign_length_mesh( - assignment=stator_id, - inside_selection=True, - maximum_length=3, - maximum_elements=None, - name="stator", -) -m2d.mesh.assign_length_mesh( - assignment=rotor_id, - inside_selection=True, - maximum_length=3, - maximum_elements=None, - name="rotor", -) - -# ## Turn on core loss - -core_loss_list = ["Rotor", "Stator"] -m2d.set_core_losses(core_loss_list, core_loss_on_field=True) - -# ## Compute transient inductance - -m2d.change_inductance_computation( - compute_transient_inductance=True, incremental_matrix=False -) - -# ## Set model depth - -m2d.model_depth = "Magnetic_Axial_Length" - -# ## Set symmetry factor - -m2d.change_symmetry_multiplier("SymmetryFactor") - -# ## Create setup and validate - -# + -setup_name = "MySetupAuto" -setup = m2d.create_setup(name=setup_name) -setup.props["StopTime"] = "StopTime" -setup.props["TimeStep"] = "TimeStep" -setup.props["SaveFieldsType"] = "None" -setup.props["OutputPerObjectCoreLoss"] = True -setup.props["OutputPerObjectSolidLoss"] = True -setup.props["OutputError"] = True -setup.update() -m2d.validate_simple() - -model = m2d.plot(show=False) -model.plot(os.path.join(temp_folder.name, "Image.jpg")) -# - - -# ## Initialize definitions for output variables -# -# Initialize the definitions for the output variables. -# These are used later to generate reports. - -output_vars = { - "Current_A": "InputCurrent(Phase_A)", - "Current_B": "InputCurrent(Phase_B)", - "Current_C": "InputCurrent(Phase_C)", - "Flux_A": "FluxLinkage(Phase_A)", - "Flux_B": "FluxLinkage(Phase_B)", - "Flux_C": "FluxLinkage(Phase_C)", - "pos": "(Moving1.Position -InitialPositionMD) *NumPoles/2", - "cos0": "cos(pos)", - "cos1": "cos(pos-2*PI/3)", - "cos2": "cos(pos-4*PI/3)", - "sin0": "sin(pos)", - "sin1": "sin(pos-2*PI/3)", - "sin2": "sin(pos-4*PI/3)", - "Flux_d": "2/3*(Flux_A*cos0+Flux_B*cos1+Flux_C*cos2)", - "Flux_q": "-2/3*(Flux_A*sin0+Flux_B*sin1+Flux_C*sin2)", - "I_d": "2/3*(Current_A*cos0 + Current_B*cos1 + Current_C*cos2)", - "I_q": "-2/3*(Current_A*sin0 + Current_B*sin1 + Current_C*sin2)", - "Irms": "sqrt(I_d^2+I_q^2)/sqrt(2)", - "ArmatureOhmicLoss_DC": "Irms^2*R_phase", - "Lad": "L(Phase_A,Phase_A)*cos0 + L(Phase_A,Phase_B)*cos1 + L(Phase_A,Phase_C)*cos2", - "Laq": "L(Phase_A,Phase_A)*sin0 + L(Phase_A,Phase_B)*sin1 + L(Phase_A,Phase_C)*sin2", - "Lbd": "L(Phase_B,Phase_A)*cos0 + L(Phase_B,Phase_B)*cos1 + L(Phase_B,Phase_C)*cos2", - "Lbq": "L(Phase_B,Phase_A)*sin0 + L(Phase_B,Phase_B)*sin1 + L(Phase_B,Phase_C)*sin2", - "Lcd": "L(Phase_C,Phase_A)*cos0 + L(Phase_C,Phase_B)*cos1 + L(Phase_C,Phase_C)*cos2", - "Lcq": "L(Phase_C,Phase_A)*sin0 + L(Phase_C,Phase_B)*sin1 + L(Phase_C,Phase_C)*sin2", - "L_d": "(Lad*cos0 + Lbd*cos1 + Lcd*cos2) * 2/3", - "L_q": "(Laq*sin0 + Lbq*sin1 + Lcq*sin2) * 2/3", - "OutputPower": "Moving1.Speed*Moving1.Torque", - "Ui_A": "InducedVoltage(Phase_A)", - "Ui_B": "InducedVoltage(Phase_B)", - "Ui_C": "InducedVoltage(Phase_C)", - "Ui_d": "2/3*(Ui_A*cos0 + Ui_B*cos1 + Ui_C*cos2)", - "Ui_q": "-2/3*(Ui_A*sin0 + Ui_B*sin1 + Ui_C*sin2)", - "U_A": "Ui_A+R_Phase*Current_A", - "U_B": "Ui_B+R_Phase*Current_B", - "U_C": "Ui_C+R_Phase*Current_C", - "U_d": "2/3*(U_A*cos0 + U_B*cos1 + U_C*cos2)", - "U_q": "-2/3*(U_A*sin0 + U_B*sin1 + U_C*sin2)", -} - -# ## Create output variables for postprocessing - -for k, v in output_vars.items(): - m2d.create_output_variable(k, v) - -# ## Initialize definition for postprocessing plots - -post_params = {"Moving1.Torque": "TorquePlots"} - -# ## Initialize definition for postprocessing multiplots - -post_params_multiplot = { # reports - ("U_A", "U_B", "U_C", "Ui_A", "Ui_B", "Ui_C"): "PhaseVoltages", - ("CoreLoss", "SolidLoss", "ArmatureOhmicLoss_DC"): "Losses", - ( - "InputCurrent(Phase_A)", - "InputCurrent(Phase_B)", - "InputCurrent(Phase_C)", - ): "PhaseCurrents", - ( - "FluxLinkage(Phase_A)", - "FluxLinkage(Phase_B)", - "FluxLinkage(Phase_C)", - ): "PhaseFluxes", - ("I_d", "I_q"): "Currents_dq", - ("Flux_d", "Flux_q"): "Fluxes_dq", - ("Ui_d", "Ui_q"): "InducedVoltages_dq", - ("U_d", "U_q"): "Voltages_dq", - ( - "L(Phase_A,Phase_A)", - "L(Phase_B,Phase_B)", - "L(Phase_C,Phase_C)", - "L(Phase_A,Phase_B)", - "L(Phase_A,Phase_C)", - "L(Phase_B,Phase_C)", - ): "PhaseInductances", - ("L_d", "L_q"): "Inductances_dq", - ("CoreLoss", "CoreLoss(Stator)", "CoreLoss(Rotor)"): "CoreLosses", - ( - "EddyCurrentLoss", - "EddyCurrentLoss(Stator)", - "EddyCurrentLoss(Rotor)", - ): "EddyCurrentLosses (Core)", - ("ExcessLoss", "ExcessLoss(Stator)", "ExcessLoss(Rotor)"): "ExcessLosses (Core)", - ( - "HysteresisLoss", - "HysteresisLoss(Stator)", - "HysteresisLoss(Rotor)", - ): "HysteresisLosses (Core)", - ( - "SolidLoss", - "SolidLoss(IPM1)", - "SolidLoss(IPM1_1)", - "SolidLoss(OPM1)", - "SolidLoss(OPM1_1)", - ): "SolidLoss", -} - -# ## Create report. - -for k, v in post_params.items(): - m2d.post.create_report( - expressions=k, - setup_sweep_name="", - domain="Sweep", - variations=None, - primary_sweep_variable="Time", - secondary_sweep_variable=None, - report_category=None, - plot_type="Rectangular Plot", - context=None, - subdesign_id=None, - polyline_points=1001, - plot_name=v, - ) - -# ## Create multiplot report - -# + -# for k, v in post_params_multiplot.items(): -# m2d.post.create_report(expressions=list(k), setup_sweep_name="", -# domain="Sweep", variations=None, -# primary_sweep_variable="Time", secondary_sweep_variable=None, -# report_category=None, plot_type="Rectangular Plot", -# context=None, subdesign_id=None, -# polyline_points=1001, plotname=v) -# - - -# ## Analyze and save project - -m2d.save_project() -m2d.analyze_setup(setup_name, use_auto_settings=False, cores=NUM_CORES) - -# ## Create flux lines plot on region -# -# Create a flux lines plot on a region. The ``object_list`` is -# formerly created when the section is applied. - -faces_reg = m2d.modeler.get_object_faces(object_list[1].name) # Region -plot1 = m2d.post.create_fieldplot_surface( - assignment=faces_reg, - quantity="Flux_Lines", - intrinsics={"Time": m2d.variable_manager.variables["StopTime"].evaluated_value}, - plot_name="Flux_Lines", -) - -# ## Export a field plot to an image file -# -# Export the flux lines plot to an image file using Python PyVista. - -m2d.post.plot_field_from_fieldplot(plot1.name, show=False) - -# ## Get solution data -# -# Get a simulation result from a solved setup and cast it in a ``SolutionData`` object. -# Plot the desired expression by using the Matplotlib ``plot()`` function. - -solutions = m2d.post.get_solution_data( - expressions="Moving1.Torque", primary_sweep_variable="Time" -) -# solutions.plot() - -# ## Retrieve the data magnitude of an expression -# -# List of shaft torque points and compute average. - -mag = solutions.data_magnitude() -avg = sum(mag) / len(mag) - -# ## Export a report to a file -# -# Export 2D plot data to a CSV file. - -m2d.post.export_report_to_file( - output_dir=temp_folder.name, plot_name="TorquePlots", extension=".csv" -) - -# ## Release AEDT - -m2d.save_project() -m2d.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. -# If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell -# removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/low_frequency/motor/aedt_motor/rmxpert.py b/examples/low_frequency/motor/aedt_motor/rmxpert.py deleted file mode 100644 index 83ef3e273..000000000 --- a/examples/low_frequency/motor/aedt_motor/rmxpert.py +++ /dev/null @@ -1,162 +0,0 @@ -# # Motor creation and export -# -# This example uses PyAEDT to create a RMxprt project and export it to Maxwell 2D. -# It shows how to create an ASSM (Adjust-Speed Synchronous Machine) in RMxprt -# and how to access rotor and stator settings. -# It then exports the model to a Maxwell 2D design -# and the RMxprt settings to a JSON file to be reused. -# -# Keywords: **RMxprt**, **Maxwell 2D** - -# ## Perform imports and define constants -# -# Perform required imports. - -import os -import tempfile -import time - -import ansys.aedt.core - -# Define constants. - -AEDT_VERSION = "2024.2" -NUM_CORES = 4 -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Launch AEDT and RMxprt -# -# Launch AEDT and RMxprt after first setting up the project name. -# This example uses ASSM (Adjust-Speed Synchronous Machine) as the solution type. - -project_name = os.path.join(temp_folder.name, "ASSM.aedt") -rmxprt = ansys.aedt.core.Rmxprt( - version=AEDT_VERSION, - new_desktop=True, - close_on_exit=True, - solution_type="ASSM", - project=project_name, - non_graphical=NG_MODE, -) - -# ## Define global machine settings - -rmxprt.general["Number of Poles"] = 4 -rmxprt.general["Rotor Position"] = "Inner Rotor" -rmxprt.general["Frictional Loss"] = "12W" -rmxprt.general["Windage Loss"] = "0W" -rmxprt.general["Reference Speed"] = "1500rpm" -rmxprt.general["Control Type"] = "DC" -rmxprt.general["Circuit Type"] = "Y3" - -# ## Define circuit settings - -rmxprt.circuit["Trigger Pulse Width"] = "120deg" -rmxprt.circuit["Transistor Drop"] = "2V" -rmxprt.circuit["Diode Drop"] = "2V" - -# ## Define stator -# -# Define stator and slot and winding settings. - -rmxprt.stator["Outer Diameter"] = "122mm" -rmxprt.stator["Inner Diameter"] = "75mm" -rmxprt.stator["Length"] = "65mm" -rmxprt.stator["Stacking Factor"] = 0.95 -rmxprt.stator["Steel Type"] = "steel_1008" -rmxprt.stator["Number of Slots"] = 24 -rmxprt.stator["Slot Type"] = 2 - -rmxprt.stator.properties.children["Slot"].props["Auto Design"] = False -rmxprt.stator.properties.children["Slot"].props["Hs0"] = "0.5mm" -rmxprt.stator.properties.children["Slot"].props["Hs1"] = "1.2mm" -rmxprt.stator.properties.children["Slot"].props["Hs2"] = "8.2mm" -rmxprt.stator.properties.children["Slot"].props["Bs0"] = "2.5mm" -rmxprt.stator.properties.children["Slot"].props["Bs1"] = "5.6mm" -rmxprt.stator.properties.children["Slot"].props["Bs2"] = "7.6mm" - -rmxprt.stator.properties.children["Winding"].props["Winding Layers"] = 2 -rmxprt.stator.properties.children["Winding"].props["Parallel Branches"] = 1 -rmxprt.stator.properties.children["Winding"].props["Conductors per Slot"] = 52 -rmxprt.stator.properties.children["Winding"].props["Coil Pitch"] = 5 -rmxprt.stator.properties.children["Winding"].props["Number of Strands"] = 1 - -# ## Define rotor -# -# Define rotor and pole settings. - -rmxprt.rotor["Outer Diameter"] = "74mm" -rmxprt.rotor["Inner Diameter"] = "26mm" -rmxprt.rotor["Length"] = "65mm" -rmxprt.rotor["Stacking Factor"] = 0.95 -rmxprt.rotor["Steel Type"] = "steel_1008" -rmxprt.rotor["Pole Type"] = 1 - -rmxprt.rotor.properties.children["Pole"].props["Embrace"] = 0.7 -rmxprt.rotor.properties.children["Pole"].props["Offset"] = "0mm" -rmxprt.rotor.properties.children["Pole"].props["Magnet Type"] = [ - "Material:=", - "Alnico9", -] -rmxprt.rotor.properties.children["Pole"].props["Magnet Thickness"] = "3.5mm" - -# ## Create setup -# -# Create a setup and define the main settings. - -setup = rmxprt.create_setup() -setup.props["RatedVoltage"] = "220V" -setup.props["RatedOutputPower"] = "550W" -setup.props["RatedSpeed"] = "1500rpm" -setup.props["OperatingTemperature"] = "75cel" - -# ## Analyze setup. - -setup.analyze(cores=NUM_CORES) - -# ## Export to Maxwell -# -# After the project is solved, you can export it to either Maxwell 2D or Maxwell 3D. - -m2d = rmxprt.create_maxwell_design(setup_name=setup.name, maxwell_2d=True) -m2d.plot( - show=False, - output_file=os.path.join(temp_folder.name, "Image.jpg"), - plot_air_objects=True, -) - -# ## Export RMxprt settings -# -# Export all RMxprt settings to a JSON file to reuse it for another -# project with the the import function. - -config = rmxprt.export_configuration(os.path.join(temp_folder.name, "assm.json")) -rmxprt2 = ansys.aedt.core.Rmxprt( - project="assm_test2", - solution_type=rmxprt.solution_type, - design="from_configuration", -) -rmxprt2.import_configuration(config) - -# ## Save project -# -# Save the project containing the Maxwell design. - -m2d.save_project(file_name=project_name) - -# ## Release AEDT and clean up temporary directory -# -# Release AEDT and remove both the project and temporary directory. - -m2d.release_desktop() -time.sleep(3) -temp_folder.cleanup() diff --git a/examples/low_frequency/motor/aedt_motor/transformer.py b/examples/low_frequency/motor/aedt_motor/transformer.py deleted file mode 100644 index bdfc40794..000000000 --- a/examples/low_frequency/motor/aedt_motor/transformer.py +++ /dev/null @@ -1,141 +0,0 @@ -# # Transformer - -# This example shows how to use PyAEDT to set core loss given a set -# of power-volume [kw/m^3] curves at different frequencies. -# -# Keywords: **Maxwell 3D**, **Transformer**. - -# ## Perform imports and define constants -# -# Perform required imports. - -import tempfile -import time - -from ansys.aedt.core import Maxwell3d, downloads -from ansys.aedt.core.generic.constants import unit_converter -from ansys.aedt.core.generic.general_methods import read_csv_pandas - -# Define constants. - -AEDT_VERSION = "2024.2" -NG_MODE = False - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Download AEDT file example -# -# Download the files required to run this example to the temporary working folder. - -# + -aedt_file = downloads.download_file( - source="core_loss_transformer", - name="Ex2-PlanarTransformer_2023R2.aedtz", - destination=temp_folder.name, -) -freq_curve_csv_25kHz = downloads.download_file( - source="core_loss_transformer", name="mf3_25kHz.csv", destination=temp_folder.name -) -freq_curve_csv_100kHz = downloads.download_file( - source="core_loss_transformer", name="mf3_100kHz.csv", destination=temp_folder.name -) -freq_curve_csv_200kHz = downloads.download_file( - source="core_loss_transformer", name="mf3_200kHz.csv", destination=temp_folder.name -) -freq_curve_csv_400kHz = downloads.download_file( - source="core_loss_transformer", name="mf3_400kHz.csv", destination=temp_folder.name -) -freq_curve_csv_700kHz = downloads.download_file( - source="core_loss_transformer", name="mf3_700kHz.csv", destination=temp_folder.name -) -freq_curve_csv_1MHz = downloads.download_file( - source="core_loss_transformer", name="mf3_1MHz.csv", destination=temp_folder.name -) - -data = read_csv_pandas(input_file=freq_curve_csv_25kHz) -curves_csv_25kHz = list(zip(data[data.columns[0]], data[data.columns[1]])) -data = read_csv_pandas(input_file=freq_curve_csv_100kHz) -curves_csv_100kHz = list(zip(data[data.columns[0]], data[data.columns[1]])) -data = read_csv_pandas(input_file=freq_curve_csv_200kHz) -curves_csv_200kHz = list(zip(data[data.columns[0]], data[data.columns[1]])) -data = read_csv_pandas(input_file=freq_curve_csv_400kHz) -curves_csv_400kHz = list(zip(data[data.columns[0]], data[data.columns[1]])) -data = read_csv_pandas(input_file=freq_curve_csv_700kHz) -curves_csv_700kHz = list(zip(data[data.columns[0]], data[data.columns[1]])) -data = read_csv_pandas(input_file=freq_curve_csv_1MHz) -curves_csv_1MHz = list(zip(data[data.columns[0]], data[data.columns[1]])) -# - - -# ## Launch AEDT and Maxwell 3D -# -# Create an instance of the ``Maxwell3d`` class named ``m3d`` by providing -# the project and design names, the version, and the graphical mode. - -m3d = Maxwell3d( - project=aedt_file, - design="02_3D eddycurrent_CmXY_for_thermal", - version=AEDT_VERSION, - new_desktop=True, - non_graphical=False, -) - -# ## Set core loss at frequencies -# -# Create a new material, create a dictionary of power-volume [kw/m^3] points -# for a set of frequencies retrieved from datasheet provided by a supplier, -# and finally set the Power-Ferrite core loss model. - -mat = m3d.materials.add_material("newmat") -freq_25kHz = unit_converter( - values=25, unit_system="Freq", input_units="kHz", output_units="Hz" -) -freq_100kHz = unit_converter( - values=100, unit_system="Freq", input_units="kHz", output_units="Hz" -) -freq_200kHz = unit_converter( - values=200, unit_system="Freq", input_units="kHz", output_units="Hz" -) -freq_400kHz = unit_converter( - values=400, unit_system="Freq", input_units="kHz", output_units="Hz" -) -freq_700kHz = unit_converter( - values=700, unit_system="Freq", input_units="kHz", output_units="Hz" -) -pv = { - freq_25kHz: curves_csv_25kHz, - freq_100kHz: curves_csv_100kHz, - freq_200kHz: curves_csv_200kHz, - freq_400kHz: curves_csv_400kHz, - freq_700kHz: curves_csv_700kHz, -} -m3d.materials[mat.name].set_coreloss_at_frequency( - points_at_frequency=pv, - coefficient_setup="kw_per_cubic_meter", - core_loss_model_type="Power Ferrite", -) -coefficients = m3d.materials[mat.name].get_core_loss_coefficients( - points_at_frequency=pv, coefficient_setup="kw_per_cubic_meter" -) - -# ## Release AEDT - -m3d.save_project() -m3d.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. -# If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell -# removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/low_frequency/motor/aedt_motor/transformer_inductance.py b/examples/low_frequency/motor/aedt_motor/transformer_inductance.py deleted file mode 100644 index 4ee1db21a..000000000 --- a/examples/low_frequency/motor/aedt_motor/transformer_inductance.py +++ /dev/null @@ -1,294 +0,0 @@ -# # Transformer leakage inductance calculation -# -# This example shows how to use PyAEDT to create a Maxwell 2D -# magnetostatic analysis to calculate transformer leakage -# inductance and reactance. -# The analysis based on this document is from page 8 in Professor S. V. -# Kulkami's paper, [Basis of Finite Element Method](https://www.ee.iitb.ac.in/~fclab/FEM/FEM1.pdf). -# -# Keywords: **Maxwell 2D**, **transformer**, **motor**. - -# ## Perform imports and define constants - -import os -import tempfile -import time - -from ansys.aedt.core import Maxwell2d - -# Define constants, - -AEDT_VERSION = "2024.2" -NUM_CORES = 4 -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Initialize and launch Maxwell 2D -# -# Initialize and launch Maxwell 2D, providing the version, the path to the project, the design -# name, and the type. - -# + - -project_name = os.path.join(temp_folder.name, "Magnetostatic.aedt") -m2d = Maxwell2d( - version=AEDT_VERSION, - new_desktop=False, - design="Transformer_leakage_inductance", - project=project_name, - solution_type="MagnetostaticXY", - non_graphical=NG_MODE, -) -# - - -# ## Initialize dictionaries -# -# Set modeler units and initialize dictionaries -# that contain all the definitions for the design variables. - -# + -m2d.modeler.model_units = "mm" - -dimensions = { - "core_width": "1097mm", - "core_height": "2880mm", - "core_opening_x1": "270mm", - "core_opening_x2": "557mm", - "core_opening_y1": "540mm", - "core_opening_y2": "2340mm", - "core_opening_width": "core_opening_x2-core_opening_x1", - "core_opening_height": "core_opening_y2-core_opening_y1", - "LV_x1": "293mm", - "LV_x2": "345mm", - "LV_width": "LV_x2-LV_x1", - "LV_mean_radius": "LV_x1+LV_width/2", - "LV_mean_turn_length": "pi*2*LV_mean_radius", - "LV_y1": "620mm", - "LV_y2": "2140mm", - "LV_height": "LV_y2-LV_y1", - "HV_x1": "394mm", - "HV_x2": "459mm", - "HV_width": "HV_x2-HV_x1", - "HV_mean_radius": "HV_x1+HV_width/2", - "HV_mean_turn_length": "pi*2*HV_mean_radius", - "HV_y1": "620mm", - "HV_y2": "2140mm", - "HV_height": "HV_y2-HV_y1", - "HV_LV_gap_radius": "(LV_x2 + HV_x1)/2", - "HV_LV_gap_length": "pi*2*HV_LV_gap_radius", -} - -specifications = { - "Amp_turns": "135024A", - "Frequency": "50Hz", - "HV_turns": "980", - "HV_current": "Amp_turns/HV_turns", -} -# - - -# ## Define variables from dictionaries -# -# Define design variables from the created dictionaries. - -# + -m2d.variable_manager.set_variable(name="Dimensions") - -for k, v in dimensions.items(): - m2d[k] = v - -m2d.variable_manager.set_variable(name="Windings") - -for k, v in specifications.items(): - m2d[k] = v -# - - -# ## Create design geometries -# -# Create the transformer core, the HV and LV windings, and the region. - -# + -core = m2d.modeler.create_rectangle( - origin=[0, 0, 0], - sizes=["core_width", "core_height", 0], - name="core", - material="steel_1008", -) - -core_hole = m2d.modeler.create_rectangle( - origin=["core_opening_x1", "core_opening_y1", 0], - sizes=["core_opening_width", "core_opening_height", 0], - name="core_hole", -) - -m2d.modeler.subtract(blank_list=[core], tool_list=[core_hole], keep_originals=False) - -lv = m2d.modeler.create_rectangle( - origin=["LV_x1", "LV_y1", 0], - sizes=["LV_width", "LV_height", 0], - name="LV", - material="copper", -) - -hv = m2d.modeler.create_rectangle( - origin=["HV_x1", "HV_y1", 0], - sizes=["HV_width", "HV_height", 0], - name="HV", - material="copper", -) - -region = m2d.modeler.create_region(pad_percent=[20, 10, 0, 10]) - -# ## Assign boundary condition -# -# Assign vector potential to zero on all region boundaries. This makes x=0 edge a symmetry boundary. - -m2d.assign_vector_potential(assignment=region.edges, boundary="VectorPotential1") -# - - -# ## Create initial mesh settings -# -# Assign a relatively dense mesh to all objects to ensure that the energy is calculated accurately. - -m2d.mesh.assign_length_mesh( - assignment=["core", "Region", "LV", "HV"], - maximum_length=50, - maximum_elements=None, - name="all_objects", -) - -# ## Define excitations -# -# Assign the same current in amp-turns but in opposite directions to the HV and LV windings. - -m2d.assign_current(assignment=lv, amplitude="Amp_turns", name="LV") -m2d.assign_current(assignment=hv, amplitude="Amp_turns", name="HV", swap_direction=True) - -# ## Create and analyze setup -# -# Create and analyze the setup. Set the number of minimum passes to 3 to ensure accuracy. - -m2d.create_setup(name="Setup1", MinimumPasses=3) -m2d.analyze_setup(use_auto_settings=False, cores=NUM_CORES) - -# ## Calculate transformer leakage inductance and reactance -# -# Calculate transformer leakage inductance from the magnetic energy with PyAEDT advanced fields calculator. - -# + -leakage_inductance = { - "name": "Leakage_inductance", - "description": "Leakage inductance from the magnetic energy", - "design_type": ["Maxwell 2D"], - "fields_type": ["Fields"], - "primary_sweep": "Distance", - "assignment": "", - "assignment_type": ["Line"], - "operations": [ - "Fundamental_Quantity('Energy')", - "EnterSurface('HV')", - "Operation('SurfaceValue')", - "Operation('Integrate')", - "Scalar_Function(FuncValue='HV_mean_turn_length')", - "Operation('*')", - "Fundamental_Quantity('Energy')", - "EnterSurface('LV')", - "Operation('SurfaceValue')", - "Operation('Integrate')", - "Scalar_Function(FuncValue='LV_mean_turn_length')", - "Operation('*')", - "Fundamental_Quantity('Energy')", - "EnterSurface('Region')", - "Operation('SurfaceValue')", - "Operation('Integrate')", - "Scalar_Function(FuncValue='HV_LV_gap_length')", - "Operation('*')", - "Operation('+')", - "Operation('+')", - "Scalar_Constant(2)", - "Operation('*')", - "Scalar_Function(FuncValue='HV_current')", - "Scalar_Function(FuncValue='HV_current')", - "Operation('*')", - "Operation('/')", - ], - "report": ["Data Table", "Rectangular Plot"], -} -m2d.post.fields_calculator.add_expression(leakage_inductance, None) - -leakage_reactance = { - "name": "Leakage_reactance", - "description": "Leakage reactance from the magnetic energy", - "design_type": ["Maxwell 2D"], - "fields_type": ["Fields"], - "primary_sweep": "Distance", - "assignment": "", - "assignment_type": ["Line"], - "operations": [ - "NameOfExpression('Leakage_inductance')", - "Scalar_Constant(2)", - "Scalar_Constant(3.14159)", - "Scalar_Function(FuncValue='Frequency')", - "Operation('*')", - "Operation('*')", - "Operation('*')", - ], - "report": ["Data Table", "Rectangular Plot"], -} -m2d.post.fields_calculator.add_expression(leakage_reactance, None) - -m2d.post.create_report( - expressions=["Leakage_inductance", "Leakage_reactance"], - report_category="Fields", - primary_sweep_variable="core_width", - plot_type="Data Table", - plot_name="Transformer Leakage Inductance", -) -# - - -# ## Print leakage inductance and reactance values in AEDT Message Manager - -m2d.logger.clear_messages() -m2d.logger.info( - "Leakage_inductance = {:.4f}H".format( - m2d.post.get_scalar_field_value(quantity="Leakage_inductance") - ) -) -m2d.logger.info( - "Leakage_reactance = {:.2f}Ohm".format( - m2d.post.get_scalar_field_value(quantity="Leakage_reactance") - ) -) - -# ## Plot energy in the simulation domain -# -# Most of the energy is confined in the air between the HV and LV windings. - -energy_field_overlay = m2d.post.create_fieldplot_surface( - assignment=m2d.modeler.object_names, - quantity="energy", - plot_name="Energy", -) - -# ## Release AEDT - -m2d.save_project() -m2d.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. -# If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell -# removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/low_frequency/motor/index.rst b/examples/low_frequency/motor/index.rst deleted file mode 100644 index 88052bb1b..000000000 --- a/examples/low_frequency/motor/index.rst +++ /dev/null @@ -1,33 +0,0 @@ -Motor -===== - -These examples use PyAEDT to show some motor applications. - - -.. grid:: 2 - - .. grid-item-card:: MotorCAD - :padding: 2 2 2 2 - :link: https://motorcad.docs.pyansys.com/version/stable/examples/index.html - :link-type: url - - .. image:: ./_static/motorcad.png - :alt: MotorCAD - :width: 200px - :height: 150px - :align: center - - Links to examples in PyMotorCAD documentation. - - .. grid-item-card:: Motor - :padding: 2 2 2 2 - :link: aedt_motor/index - :link-type: doc - - .. image:: ./_static/motor.png - :alt: Motor - :width: 200px - :height: 150px - :align: center - - Motor workflows using PyAEDT. diff --git a/examples/low_frequency/multiphysics/_static/charging.png b/examples/low_frequency/multiphysics/_static/charging.png deleted file mode 100644 index 7ab53d50d..000000000 Binary files a/examples/low_frequency/multiphysics/_static/charging.png and /dev/null differ diff --git a/examples/low_frequency/multiphysics/index.rst b/examples/low_frequency/multiphysics/index.rst deleted file mode 100644 index 1192bb4c2..000000000 --- a/examples/low_frequency/multiphysics/index.rst +++ /dev/null @@ -1,22 +0,0 @@ -Multiphysics -~~~~~~~~~~~~ - -These examples use PyAEDT to show some multiphysics applications. - -.. grid-item-card:: Maxwell 3D-Icepak electrothermal analysis - :padding: 2 2 2 2 - :link: maxwell_icepak - :link-type: doc - - .. image:: _static/charging.png - :alt: Charging - :width: 250px - :height: 200px - :align: center - - This example uses PyAEDT to set up a simple Maxwell design consisting of a coil and a ferrite core. - -.. toctree:: - :hidden: - - maxwell_icepak \ No newline at end of file diff --git a/examples/low_frequency/multiphysics/maxwell_icepak.py b/examples/low_frequency/multiphysics/maxwell_icepak.py deleted file mode 100644 index 2c847c6a5..000000000 --- a/examples/low_frequency/multiphysics/maxwell_icepak.py +++ /dev/null @@ -1,330 +0,0 @@ -# # Maxwell 3D-Icepak electrothermal analysis -# -# This example uses PyAEDT to set up a simple Maxwell design consisting of a coil and a ferrite core. -# Coil current is set to 100A, and coil resistance and ohmic loss are analyzed. -# Ohmic loss is mapped to Icepak, and a thermal analysis is performed. -# Icepak calculates a temperature distribution, and it is mapped back to Maxwell (2-way coupling). -# Coil resistance and ohmic loss are analyzed again in Maxwell. Results are printed in AEDT Message Manager. -# -# Keywords: **Multiphysics**, **Maxwell**, **Icepak**, **Wireless Charging**. -# -# ## Perform imports and define constants -# -# Perform required imports. - -import os -import tempfile -import time - -import ansys.aedt.core -from ansys.aedt.core.generic.constants import AXIS - -# Define constants. - -AEDT_VERSION = "2024.2" -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Launch application -# -# The syntax for different applications in AEDT differ -# only in the name of the class. This template uses -# the ``Hfss()`` class. Modify this text as needed. - -# + -project_name = os.path.join(temp_folder.name, "Maxwell-Icepak-2way-Coupling") -maxwell_design_name = "1 Maxwell" -icepak_design_name = "2 Icepak" - -m3d = ansys.aedt.core.Maxwell3d( - project=project_name, - design=maxwell_design_name, - solution_type="EddyCurrent", - version=AEDT_VERSION, - non_graphical=NG_MODE, -) -# - - -# ## Set up model -# -# Create the coil, coil terminal, core, and region. - -# + -coil = m3d.modeler.create_rectangle( - orientation="XZ", origin=[70, 0, -11], sizes=[11, 110], name="Coil" -) - -coil.sweep_around_axis(axis=AXIS.Z) - -coil_terminal = m3d.modeler.create_rectangle( - orientation="XZ", origin=[70, 0, -11], sizes=[11, 110], name="Coil_terminal" -) - -core = m3d.modeler.create_rectangle( - orientation="XZ", origin=[45, 0, -18], sizes=[7, 160], name="Core" -) -core.sweep_around_axis(axis=AXIS.Z) - -# Magnetic flux is not concentrated by the core in +z-direction. Therefore, more padding is needed in that direction. -region = m3d.modeler.create_region(pad_percent=[20, 20, 20, 20, 500, 100]) -# - - -# ### Create and assign material -# -# Create a new cooper material: Copper AWG40 Litz wire, strand diameter = 0.08mm, -# 24 parallel strands. Then assign materials: Assign the coil to AWG40 copper, -# the core to ferrite, and the region to vacuum. - -# + -no_strands = 24 -strand_diameter = 0.08 - -cu_litz = m3d.materials.duplicate_material("copper", "copper_litz") -cu_litz.stacking_type = "Litz Wire" -cu_litz.wire_diameter = str(strand_diameter) + "mm" -cu_litz.wire_type = "Round" -cu_litz.strand_number = no_strands - -m3d.assign_material(region.name, "vacuum") -m3d.assign_material(coil.name, "copper_litz") -m3d.assign_material(core.name, "ferrite") -# - - -# Assign coil current. The coil consists of 20 turns. The total current is 10A. -# Note that each coil turn consists of 24 parallel Litz strands as indicated earlier. - -# + -no_turns = 20 -coil_current = 10 -m3d.assign_coil(["Coil_terminal"], conductors_number=no_turns, name="Coil_terminal") -m3d.assign_winding(is_solid=False, current=coil_current, name="Winding1") - -m3d.add_winding_coils(assignment="Winding1", coils=["Coil_terminal"]) -# - - -# ## Assign mesh operations -# -# Mesh operations are not necessary in the eddy current solver because of auto-adaptive meshing. -# However, with appropriate mesh operations, less adaptive passes are needed - -m3d.mesh.assign_length_mesh( - ["Core"], maximum_length=15, maximum_elements=None, name="Inside_Core" -) -m3d.mesh.assign_length_mesh( - ["Coil"], maximum_length=30, maximum_elements=None, name="Inside_Coil" -) - -# Set conductivity as a function of temperature. Resistivity increases by 0.393% per K. - -cu_resistivity_temp_coefficient = 0.00393 -cu_litz.conductivity.add_thermal_modifier_free_form( - "1.0/(1.0+{}*(Temp-20))".format(cu_resistivity_temp_coefficient) -) - -# ## Set object temperature and enable feedback -# -# Set the temperature of the objects to the default temperature (22 degrees C) -# and enable temperature feedback for two-way coupling. - -m3d.modeler.set_objects_temperature(["Coil"], ambient_temperature=22) - -# ## Assign matrix -# -# Assign matrix for resistance and inductance calculation. - -m3d.assign_matrix(["Winding1"], matrix_name="Matrix1") - -# ## Create and analyze simulation setup -# -# The simulation frequency is 150 kHz. - -setup = m3d.create_setup(name="Setup1") -setup.props["Frequency"] = "150kHz" -m3d.analyze_setup("Setup1") - -# ## Postprocess -# -# Calculate analytical DC resistance and compare it with the simulated coil -# resistance. Print them in AEDT Message Manager, along with the ohmic loss in -# coil before the temperature feedback. - -# + -report = m3d.post.create_report(expressions="Matrix1.R(Winding1,Winding1)") -solution = report.get_solution_data() -resistance = solution.data_magnitude()[0] - -report_loss = m3d.post.create_report(expressions="StrandedLossAC") -solution_loss = report_loss.get_solution_data() -em_loss = solution_loss.data_magnitude()[0] - -# Analytical calculation of the DC resistance of the coil -cu_cond = float(cu_litz.conductivity.value) -# Average radius of a coil turn = 0.125m -l_conductor = no_turns * 2 * 0.125 * 3.1415 -# R = resistivity * length / area / no_strand -r_analytical_DC = ( - (1.0 / cu_cond) - * l_conductor - / (3.1415 * (strand_diameter / 1000 / 2) ** 2) - / no_strands -) - -# Print results in AEDT Message Manager -m3d.logger.info( - "*******Coil analytical DC resistance = {:.2f}Ohm".format(r_analytical_DC) -) -m3d.logger.info( - "*******Coil resistance at 150kHz BEFORE temperature feedback = {:.2f}Ohm".format( - resistance - ) -) -m3d.logger.info( - "*******Ohmic loss in coil BEFORE temperature feedback = {:.2f}W".format( - em_loss / 1000 - ) -) -# - - -# ## Insert Icepak design -# -# Insert Icepak design, copy solid objects from Maxwell 3D, and modify region dimensions. - -# + -ipk = ansys.aedt.core.Icepak(design=icepak_design_name, version=AEDT_VERSION) -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() -coil_dim = coil.bounding_dimension[0] -ipk.modeler.create_region(0, False) -ipk.modeler.edit_region_dimensions( - [coil_dim / 2, coil_dim / 2, coil_dim / 2, coil_dim / 2, coil_dim * 2, coil_dim] -) -# - - -# ## Map coil losses -# -# Map ohmic losses from Maxwell 3D to the Icepak design. - -ipk.assign_em_losses( - design="1 Maxwell", - setup=m3d.setups[0].name, - sweep="LastAdaptive", - assignment=["Coil"], -) - -# ### Define boundary conditions -# -# Assign the opening. - -faces = ipk.modeler["Region"].faces -face_names = [face.id for face in faces] -ipk.assign_free_opening(face_names, boundary_name="Opening1") - -# ### Assign monitor -# -# Assign the temperature monitor on the coil surface. - -temp_monitor = ipk.assign_point_monitor([70, 0, 0], monitor_name="PointMonitor1") - -# Set up Icepak solution - -solution_setup = ipk.create_setup() -solution_setup.props["Convergence Criteria - Max Iterations"] = 50 -solution_setup.props["Flow Regime"] = "Turbulent" -solution_setup.props["Turbulent Model Eqn"] = "ZeroEquation" -solution_setup.props["Radiation Model"] = "Discrete Ordinates Model" -solution_setup.props["Include Flow"] = True -solution_setup.props["Include Gravity"] = True -solution_setup.props["Solution Initialization - Z Velocity"] = "0.0005m_per_sec" -solution_setup.props["Convergence Criteria - Flow"] = 0.0005 -solution_setup.props["Flow Iteration Per Radiation Iteration"] = "5" - -# ## Add two-way coupling and solve the project -# -# Enable mapping temperature distribution back to Maxwell 3D. The default number -# for Maxwell <–> Icepak iterations is 2. However, for increased accuracy, -# you can increate the value for the ``number_of_iterations`` parameter. - -ipk.assign_2way_coupling() -ipk.analyze_setup(name=solution_setup.name) - -# ## Postprocess -# -# Plot temperature on the object surfaces. - -# + -surface_list = [] -for name in ["Coil", "Core"]: - surface_list.extend(ipk.modeler.get_object_faces(name)) - -surf_temperature = ipk.post.create_fieldplot_surface( - surface_list, quantity="SurfTemperature", plot_name="Surface Temperature" -) - -velocity_cutplane = ipk.post.create_fieldplot_cutplane( - assignment=["Global:XZ"], quantity="Velocity Vectors", plot_name="Velocity Vectors" -) - -surf_temperature.export_image() -velocity_cutplane.export_image(orientation="right") - -report_temp = ipk.post.create_report( - expressions="PointMonitor1.Temperature", primary_sweep_variable="X" -) -solution_temp = report_temp.get_solution_data() -temp = solution_temp.data_magnitude()[0] -m3d.logger.info("*******Coil temperature = {:.2f}deg C".format(temp)) -# - - -# ### Get new resistance from Maxwell 3D -# -# The temperature of the coil increases, and consequently the coil resistance increases. - -# + -report_new = m3d.post.create_report(expressions="Matrix1.R(Winding1,Winding1)") -solution_new = report_new.get_solution_data() -resistance_new = solution_new.data_magnitude()[0] -resistance_increase = (resistance_new - resistance) / resistance * 100 - -report_loss_new = m3d.post.create_report(expressions="StrandedLossAC") -solution_loss_new = report_loss_new.get_solution_data() -em_loss_new = solution_loss_new.data_magnitude()[0] - -m3d.logger.info( - "*******Coil resistance at 150kHz AFTER temperature feedback = {:.2f}Ohm".format( - resistance_new - ) -) -m3d.logger.info( - "*******Coil resistance increased by {:.2f}%".format(resistance_increase) -) -m3d.logger.info( - "*******Ohmic loss in coil AFTER temperature feedback = {:.2f}W".format( - em_loss_new / 1000 - ) -) -# - - -# ### Save project - -ipk.save_project() -ipk.release_desktop() -time.sleep(3) # Allow AEDT to shut down before cleaning the temporary project folder. - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. -# If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell removes -# all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/low_frequency/team_problem/_static/asymmetric_conductor.png b/examples/low_frequency/team_problem/_static/asymmetric_conductor.png deleted file mode 100644 index 555d45348..000000000 Binary files a/examples/low_frequency/team_problem/_static/asymmetric_conductor.png and /dev/null differ diff --git a/examples/low_frequency/team_problem/_static/bath.png b/examples/low_frequency/team_problem/_static/bath.png deleted file mode 100644 index a1b470dab..000000000 Binary files a/examples/low_frequency/team_problem/_static/bath.png and /dev/null differ diff --git a/examples/low_frequency/team_problem/asymmetric_conductor.py b/examples/low_frequency/team_problem/asymmetric_conductor.py deleted file mode 100644 index aa86bd64d..000000000 --- a/examples/low_frequency/team_problem/asymmetric_conductor.py +++ /dev/null @@ -1,548 +0,0 @@ -# # Asymmetric conductor analysis -# -# This example uses PyAEDT to set up the TEAM 7 problem for an asymmetric -# conductor with a hole and solve it using the Maxwell 3D eddy current solver. -# For more information on this problem, see this -# [paper](https://www.compumag.org/wp/wp-content/uploads/2018/06/problem7.pdf). -# -# Keywords: **Maxwell 3D**, **Asymmetric conductor**. - -# ## Perform imports and define constants -# -# Perform required imports. - -import os -import tempfile -import time - -import numpy as np -from ansys.aedt.core import Maxwell3d -from ansys.aedt.core.generic.general_methods import write_csv - -# Define constants. - -AEDT_VERSION = "2024.2" -NUM_CORES = 4 -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Launch AEDT and Maxwell 3D -# -# Create an instance of the ``Maxwell3d`` class named ``m3d`` by providing -# the project and design names, the solver, and the version. - -# + -project_name = os.path.join(temp_folder.name, "COMPUMAG2.aedt") -m3d = Maxwell3d( - project=project_name, - design="TEAM_7_Asymmetric_Conductor", - solution_type="EddyCurrent", - version=AEDT_VERSION, - non_graphical=NG_MODE, - new_desktop=True, -) -m3d.modeler.model_units = "mm" -# - - -# ## Add Maxwell 3D setup -# -# Add a Maxwell 3D setup with frequency points at DC, 50 Hz, and 200Hz. -# Otherwise, the default PyAEDT setup values are used. To approximate a DC field in the -# eddy current solver, use a low frequency value. Second-order shape functions improve -# the smoothness of the induced currents in the plate. - -# + -dc_freq = 0.1 -stop_freq = 50 - -setup = m3d.create_setup(name="Setup1") -setup.props["Frequency"] = "200Hz" -setup.props["HasSweepSetup"] = True -setup.add_eddy_current_sweep( - range_type="LinearStep", - start=dc_freq, - end=stop_freq, - count=stop_freq - dc_freq, - clear=True, -) -setup.props["UseHighOrderShapeFunc"] = True -setup.props["PercentError"] = 0.4 -# - - -# ## Define coil dimensions -# -# Define coil dimensions as shown on the TEAM7 drawing of the coil. - -coil_external = 150 + 25 + 25 -coil_internal = 150 -coil_r1 = 25 -coil_r2 = 50 -coil_thk = coil_r2 - coil_r1 -coil_height = 100 -coil_centre = [294 - 25 - 150 / 2, 25 + 150 / 2, 19 + 30 + 100 / 2] - -# Use expressions to construct the three dimensions needed to describe the midpoints of -# the coil. - -dim1 = coil_internal / 2 + (coil_external - coil_internal) / 4 -dim2 = coil_internal / 2 - coil_r1 -dim3 = dim2 + np.sqrt(((coil_r1 + (coil_r2 - coil_r1) / 2) ** 2) / 2) - -# Use coordinates to draw a polyline along which to sweep the coil cross sections. - -P1 = [dim1, -dim2, 0] -P2 = [dim1, dim2, 0] -P3 = [dim3, dim3, 0] -P4 = [dim2, dim1, 0] - -# ## Create coordinate system for positioning coil - -m3d.modeler.create_coordinate_system( - origin=coil_centre, mode="view", view="XY", name="Coil_CS" -) - -# ## Create polyline -# -# Create a polyline. One quarter of the coil is modeled by sweeping a 2D sheet along a polyline. - -test = m3d.modeler.create_polyline( - points=[P1, P2, P3, P4], segment_type=["Line", "Arc"], name="Coil" -) -test.set_crosssection_properties(type="Rectangle", width=coil_thk, height=coil_height) - -# ## Duplicate and unite polyline to create full coil - -m3d.modeler.duplicate_around_axis( - assignment="Coil", - axis="Global", - angle=90, - clones=4, - create_new_objects=True, - is_3d_comp=False, -) -m3d.modeler.unite("Coil, Coil_1, Coil_2") -m3d.modeler.unite("Coil, Coil_3") -m3d.modeler.fit_all() - -# ## Assign material and if solution is allowed inside coil -# -# Assign the material ``Cooper`` from the Maxwell internal library to the coil and -# allow a solution inside the coil. - -m3d.assign_material(assignment="Coil", material="Copper") -m3d.solve_inside("Coil") - -# ## Create terminal -# -# Create a terminal for the coil from a cross-section that is split and one half deleted. - -m3d.modeler.section(assignment="Coil", plane="YZ") -m3d.modeler.separate_bodies(assignment="Coil_Section1") -m3d.modeler.delete(assignment="Coil_Section1_Separate1") - -# ## Add variable for coil excitation -# -# Add a design variable for coil excitation. The NB units here are AmpereTurns. - -Coil_Excitation = 2742 -m3d["Coil_Excitation"] = str(Coil_Excitation) + "A" -m3d.assign_current(assignment="Coil_Section1", amplitude="Coil_Excitation", solid=False) -m3d.modeler.set_working_coordinate_system("Global") - -# ## Add material -# -# Add a material named ``team3_aluminium``. - -mat = m3d.materials.add_material("team7_aluminium") -mat.conductivity = 3.526e7 - -# ## Model aluminium plate with a hole -# -# Model the aluminium plate with a hole by subtracting two rectangular cuboids. - -plate = m3d.modeler.create_box( - origin=[0, 0, 0], sizes=[294, 294, 19], name="Plate", material="team7_aluminium" -) -m3d.modeler.fit_all() -hole = m3d.modeler.create_box(origin=[18, 18, 0], sizes=[108, 108, 19], name="Hole") -m3d.modeler.subtract(blank_list="Plate", tool_list=["Hole"], keep_originals=False) - -# ## Draw background region -# -# Draw a background region that uses the default properties for an air region. - -m3d.modeler.create_air_region( - x_pos=100, y_pos=100, z_pos=100, x_neg=100, y_neg=100, z_neg=100 -) - -# ## Adjust eddy effects for plate and coil -# -# Adjust the eddy effects for the plate and coil by turning off displacement currents -# for all parts. The setting for the eddy effect is ignored for the stranded conductor type -# used in the coil. - -m3d.eddy_effects_on(assignment="Plate") -m3d.eddy_effects_on( - assignment=["Coil", "Region", "Line_A1_B1mesh", "Line_A2_B2mesh"], - enable_eddy_effects=False, - enable_displacement_current=False, -) - -# ## Create expression for Z component of B in Gauss -# -# Create an expression for the Z component of B in Gauss using PyAEDT advanced fields calculator. - -bz = { - "name": "Bz", - "description": "Z component of B in Gauss", - "design_type": ["Maxwell 3D"], - "fields_type": ["Fields"], - "primary_sweep": "Distance", - "assignment": "", - "assignment_type": ["Line"], - "operations": [ - "NameOfExpression('')", - "Operation('ScalarZ')", - "Scalar_Function(FuncValue='Phase')", - "Operation('AtPhase')", - "Scalar_Constant(10000)", - "Operation('*')", - "Operation('Smooth')", - ], - "report": ["Field_3D"], -} -m3d.post.fields_calculator.add_expression(bz, None) - -# ## Draw two lines along which to plot Bz -# -# Draw two lines along which to plot Bz. The following code also adds a small cylinder -# to refine the mesh locally around each line. - -# + -lines = ["Line_A1_B1", "Line_A2_B2"] -mesh_diameter = "2mm" - -line_points_1 = [["0mm", "72mm", "34mm"], ["288mm", "72mm", "34mm"]] -polyline = m3d.modeler.create_polyline(points=line_points_1, name=lines[0]) -l1_mesh = m3d.modeler.create_polyline(points=line_points_1, name=lines[0] + "mesh") -l1_mesh.set_crosssection_properties(type="Circle", width=mesh_diameter) - -line_points_2 = [["0mm", "144mm", "34mm"], ["288mm", "144mm", "34mm"]] -polyline2 = m3d.modeler.create_polyline(points=line_points_2, name=lines[1]) -l2_mesh = m3d.modeler.create_polyline(points=line_points_2, name=lines[1] + "mesh") -l2_mesh.set_crosssection_properties(type="Circle", width=mesh_diameter) -# - - -# Published measurement results are included with this script via the following list. -# Test results are used to create text files for import into a rectangular plot -# and to overlay simulation results. - -# + -project_dir = temp_folder.name -dataset = [ - "Bz A1_B1 000 0", - "Bz A1_B1 050 0", - "Bz A1_B1 050 90", - "Bz A1_B1 200 0", - "Bz A1_B1 200 90", - "Bz A2_B2 050 0", - "Bz A2_B2 050 90", - "Bz A2_B2 200 0", - "Bz A2_B2 200 90", -] -header = ["Distance [mm]", "Bz [Tesla]"] - -line_length = [ - 0, - 18, - 36, - 54, - 72, - 90, - 108, - 126, - 144, - 162, - 180, - 198, - 216, - 234, - 252, - 270, - 288, -] -data = [ - [ - -6.667, - -7.764, - -8.707, - -8.812, - -5.870, - 8.713, - 50.40, - 88.47, - 100.9, - 104.0, - 104.8, - 104.9, - 104.6, - 103.1, - 97.32, - 75.19, - 29.04, - ], - [ - 4.90, - -17.88, - -22.13, - -20.19, - -15.67, - 0.36, - 43.64, - 78.11, - 71.55, - 60.44, - 53.91, - 52.62, - 53.81, - 56.91, - 59.24, - 52.78, - 27.61, - ], - [ - -1.16, - 2.84, - 4.15, - 4.00, - 3.07, - 2.31, - 1.89, - 4.97, - 12.61, - 14.15, - 13.04, - 12.40, - 12.05, - 12.27, - 12.66, - 9.96, - 2.36, - ], - [ - -3.63, - -18.46, - -23.62, - -21.59, - -16.09, - 0.23, - 44.35, - 75.53, - 63.42, - 53.20, - 48.66, - 47.31, - 48.31, - 51.26, - 53.61, - 46.11, - 24.96, - ], - [ - -1.38, - 1.20, - 2.15, - 1.63, - 1.10, - 0.27, - -2.28, - -1.40, - 4.17, - 3.94, - 4.86, - 4.09, - 3.69, - 4.60, - 3.48, - 4.10, - 0.98, - ], - [ - -1.83, - -8.50, - -13.60, - -15.21, - -14.48, - -5.62, - 28.77, - 60.34, - 61.84, - 56.64, - 53.40, - 52.36, - 53.93, - 56.82, - 59.48, - 52.08, - 26.56, - ], - [ - -1.63, - -0.60, - -0.43, - 0.11, - 1.26, - 3.40, - 6.53, - 10.25, - 11.83, - 11.83, - 11.01, - 10.58, - 10.80, - 10.54, - 10.62, - 9.03, - 1.79, - ], - [ - -0.86, - -7.00, - -11.58, - -13.36, - -13.77, - -6.74, - 24.63, - 53.19, - 54.89, - 50.72, - 48.03, - 47.13, - 48.25, - 51.35, - 53.35, - 45.37, - 24.01, - ], - [ - -1.35, - -0.71, - -0.81, - -0.67, - 0.15, - 1.39, - 2.67, - 3.00, - 4.01, - 3.80, - 4.00, - 3.02, - 2.20, - 2.78, - 1.58, - 1.37, - 0.93, - ], -] -# - - -# ## Write dataset values to a CSV file -# -# Dataset details are used to encode test parameters in the text files. -# For example, ``Bz A1_B1 050 0`` is the Z component of flux density ``B`` -# along line ``A1_B1`` at 50 Hz and 0 deg. - -# + -line_length.insert(0, header[0]) -for i in range(len(dataset)): - data[i].insert(0, header[1]) - ziplist = zip(line_length, data[i]) - file_path = os.path.join(temp_folder.name, str(dataset[i]) + ".csv") - write_csv(output_file=file_path, list_data=ziplist) -# - - -# ## Create rectangular plots and import test data into report -# -# Create rectangular plots, using text file encoding to control their formatting. -# Import test data into the correct plot and overlay with the simulation results. -# Variations for a DC plot must have a different frequency and phase than the other plots. - -for item in range(len(dataset)): - if item % 2 == 0: - t = dataset[item] - plot_name = t[0:3] + "Along the Line" + t[2:9] + ", " + t[9:12] + "Hz" - if t[9:12] == "000": - variations = { - "Distance": ["All"], - "Freq": [str(dc_freq) + "Hz"], - "Phase": ["0deg"], - "Coil_Excitation": ["All"], - } - else: - variations = { - "Distance": ["All"], - "Freq": [t[9:12] + "Hz"], - "Phase": ["0deg", "90deg"], - "Coil_Excitation": ["All"], - } - report = m3d.post.create_report( - plot_name=plot_name, - report_category="Fields", - context="Line_" + t[3:8], - primary_sweep_variable="Distance", - variations=variations, - expressions=t[0:2], - ) - file_path = os.path.join(temp_folder.name, str(dataset[i]) + ".csv") - report.import_traces(input_file=file_path, plot_name=plot_name) - -# Analyze project. - -m3d.analyze(cores=NUM_CORES) - -# ## Create plots of induced current and flux density on surface of plate -# -# Create two plots of the induced current (``Mag_J``) and the flux density (``Mag_B``) on the -# surface of the plate. - -surf_list = m3d.modeler.get_object_faces(assignment="Plate") -intrinsic_dict = {"Freq": "200Hz", "Phase": "0deg"} -m3d.post.create_fieldplot_surface( - assignment=surf_list, - quantity="Mag_J", - intrinsics=intrinsic_dict, - plot_name="Mag_J", -) -m3d.post.create_fieldplot_surface( - assignment=surf_list, - quantity="Mag_B", - intrinsics=intrinsic_dict, - plot_name="Mag_B", -) -m3d.post.create_fieldplot_surface( - assignment=surf_list, quantity="Mesh", intrinsics=intrinsic_dict, plot_name="Mesh" -) - -# ## Release AEDT - -m3d.save_project() -m3d.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. -# If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell -# removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/low_frequency/team_problem/bath_plate.py b/examples/low_frequency/team_problem/bath_plate.py deleted file mode 100644 index b0bb16d0d..000000000 --- a/examples/low_frequency/team_problem/bath_plate.py +++ /dev/null @@ -1,299 +0,0 @@ -# # Bath plate analysis -# -# This example uses PyAEDT to set up the TEAM 3 bath plate problem and -# solve it using the Maxwell 3D eddy current solver. -# # For more information on this problem, see this -# [paper](https://www.compumag.org/wp/wp-content/uploads/2018/06/problem3.pdf). -# -# Keywords: **Maxwell 3D**, **TEAM 3 bath plate** - -# ## Perform imports and define constants -# -# Perform required imports. - -import os -import tempfile -import time - -import ansys.aedt.core - -# Define constants. - -AEDT_VERSION = "2024.2" -NUM_CORES = 4 -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Launch AEDT and Maxwell 3D -# -# Create an instance of the ``Maxwell3d`` class named ``m3d`` by providing -# the project and design names, the solver, and the version. - -# + -m3d = ansys.aedt.core.Maxwell3d( - project=os.path.join(temp_folder.name, "COMPUMAG.aedt"), - design="TEAM_3_Bath_Plate", - solution_type="EddyCurrent", - version=AEDT_VERSION, - non_graphical=NG_MODE, - new_desktop=True, -) -uom = m3d.modeler.model_units = "mm" -# - - -# ## Add variable -# -# Add a design variable named ``Coil_Position`` to use later to adjust the -# position of the coil. - -Coil_Position = -20 -m3d["Coil_Position"] = str(Coil_Position) + m3d.modeler.model_units - -# ## Add material -# -# Add a material named ``team3_aluminium`` for the ladder plate. - -mat = m3d.materials.add_material(name="team3_aluminium") -mat.conductivity = 32780000 - -# ## Draw background region -# -# Draw a background region that uses the default properties for an air region. - -m3d.modeler.create_air_region( - x_pos=100, y_pos=100, z_pos=100, x_neg=100, y_neg=100, z_neg=100 -) - -# ## Draw ladder plate and assign material -# -# Draw a ladder plate and assign it the newly created material ``team3_aluminium``. - -m3d.modeler.create_box( - origin=[-30, -55, 0], - sizes=[60, 110, -6.35], - name="LadderPlate", - material="team3_aluminium", -) -m3d.modeler.create_box(origin=[-20, -35, 0], sizes=[40, 30, -6.35], name="CutoutTool1") -m3d.modeler.create_box(origin=[-20, 5, 0], sizes=[40, 30, -6.35], name="CutoutTool2") -m3d.modeler.subtract( - blank_list="LadderPlate", - tool_list=["CutoutTool1", "CutoutTool2"], - keep_originals=False, -) - -# ## Add mesh refinement to ladder plate - -# > **Note:** You can uncomment the following code. - -# m3d.mesh.assign_length_mesh( -# assignment="LadderPlate", -# maximum_length=3, -# maximum_elements=None, -# name="Ladder_Mesh", -# ) - -# ## Draw search coil and assign excitation -# -# Draw a search coil and assign it a ``stranded`` current excitation. -# The stranded type forces the current density to be constant in the coil. - -m3d.modeler.create_cylinder( - orientation="Z", - origin=[0, "Coil_Position", 15], - radius=40, - height=20, - name="SearchCoil", - material="copper", -) -m3d.modeler.create_cylinder( - orientation="Z", - origin=[0, "Coil_Position", 15], - radius=20, - height=20, - name="Bore", - material="copper", -) -m3d.modeler.subtract(blank_list="SearchCoil", tool_list="Bore", keep_originals=False) -m3d.modeler.section(assignment="SearchCoil", plane="YZ") -m3d.modeler.separate_bodies(assignment="SearchCoil_Section1") -m3d.modeler.delete(assignment="SearchCoil_Section1_Separate1") -m3d.assign_current( - assignment=["SearchCoil_Section1"], - amplitude=1260, - solid=False, - name="SearchCoil_Excitation", -) - -# ## Draw a line for plotting Bz -# -# Draw a line for plotting Bz later. Bz is the Z component of the flux -# density. The following code also adds a small diameter cylinder to refine the -# mesh locally around the line. - -line_points = [["0mm", "-55mm", "0.5mm"], ["0mm", "55mm", "0.5mm"]] -m3d.modeler.create_polyline(points=line_points, name="Line_AB") -poly = m3d.modeler.create_polyline(points=line_points, name="Line_AB_MeshRefinement") -poly.set_crosssection_properties(type="Circle", width="0.5mm") - -# ## Add Maxwell 3D setup -# -# Add a Maxwell 3D setup with frequency points at 50 Hz and 200 Hz. - -setup = m3d.create_setup(name="Setup1") -setup.props["Frequency"] = "200Hz" -setup.props["HasSweepSetup"] = True -setup.props["MaximumPasses"] = 1 -setup.add_eddy_current_sweep( - range_type="LinearStep", start=50, end=200, count=150, clear=True -) - -# ## Adjust eddy effects -# -# Adjust eddy effects for the ladder plate and the search coil. The setting for -# eddy effect is ignored for the stranded conductor type used in the search coil. - -m3d.eddy_effects_on( - assignment=["LadderPlate"], - enable_eddy_effects=True, - enable_displacement_current=True, -) -m3d.eddy_effects_on( - assignment=["SearchCoil"], - enable_eddy_effects=False, - enable_displacement_current=True, -) - -# ## Add linear parametric sweep -# -# Add a linear parametric sweep for the two coil positions. - -sweep_name = "CoilSweep" -param = m3d.parametrics.add( - variable="Coil_Position", - start_point=-20, - end_point=0, - step=20, - variation_type="LinearStep", - name=sweep_name, -) -param["SaveFields"] = True -param["CopyMesh"] = False -param["SolveWithCopiedMeshOnly"] = True - -# ## Solve parametric sweep -# -# Solve the parametric sweep directly so that results of all variations are available. - -m3d.save_project() -param.analyze(cores=NUM_CORES) - -# ## Create expression for Bz -# -# Create an expression for Bz using PyAEDT advanced fields calculator. - -bz = { - "name": "Bz", - "description": "Z component of B", - "design_type": ["Maxwell 3D"], - "fields_type": ["Fields"], - "primary_sweep": "Distance", - "assignment": "", - "assignment_type": ["Line"], - "operations": [ - "NameOfExpression('')", - "Operation('ScalarZ')", - "Scalar_Constant(1000)", - "Operation('*')", - "Operation('Smooth')", - ], - "report": ["Field_3D"], -} -m3d.post.fields_calculator.add_expression(bz, None) - -# ## Plot mag(Bz) as a function of frequency -# -# Plot mag(Bz) as a function of frequency for both coil positions. - -# + -variations = { - "Distance": ["All"], - "Freq": ["All"], - "Phase": ["0deg"], - "Coil_Position": ["All"], -} - -m3d.post.create_report( - expressions="mag(Bz)", - variations=variations, - primary_sweep_variable="Distance", - report_category="Fields", - context="Line_AB", - plot_name="mag(Bz) Along 'Line_AB' Coil", -) -# - - -# ## Get simulation results from a solved setup -# -# Get simulation results from a solved setup as a ``SolutionData`` object. - -# + - -solutions = m3d.post.get_solution_data( - expressions="mag(Bz)", - report_category="Fields", - context="Line_AB", - variations=variations, - primary_sweep_variable="Distance", -) -# - - -# ## Set up sweep value and plot solution - -solutions.active_variation["Coil_Position"] = -0.02 -solutions.plot() - -# ## Change sweep value and plot solution -# -# Change the sweep value and plot the solution again. -# Uncomment to show plots. - -solutions.active_variation["Coil_Position"] = 0 -# solutions.plot() - -# ## Plot induced current density on surface of ladder plate -# -# Plot the induced current density, ``"Mag_J"``, on the surface of the ladder plate. - -ladder_plate = m3d.modeler.objects_by_name["LadderPlate"] -intrinsics = {"Freq": "50Hz", "Phase": "0deg"} -m3d.post.create_fieldplot_surface( - assignment=ladder_plate.faces, - quantity="Mag_J", - intrinsics=intrinsics, - plot_name="Mag_J", -) - -# ## Release AEDT - -m3d.save_project() -m3d.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. -# If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell -# removes all temporary files, including the project folder. - -temp_folder.cleanup() diff --git a/examples/low_frequency/team_problem/index.rst b/examples/low_frequency/team_problem/index.rst deleted file mode 100644 index f9904c776..000000000 --- a/examples/low_frequency/team_problem/index.rst +++ /dev/null @@ -1,39 +0,0 @@ -T.E.A.M. -~~~~~~~~ - -These examples use PyAEDT to show some T.E.A.M. applications. - -.. grid:: 2 - - .. grid-item-card:: Asymmetric conductor analysis - :padding: 2 2 2 2 - :link: asymmetric_conductor - :link-type: doc - - .. image:: _static/asymmetric_conductor.png - :alt: Asymmetric conductor - :width: 250px - :height: 200px - :align: center - - This example uses PyAEDT to set up the TEAM 7 problem for an asymmetric conductor with a hole and solve it using the Maxwell 3D eddy current solver. - - .. grid-item-card:: Bath plate analysis - :padding: 2 2 2 2 - :link: bath_plate - :link-type: doc - - .. image:: _static/bath.png - :alt: Bath - :width: 250px - :height: 200px - :align: center - - This example uses PyAEDT to set up the TEAM 3 bath plate problem and solve it using the Maxwell 3D eddy current solver. - - - .. toctree:: - :hidden: - - asymmetric_conductor - bath_plate diff --git a/examples/template.py b/examples/template.py deleted file mode 100644 index 7cbf473be..000000000 --- a/examples/template.py +++ /dev/null @@ -1,80 +0,0 @@ -# # Short, Descriptive Title (do not specify the application name here, i.e.: Maxwell2D, Maxwell3D etc) -# -# Description: -# -# Most examples can be described as a series of steps that comprise a workflow. -# 1. Import packages and instantiate the application. -# 2. Do something useful and interesting. -# 3. View the results. -# -# Keywords: **Template**, **Jupyter** - -# ## Perform imports and define constants -# -# Perform required imports. - -import os -import tempfile -import time - -import ansys.aedt.core - -# Define constants. - -AEDT_VERSION = "2024.2" -NUM_CORES = 4 -NG_MODE = False # Open AEDT UI when it is launched. - -# ## Create temporary directory -# -# Create a temporary directory where downloaded data or -# dumped data can be stored. -# If you'd like to retrieve the project data for subsequent use, -# the temporary folder name is given by ``temp_folder.name``. - -temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") - -# ## Launch AEDT and application -# -# Create an instance of the application (such as ``Maxwell3d`` or``Hfss``) -# with a class (such as ``m3d`` or``hfss``) by providing -# the project and design names, the solver, and the version. - -project_name = os.path.join(temp_folder.name, "my_project.aedt") -m3d = ansys.aedt.core.Maxwell3d( - project=project_name, - design="my_design", - solution_type="my_solver", - version=AEDT_VERSION, - non_graphical=NG_MODE, - new_desktop=True, -) -m3d.modeler.model_units = "mm" - -# ## Preprocess -# -# Description of preprocessing task. -# Add as many sections as needed for preprocessing tasks. - - -# ## Postprocess -# -# Description of postprocessing task. -# Add as many sections as needed for postprocessing tasks. - - -# ## Release AEDT - -m3d.save_project() -m3d.release_desktop() -# Wait 3 seconds to allow AEDT to shut down before cleaning the temporary directory. -time.sleep(3) - -# ## Clean up -# -# All project files are saved in the folder ``temp_folder.name``. -# If you've run this example as a Jupyter notebook, you -# can retrieve those project files. The following cell -# removes all temporary files, including the project folder. - -temp_folder.cleanup()